0

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属性を無視します。ありがとうございました。

4

2 に答える 2

1

私にとって目立ったのは、オブジェクトが実行されるたびに新しいオブジェクトを作成することです。オブジェクトをローカルに (オブジェクト内に) 保存し、メモリの 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に移動する必要があります。

于 2011-02-05T18:29:51.447 に答える
0

これはパフォーマンスに悪いです:

$xml = preg_replace("/>\s+</", "><", $xml);

さらに、信頼性が保証されていません (これにより、コメントや CDATA セクションが望ましくない方法で変更される可能性があります)。しかし、より良い解決策を見つけるのは簡単ではありません。すべてのテキスト ノードを反復処理してトリミングすると、信頼性が向上しますが、高速ではありません。

これを配列にしたいだけなら、php の SAX パーサーか SimpleXML の方が適しているかもしれません。どちらのオプションも高速になる可能性があります (私はテストしていません)。

于 2011-02-05T17:37:58.173 に答える