Eval или include?
Раздел:
Programming /
PHP
@
24.04.2008 |
Ключевые слова: framework php eval include
Автор: Apostol
Источник: habrahabr
Один из текущих проектов разрабатываю на собственном фреймворке, параллельно его обкатывая и дописывая. Зачем мне понадобилось изобретать велосипед, и чем он отличается от существующих, напишу когда буду представлять его общественности. Сейчас же хочется поделиться некоторыми мыслями по поводу производительности и заодно выслушать мнения коллег. Возможно, мои наблюдения будут полезны и тем, кто не использует фреймфорки.
Когда пришлось реализовывать дерево комментариев, столкнулся с необходимостью рекурсивного вызова представления (view в MVC). Так как представления у меня, да и практически везде, — это обычные файлы с кусками HTML-кода и возможностью вставки PHP, то подключаются они с помощью include. Мне стало не по себе, когда представил как этот include вызывается рекурсивно сотни раз. Первая мысль — засунуть файл представления при первом запросе в память и потом выполнять его через eval. Такой подход позволит кешировать код представлений, и даже хранить его в БД. Так как eval кушает только PHP, а представления у нас чистым PHP-кодом не являются, то обрамляем содержимое в `?>` и `<?php`.
Итак, за дело.
Тесты
Для начала, разными способами в цикле выведем простенькое представление `view.php`, содержащее, например: i=<?=$i?>
Код |
|
Время, с (в скобках — с eAccelerator) |
for($i=0; $i<100; $i++) include (`view.php`);
|
|
0,0058141 (0,002068) |
for($i=0; $i<100; $i++){
$code=` ?>`.file_get_contents(`view.php`).`<?php `;
eval($code);
}
|
|
0,005527 (0,0056472) |
$code=` ?>`.file_get_contents(`view.php`).`<?php `;
for($i=0; $i<100; $i++){
eval($code);
}
|
|
0,0015929 (0,0016122) |
И рекурсивно
Код |
|
Время, с (в скобках — с eAccelerator) |
$i=0;
include(`view.php`);
---------- view.php ----------
html
<?php
if(++$i<100){
include(`view.php`);
}
?>
|
|
0,006865 (0,0019491) |
$i=0;
$code=` ?>`.file_get_contents(`view.php`).`<?php `;
eval($code);
---------- view.php ----------
html
<?php
if(++$i<100){
$code=` ?>`.file_get_contents(`view.php`).`<?php `;
eval($code);
}
?>
|
|
0,008599 (0,0087898) |
$i=0;
$code=` ?>`.file_get_contents(`view.php`).`<?php `;
eval($code);
---------- view.php ----------
html
<?php
if(++$i<100){
eval($code);
}
?>
|
|
0,0034332 (0,0032461) |
Выводы
Первое, что бросается в глаза — варианты с eval не поддаются оптимизации и кешированию с помошью eAccelerator. Поэтому, если вы его используете и вам не нужны другие преимущества eval — лучше остановитесь на include.
Использование eval имеет смысл там, где представления вызываются многократно, но нет возможности использовать акселераторы. Или если представления хранятся в БД.
Немного отличается и обработка ошибок в eval. При возникновении ошибки разбора кода, например, выполнение скрипта не прерывается. Это может быть полезно в некоторых случаях. Но при этом, сообщение об ошибке выглядит по другому, что может немного сбить с толку:
Parse error: syntax error, unexpected T_ECHO, expecting `)` in /www/test/eval_vs_include/test.php(39) : eval()`d code on line 4
Здесь указанная ошибка возникла в 4 строке файла view.php, который был скормлен в eval, расположенный в 39 строке файла test.php. Конечно, нам ничего не мешает выводить и название подключаемого файла, если eval возвратил false. Учитывая, что работа над ошибками — это не штатный режим, и на рабочем проекте ошибки не выводятся, считаю указанный недостаток не существенным.
Eval
+ Быстрее чем include, если не используются акселераторы
+ Возможность кеширования кода представлений во фреймворке или шаблонизаторе
+ Возможность хранения представлений в БД
+ Выполнение скрипта не прерывается при возникновении ошибок
- Не оптимизируется и не кешируется внешними акселераторами
- Вывод ошибок отличаться от привычного
- На некоторых хостингах может быть запрещено выполнение eval
Include
+ Работает везде
+ Внешние акселераторы на много увеличивают производительность
- Низкая скорость без акселераторов
- Нет возможности кешировать подключаемый из файла код в своём движке
- Подключаемый код может находиться только в файле
Следует отметить, что во фреймворке CodeIgniter eval тоже используется для вывода представлений, но только в том случае, если в настройках указана необходимость замены коротких `<?=` на `<?php есho` и при этом в настройках PHP короткие теги будут отключены. Во всех остальных случаях используется include. В CakePHP всегда используется include.
Это интересно:
Распечатать статью
Вернуться в раздел:
Programming /
PHP
Реклама: