Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- abstract class XMLMapper
- {
- public $xml;
- public $visitors = [];
- public $reference = null;
- public $references = [];
- private $lastVisitedNodeName;
- public function __construct()
- {
- $this->registerVisitors();
- $this->xml = $this->createReader();
- }
- public function parse()
- {
- $startMicrotime = microtime(true);
- $this->xml->read();
- $this->reference = $this->visitors;
- while ($this->xml->read()) {
- $type = $this->xml->nodeType;
- $name = $this->xml->name;
- if ($type === XMLReader::END_ELEMENT) {
- if ($this->lastVisitedNodeName === $name) {
- $this->reference = array_pop($this->references);
- }
- $method = $this->reference[$name]['leave'] ?? null;
- if ($method !== null) {
- call_user_func([$this, $method]);
- }
- continue;
- }
- if ($type === XMLReader::ELEMENT) {
- $visitor = $this->reference[$name] ?? null;
- if ($visitor !== null) {
- $this->references[] = $this->reference;
- $this->lastVisitedNodeName = $name;
- $this->reference = $visitor;
- $method = $visitor['enter'] ?? null;
- if ($method != null) {
- call_user_func([$this, $method]);
- }
- }
- continue;
- }
- }
- $this->duration = microtime(true) - $startMicrotime;
- }
- abstract protected function createReader(): XMLReader;
- private function registerVisitors()
- {
- $methods = get_class_methods(static::class); // pobierz nazwy wszystkich method klasy potomnej
- foreach ($methods as $method) { // dla każdej metody
- $parts = explode('_', $method); // rozstrzel jej nazwę na części
- $first = array_shift($parts); // zdejmij pierszy element;
- if (!in_array($first, ['enter', 'leave'])) { // jeżeli pierwszy element to żaden z podanych
- continue; // przejdź do przetwarzania natępnej metody
- }
- $reference = &$this->visitors; // ustaw referencję na visitors
- while (count($parts) > 0) { // dokóki istnieją elementy
- $part = array_shift($parts); // to sciągaj po jednym
- if (!isset($reference[$part])) { // jeżeli taki element nie istnieje w visitorach
- $reference[$part] = []; // to nadaj mu pustą tablicę
- }
- $reference = &$reference[$part]; // i przesuń referencję na niego
- }
- $reference[$first] = $method; // wstaw do ostatniej tablicy nazwę metody
- }
- }
- }
- class CustomXMLMapper extends XMLMapper
- {
- protected function createReader(): XMLReader
- {
- $xml = new XMLReader();
- $xml->open('document.xml');
- return $xml;
- }
- protected function enter_offer_name()
- {
- echo $this->xml->readString().PHP_EOL;
- }
- }
- $xml = new CustomXMLMapper();
- $xml->parse();
- sleep(120);
- echo '';
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement