Advertisement
lignite0

better XMLMapper

May 8th, 2017
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 3.24 KB | None | 0 0
  1. <?php
  2.  
  3. abstract class XMLMapper
  4. {
  5.     public $xml;
  6.     public $visitors = [];
  7.     public $reference = null;
  8.     public $references = [];
  9.     private $lastVisitedNodeName;
  10.  
  11.     public function __construct()
  12.     {
  13.         $this->registerVisitors();
  14.         $this->xml = $this->createReader();
  15.     }
  16.  
  17.     public function parse()
  18.     {
  19.         $startMicrotime = microtime(true);
  20.         $this->xml->read();
  21.         $this->reference = $this->visitors;
  22.  
  23.         while ($this->xml->read()) {
  24.  
  25.             $type = $this->xml->nodeType;
  26.             $name = $this->xml->name;
  27.  
  28.             if ($type === XMLReader::END_ELEMENT) {
  29.  
  30.                 if ($this->lastVisitedNodeName === $name) {
  31.                     $this->reference = array_pop($this->references);
  32.                 }
  33.  
  34.                 $method = $this->reference[$name]['leave'] ?? null;
  35.                 if ($method !== null) {
  36.                     call_user_func([$this, $method]);
  37.                 }
  38.  
  39.                 continue;
  40.             }
  41.  
  42.             if ($type === XMLReader::ELEMENT) {
  43.  
  44.                 $visitor = $this->reference[$name] ?? null;
  45.                 if ($visitor !== null) {
  46.                     $this->references[] = $this->reference;
  47.                     $this->lastVisitedNodeName = $name;
  48.                     $this->reference = $visitor;
  49.                     $method = $visitor['enter'] ?? null;
  50.                     if ($method != null) {
  51.                         call_user_func([$this, $method]);
  52.                     }
  53.                 }
  54.  
  55.                 continue;
  56.             }
  57.         }
  58.  
  59.         $this->duration = microtime(true) - $startMicrotime;
  60.     }
  61.  
  62.     abstract protected function createReader(): XMLReader;
  63.  
  64.     private function registerVisitors()
  65.     {
  66.         $methods = get_class_methods(static::class); // pobierz nazwy wszystkich method klasy potomnej
  67.         foreach ($methods as $method) { // dla każdej metody
  68.             $parts = explode('_', $method); // rozstrzel jej nazwę na części
  69.             $first = array_shift($parts); // zdejmij pierszy element;
  70.             if (!in_array($first, ['enter', 'leave'])) { // jeżeli pierwszy element to żaden z podanych
  71.                 continue; // przejdź do przetwarzania natępnej metody
  72.             }
  73.             $reference = &$this->visitors; // ustaw referencję na visitors
  74.             while (count($parts) > 0) { // dokóki istnieją elementy
  75.                 $part = array_shift($parts); // to sciągaj po jednym
  76.                 if (!isset($reference[$part])) { // jeżeli taki element nie istnieje w visitorach
  77.                     $reference[$part] = []; // to nadaj mu pustą tablicę
  78.                 }
  79.                 $reference = &$reference[$part]; // i przesuń referencję na niego
  80.             }
  81.             $reference[$first] = $method; // wstaw do ostatniej tablicy nazwę metody
  82.         }
  83.     }
  84. }
  85.  
  86. class CustomXMLMapper extends XMLMapper
  87. {
  88.     protected function createReader(): XMLReader
  89.     {
  90.         $xml = new XMLReader();
  91.         $xml->open('document.xml');
  92.  
  93.         return $xml;
  94.     }
  95.  
  96.     protected function enter_offer_name()
  97.     {
  98.         echo $this->xml->readString().PHP_EOL;
  99.     }
  100. }
  101.  
  102. $xml = new CustomXMLMapper();
  103. $xml->parse();
  104. sleep(120);
  105. echo '';
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement