2011-02-05 3 views
0

TDD (SimpleTest)를 사용하여 첫 수업을했습니다. 그것은 꽤 잘 작동합니다. 이 클래스는 XML 구성 파일을 구문 분석하여 배열로 반환합니다. 어떻게 향상시킬 수 있습니까 (성능, 팁)? 수업 책임은 어떻습니까? 어쩌면 XMLtoArray 다른 클래스로 이동해야, 나도 몰라 ...PHP 클래스 개선

<?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 특성을 무시합니다. 감사합니다.

+3

http://codereview.stackexchange.com/ – RobertPitt

답변

0

이 성능에 나쁜 :

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

Aditionally가 (이 원하지 않는 방식으로 의견과 CDATA 섹션을 변경할 수 있습니다) 신뢰할 수있는 보장 할 수 없습니다. 더 나은 솔루션을 찾는 것은 쉽지 않습니다. 트리밍하는 모든 텍스트 노드를 반복하면 더 안정적 일 수는 있지만 더 빠를 수는 없습니다.

이 배열을 만들면 PHP의 SAX 파서 또는 SimpleXML이 더 적합 할 수 있습니다. 두 옵션 모두 더 빠를 수 있습니다 (테스트하지 않았습니다).

+0

으로 이동해야합니다.이 속성은 http://www.php.net/manual/en/class.domdocument.php#domdocument.props.preservewhitespace에 저장되었습니다. 고맙습니다. 어떤 팁? – thom

+0

@thom : 예 ... 그 옵션이 있어야한다고 생각했습니다. 내가 찾지 못한 이유는 무엇입니까? 어쨌든, 그때는 한 가지 개선이라고 생각합니다. – yankee

+0

남자, 당신은 저를 많이 도왔습니다. 자신을 비난하지 마십시오. D. 고맙습니다. – thom

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으로 옮겨야합니다.

+0

변경했습니다. 고맙습니다. – thom