Pull to refresh

Comments 42

1)
$this->pointer = &$this;
public function &appendChild($tag, $attributes)
в php5 обьекты передаются по ссылке, spl требует php5, зачем ставить ссылку? (сами же об этом пишите)
2)
стоит учитывать что __get не сработает при обращении к
private $pointer;
private $tagName;
private $attributes = array();
private $cdata;
private $parent;
private $childs = array();

а значит некоторые теги придется "потерять"
3)
не плохо бы ввести методы __isset() и __unset()

ps интересующимся могу предложить вариант написанный с использованием строковых функций парсер xml 2 array() http://weblancer.net/download/portfolio/…
1) передается, но если специально не указать, то объект будет склонирован, при попытке изменения, о чем я тоже написал
2) да, глупость, можно поставить перед именами переменных '_'
3) это просто и самому добавить - там просто :) статья писалась во-первых, чтобы пробежаться по всем возможностям пхп
1) http://www.php.net/manual/ru/language.oo… пример 6.
2) извиняюсь, тут arrayAccess вмешивается, но в общем случае именно так.
class xxx
{
private $test = 123;
function ___get($Name)
{
echo $Name;
}
}
$q = new xxx();
$q->test;


про xml 2 array в моем посте я упомянул, потому что обертку к libxml нельзя называть парсером, парсер - прямая работа с xml документом. см код.
1) Ну да, и этот пример как раз показывает, что иногда смысл ставить & всё же бывает. Например, когда вы передаёте какой-то объект и хотите, чтобы в случае замены изначального объекта был заменён и переданный объект. Хотя подобное бывает нужно крайне редко.
2) только-что проверил - срабатывает, на 5.2.1

а про xml=>array в начале поста я написал, см 1 ссылку
Статья интересная и познавательная, но начало "недолго думая, я решил написать свой" меня от души повеселило!
Интересно, что бы вы делали, если бы на хостинге не оказалось PHP? А веб-сервера?
Не стоит изобретать велосипед, проще найти нормальный хостинг где есть всё, что нужно для вашего проекта.
Такие усилия оправданы только в том случае, если изначально перед вами стояла задача написать собственный XML-парсер на PHP, а не какой-то коммерческий веб-сайт.
Велосипед этот изобретался во-первых ради интереса :)
К тому же проект этот делался "для себя"
Кстати тех-поддержка этого, на предложение поставить нужные модули ответила достаточно интересно:

I understand that you want to enable xml file, I am very sorry but we were advise by our seniors that we dont support xml file as of now because it gives an error on our php but our seniors are working on it to enable it.
Бежать без оглядки от таких хостеров.
Смените хостинг, от души советую.
У меня просто слёзы на глаза наворачиваются, когда я читаю такие вот "отписки" от саппорта :)
Если эти люди не в стостоянии собрать PHP с поддержкой DOM (которая, к слову, по умолчанию включена), я бы им даже крохотный "длясебяшный" проект не доверил...

Кстати, про статью. Вы лукавите :) Парсер вы не написали, вы написали только удобный интерфейс к нему. А libxml вы перепутали с XML-парсером expat - именно он предоставляет используемые вами функции xml_set_element_handler() и xml_set_character_data_handler().

Но ценность статьи для разминки мозгов это не уменьшает :)
UFO just landed and posted this here
seniors - это "старшаки" по-нашему? :)
Они бы еще пхп убрали, потому что небезопасен, апач - потому что 80-й порт открыт и вообще могут заддосить, ну и мускул может нагрузку на сервер создать - тоже снести.
UFO just landed and posted this here
UFO just landed and posted this here
Прочитайте хотя-бы до хабраката.
Это полезно и интересно - если не сумеешь изобрести велосипед, то какая речь может идти о машинах :)
UFO just landed and posted this here
Никогда не пишите, что бы вы могли сделать, если б могли =)
Спасибо интересено. Вот только по всей статье слово "указатель" лучше заменить на "ссылка".
Указателей в php нет :)
Мне понравилось как MS реализовала LINQ to XML. Не то чтобы что-то новое, но довольно так аккуратно.
public function offsetGet($offset) {
if (isset($this->attributes[$offset]))
return $this->attributes[$offset];
throw new Exception("Атрибута [$offset] не существует");
}

