我使用TDD(SimpleTest)创建了我的第一堂课。它工作得很好。此类解析XML配置文件并将其作为数组返回。我怎么能改进它(性能,任何提示)?班级责任怎么样?也许XMLtoArray应该被移到另一个类,我不知道......
<?php
class Configuration
{
private $domdocument_object;
private $domxpath_object;
public function __construct($filename) {
$this->loadXML($filename);
$this->domxpath_object = new DOMXPath($this->domdocument_object);
}
private function loadXML($filename)
{
if (!file_exists($filename))
{
throw new ConfigurationException('Configuration file not found');
}
$this->domdocument_object = $domdocument_object = new DOMDocument();
$this->domdocument_object->preserveWhiteSpace = false;
if (!$this->domdocument_object->load($filename))
{
throw new ConfigurationException('Malformed configuration file');
}
}
public function get($path = '/*') {
$configuration = array();
$domnodelist_object = $this->domxpath_object->query($path);
$configuration = $this->XMLToArray($domnodelist_object);
/**
* Get a configuration entry as string or array
*
* For example:
* $xml = '<foo><bar>baz</bar></foo>'
* $path = '/foo/bar/'
* return just baz, as string instead of an array('baz');
*
* Another example:
* $xml = '<foo><bar>baz</bar><lorem>ipsum</lorem></foo>';
* $path = '/foo'
* return just array('bar' => 'baz', 'lorem' => ipsum);
* instead of array('foo' => array('bar' => 'baz', 'lorem' => ipsum));
*/
while (!is_string($configuration) && count($configuration) == 1)
{
$configuration_values = array_values($configuration);
$configuration = $configuration_values[0];
}
if (empty($configuration))
{
$configuration = null;
}
return $configuration;
}
public function XMLToArray(DOMNodeList $domnodelist_object) {
$configuration = array();
foreach ($domnodelist_object as $element)
{
if ($element->nodeType == XML_DOCUMENT_NODE)
{
if ($element->hasChildNodes())
{
$configuration = $this->XMLToArray($element->childNodes);
}
}
else if ($element->nodeType == XML_ELEMENT_NODE)
{
if (!$element->hasChildNodes())
{
$configuration[$element->nodeName] = null;
}
else if (
$element->firstChild->nodeType == XML_TEXT_NODE ||
$element->firstChild->nodeType == XML_CDATA_SECTION_NODE
)
{
$configuration[$element->nodeName] = $element->nodeValue;
}
else if ($element->firstChild->nodeType == XML_ELEMENT_NODE)
{
$configuration[$element->nodeName] = $this->XMLToArray($element->childNodes);
}
}
}
return $configuration;
}
}
?>
此类忽略XML属性。 谢谢。
答案 0 :(得分:1)
对我来说很突出的是你每次执行一个对象时创建一个新对象,你应该在本地存储对象(在对象中),然后它只使用你内存的一部分。
以下是我要做的更改:
class Configuration
{
private $domdocument_object;
private $domxpath_object; //+
public function __construct($filename)
{
$this->loadXML($filename);
$this->domxpath_object = new DOMXPath($this->domdocument_object); //+
}
public function get($path = '/*')
{
//Remove the following
$domxpath_object = new DOMXPath($this->domdocument_object);
}
}
然后将$domxpath_object
更改为$this->domxpath_object
所需的位置。
但是这应该转移到CoderReview,因为这不是主题。
答案 1 :(得分:0)
这对性能不利:
$xml = preg_replace("/>\s+</", "><", $xml);
另外,它不能保证可靠(这可能会以不希望的方式改变评论和CDATA部分)。虽然找到更好的解决方案并不容易。迭代所有文本节点修剪它们将更可靠,但不会更快。
如果你只是想让这个数组成为php的SAX解析器或SimpleXML可能更合适。两种选择都可能更快(我没有测试)。