Последнее обновление:
Не используйте библиотеку simple_html_dom.php
Это библиотека предназначена для работы с HTML-содержимым при помощи DOM, т.е. по аналогии с javascript. Известно, что, если не принять специальных мер, язык РНР воспринимает код html точно также, как и любой другой текст – в виде константы типа string определенной длины. Чтобы с текстом (кодом) html можно было бы работать, используя модель DOM, нужны те или иные приемы.
Одним из них и является библиотека simple_html_dom.php. Ее можно подключить в любом месте файла рнр, например, следующим образом:
include($_SERVER['DOCUMENT_ROOT'].'/path/simple_html_dom.php');
После чего ее можно использовать. Да, можно. Не, не нужно.
Объем этой библиотеки занимает 63,5 КБайт. Вроде бы, немного. Число строк внутри ее файла – всего-то 1700 с небольшим. Казалось бы, ерунда. Однако, она существенно замедляет работу программ.
Пример
Рассмотрим простейший пример, из которого это видно. Поставим задачу:
Найти в конце некоего файла html последний тег <span> (имеющий id=”counter_comm” и вывести на экран его содержимое (т.е. текст, который он содержит).
В javascript эта задача вполне знакомая и решается в пару строк. На РНР, в принципе, все не намного сложнее.
Вот программный код, использующий библиотеку simple_html_dom.php:
$tim[1] = microtime(true);
$id_comm = 0;
$text = str_get_html($file_html);
if(is_object($text->find('span[id=counter_comm]',0))){
$id_comm = $text->find('span[id=counter_comm]',0)->plaintext;
echo "id_comm: ".$id_comm;
}else{
$file_html = '<div class="com"><div id="number_comm__">Значение счетчика <span id="counter_comm">0</span></div></div>';
}
Вначале этот код считывает текущее время в секундах с высокой точностью, заносит его в массив $tim[]. После чего ищет в текстовой переменной $file_html тег, имеющий указанный id и, если найдет, выводит его текстовое значение. Если же не найдет – то добавляет соответствующие html-теги со значением счетчика, равным нулю.
Однако, данный задачу вполне можно решить, используя чистый РНР, без этой библиотеки. Благо, РНР, как и javascript, вполне умеет работать с DOM. Надо лишь дать ему понять, что обрабатывается не просто текстовая (string) константа, а, именно – код html:
$tim[2] = microtime(true);
$id_comm1 = 0;
$domdocument = new domDocument('1.0', Encoding);
$domdocument->loadXML(XMLHead."<html><body>".mb_convert_encoding($file_html, "cp1251", "utf-8")."</body></html>");
$span_counter = $domdocument->getElementsByTagName("span");
// Получаем узел - последний тег <span> (т.е. тот, в котором находится счетчик)
$number = $span_counter->item($span_counter->length-1);
// Общее число счетчика (определяется по текстовому значению последнего тега <span> в файле ***-comments.html)
$id_comm1 = $number->lastChild->nodeValue;
echo "id_comm1: ".$id_comm1;
if($id_comm1 == 0)
$file_html = '<div class="com"><div id="number_comm__">Значение счетчика <span id="counter_comm">0</span></div></div>';
$tim[3] = microtime(true);
Как и ранее, записываем в указанный массив новое текущее время (которое совпадает с моментом окончания работы предпоследнего кода и начала работы последнего).
Затем указываем РНР, что имеем дело с html. Переменная $domdocument будет содержать html-код в соответствии с моделью DOM.
Точно также, как и в предыдущем случае, если число в последнем теге <span> равно нулю или он вовсе отсутствует, то в файл добавляются соответствующие теги, задающее значение счетчика, равное нулю.
После чего определяем конечное время – момент, когда второй код прекращает работу. Вывод времен работы обоих кодов осуществлялся следующим образом:
echo "time: ".($tim[2]-$tim[1])." ".($tim[3]-$tim[2]);
Примечание: Здесь используются константы, имеющие следующие значения:
// Стандартная кодировка документа
define('Encoding', 'windows-1251');
// Заголовок XML-документа
define('XMLHead', "<?xml version='1.0' encoding='".Encoding."'?>");
Как видим, объем кода практически тот же самый – в обоих случаях.
Сравниваем быстродействие
Оба программных кода тестировались на файле размером 184 Кбайт на локальном компьютере достаточно высокой производительности.
И вот каковы типичные результаты:
time: 0.17655420303345 0.010126829147339
time: 0.19093608856201 0.010679006576538
Видно, что разница есть. Первый код работает дольше второго – более, чем в 17 раз. Хотя, вроде бы – та же самая задача, тот же самый файл, тот же самый компьютер, и тот же самый РНР. Да и выполняются оба кода – один за другим.
А, так, может, как-то влияет кэширование? Для проверки этого предположения – поменяем местами указанные коды. Т.е. теперь вначале будет работать код без библиотеки, а потом – с библиотекой. Вот реультаты времени работы:
time: 0.012299060821533 0.18253898620605
time: 0.011257886886597 0.18212008476257
Что же, компьютер – не обманешь. Все равно тот код, который использует библиотеку, работает медленнее, как минимум, в 17 раз.
Самое интересное, что данная библиотека даже не дает никакой особой легкости для программиста. К с ее помощью, так и без нее – все равно не обойтись без написания программного кода, повторимся, примерно одинакового объема. Вот, для сравнения, те же данные, полученные при запуске указанных выше программных кодов на сервере:
time: 0.01199197769165 0.06469202041626
Код с библиотекой работает на севере почти в 3 раза быстрее (чем на локальном компьютере). Однако, тем не менее, все равно по быстроте проигрывает - почти в 6 раз. Так к тому же, замечено, что эта библиотека еще и способна неконтролируемо изменить код html, который обрабатывается при помощи нее. Например, она способна убрать все символы переноса строк, превращая код в нечто нечитаемое.
Отметим, что лишь ОДНА операция – поиска соответствующего тега <span> и считывание его текстового содержимого (что потребовала аж целых три вызова библиотечных функций) потребовали время, равное почти 0,2 секунды на локальном компьютере (свыше 0,05 с на сервере). А если таких операций будет на три, а 33? Или 333?... А если объем обрабатываемого кода html будет увеличен раз в 100? В таком случае – это уже будет не сайт, а тормозящая, поедающая ресурсы сервера, никому не нужная, а то и раздражающая пользователей – игрушка. После чего появятся посты где-нибудь на хабрахабре о «ненужности» языка РНР. А также о желании попробовать что-то «новое».
Так зачем и кому может понадобиться библиотека simple_html_dom.php?
Не в обиду ее разработчику, но, честно говоря, не знаю. Разве что, для того, чтобы реализовать довольно эффективный замедлитель работы программ на РНР (хотя, как видите, замедление-то осуществляется всего в 3...17 раз, все же; ведь не два-три порядка). И потом писать письма заказчикам (употребляя в них разного рода жаргонные «термины», используемые на компьютерных форумах и делая вид, что, мол, обижаемся из-за того, что заказчик, мол, такой «непонятливый»).
Письма на предмет того, что РНР, якобы, «мертвый» язык, медленный и т.п. И вообще, мол, если заказчик желает, чтобы все работало быстро, надо, типа того, весь его сайт переделывать, переводить на «более эффективный язык» (который по производительности может быть даже хуже). Или - переносить сайт на более скоростной хостинг.
Однако, как видим, язык РНР может работать быстро, главное, НЕ использовать ненужные библиотеки. Впрочем, на вкус и цвет = как говорится. Если кому по душе эта или иные аналогичные библиотеки - конечно, используйте на здоровье.