public function offsetExists($offset) {
return isset($this->attributes[$offset]);
}
--------------------------------------------------------
Метод offsetGet необходимо переписать с учетом существования метода offsetExists
На всякий случай:
SimpleXML, DOM, DOMXML в PHP5 это три разных модуля действительно работающие поверх упомянутой библиотеки libxml, причем модуль DOMXML это атавизм,
указанные вами функции
xml_set_character_data_handler
xml_set_element_handler
ни к указанным модулям PHP5, ни к libxml не имеют никакого отношения.

Не засоряйте людям мозги, если сами не разобрались
правильно подправили, не libxml, а expat,
Спасибо. Как раз мне нужно для одного документа создать дерево объектов наподобие DOM с простым доступом X->Y->Z. Теперь знаю как делать.
единственное примечание:
"поэтому" - слитно
"по порядку" - без дефиса

не поймите неправильно, сбивает просто при чтении
а статья классная, спасибо
Статья сбивает с толку. Полнейшая путаница с XML. Возможно стоило писать статью с упором на описание работы интерфейсов, "магических" методов и стандартной библиотеке, а не "я тут решил сделать свой XML парсер". К тому же, как правильно заметили выше, это не парсер, это обертка к нему. Ошибка по поводу передачи по ссылке объектов очень грубая. Исключения с сообщениями на русском не самое лучшее решение.
Из хорошего: статья очень хорошо оформлена ;)
А можно маленький вопрос?
А зачем так сложно?
Уж если делать простенький XML парсер - достаточно реализовать обыкновенный SAX parser и ВСЕ!
Безо всякой магии :)
Я не в коем случае не хочу сказать что сделано чтото плохо - конечно нет. Но просто существует гораздо более простой спосою. Под PHP я парсер не написал - не надо было, а вот под JS пожалуйста пример:

proto.saxParser = function() {
}

proto.saxParser.prototype.parse = function( dom, ignoreParent ) {
if ( ignoreParent ) {
if ( dom.documentElement ) {
this.parseRecursive( dom.documentElement );
} else if ( dom.tagName ) {
for ( var i = dom.firstChild; i; i = i.nextSibling ) this.parseRecursive( i );
}
}
else this.parseRecursive( dom, ignoreParent );
}

proto.saxParser.prototype.parseRecursive = function( dom ) {
if ( dom.documentElement ) {
this.startDocument( dom );
this.parseRecursive( dom.documentElement );
this.endDocument();
} else if ( dom.tagName ) {
this.startElement( dom );

for ( var i = dom.firstChild; i; i = i.nextSibling ) this.parseRecursive( i );

this.endElement( dom );
}
else this.characters( dom );
}

proto.saxParser.prototype.startDocument = function( doc ) {
}

proto.saxParser.prototype.startElement = function( el ) {
}

proto.saxParser.prototype.endElement = function( el ) {
}

proto.saxParser.prototype.characters = function( el ) {
}

proto.saxParser.prototype.endDocument = function() {
}


Все :) Весь парсер. Смысл я думаю объяснять не надо ) С задачей XML => Array справляется на ура и очень быстро )
По тому, что это замена SimpleXML - у него интерфейс другой, а про простой xml=>array я написал в первом абзаце и на него есть ссылка
бардак в названиях.

function offsetGet
function getIterator
function tag_close
во всем php кстати тоже :)
в spl они использую camel, да, а в остальных местах старую нотацию с '_'
А насколько быстро это работает? Я имею в виду насколько быстрее(или медленнее) по сравнению с SimpleXML и пр.
Интересно. Можно, в принципе написать и проще...
Вот, например простенький, но справляющийся со своей задачей XML парсер на JavaScript
http://www.codelibrary.ru/index.php?page=192
>> Мне требовался разбор не сложных rss-лент
http://simplepie.org/

При всем моем уважении к чужому труду, я так и не понял, зачем же все-таки изобретать велосипеды. Понятно, что люди это делают скорее для себя, но ведь можно воспользоваться готовыми решениями, особенно если задача стандартна (которые, уж поверьте, реализуют гораздо больше возможностей написанного вами чего-либо).
payalnik
Пишем свой XML-парсер
Решив запустить небольшой сервис на подаренном мне хостинге, оказалось, что там нету ни одного xml-парсера: ни SimpleXML, ни DOMXML, а только libxml и xml-rpc. Недолго думая, я решил написать свой

pc.speaker
Не обнаружив в доме ни одной женщины, недолго думая...
Я решил...
Статья хорошая.
А вот магические вещи PHP5 в ООП - плохие.
Методы __get() и __set() работают медленно! Рискуте так же меленно работать как JSP (Java Servlet Pages).

Так что аккуратнее с этими методами в высоконагрузочных проектах.
А еще print заменять на echo, да? :)
без разницы :) там разница не существенная
а здесь раз в 10 вызов метода __get() и __set() медленнее.
Хабр не хочет постить длинный комментарий - вот исходный код теста. Вот результаты:
Direct method: 10.228451728821
Magic methods: 46.129437685013


Ок, разница есть в 5 раз и это при 5 000 000 повторений. Нету никакого желания жертвовать удобством написания, ради такой мизерной разницы. Опкод-кешер даст прирост производительности в сотни раз больше.
Если не стоит сам SimpleXML, то и итератора этого нету
У меня есть вопрос , можете подсказать .
столкнулся с задачей - вывода из xml файла.
стоит использовать свой класс который с помошью строковых функции находит и заносит в массив данные из xml или использовать какой-то готовое решение?

вот класс

abstract class xml
{

protected $num_args;
protected $what_to_select_var;
protected $number_of_echo_news;
protected $variable;
protected $buffer;
protected $xml_path;
protected $counter;
protected $counter_s;
protected $possition_open;
protected $possition_close;


//конструктор вводи путь xml и количество выводов блоков
function __construct($xml_path,$number_of_print_blocks)
{
$this->xml_path = $xml_path;
$this->number_of_echo_news = $number_of_echo_news;
}

//заносим в буфер контент xml файла
function get_xml_file()
{
$this->buffer = file_get_contents($this->xml_path);
}


//достаём аргументы и количество аргументов вводимые в данную функцию (то что хотим вывести)
function what_to_select()
{
$this->num_args = func_num_args();
$this->what_to_select_var = func_get_args();
}

//заносим в матрицу $this->variable уже данные внутри тех тегов которые желаем вывести
function solve_variables()
{
for ($this->counter = 1 ; $this->counter number_of_echo_news ; $this->counter++)
{
for ($this->counter_s = 0 ; $this->counter_s < $this->num_args ; $this->counter_s++)
{
$this->possition_open = stripos($this->buffer,'') + 2 + strlen($this->what_to_select_var[$this->counter_s]);
$this->possition_close = stripos($this->buffer,' what_to_select_var[$this->counter_s].'>');
$this->variable[$this->counter][$this->counter_s] = substr($this->buffer , $this->possition_open , $this->possition_close - $this->possition_open);

$this->buffer = substr($this->buffer , $this->possition_close + strlen($this->what_to_select_var[$this->counter_s]) + 3);
}

}
}
abstract function printing();
}





и дочерний класс для вывода


class print_news extends xml
{
function printing()
{
for ($this->counter = 1 ; $this->counter number_of_echo_news ; $this->counter++)
{//цифры - поля которые желаем вывести
echo $this->variable[$this->counter][0]."\n";
echo $this->variable[$this->counter][1]."\n";
echo $this->variable[$this->counter][2]."\n";
echo $this->variable[$this->counter][3]."\n";


}
}
}


//тело скрипта
$obj = new print_news('./xml/news.xml',"5");
$obj->get_xml_file();
$obj->what_to_select('id','title','date','message');
$obj->solve_variables();
$obj->printing();
подскажите, а почему игнорируются такие тегиг как, напр., <name:exp></name:exp> (имею ввиду из-за налилчия ":" ) — и возможно переопределить этот момент при использовании SimpleXML?
Sign up to leave a comment.

Articles

Change theme settings