На пути к идеалу
Опубликовано 7 февраля 2008, автор: Иван Блинков
...или 15 привычек, которые помогут ускорить PHP-приложение
Практически каждый программист стремится в своих приложениях не только максимально точно реализовать требуемый функционал, но и сделать это как можно более эффективным методом. Для этого конечно же необходимо проектирование, подходящий выбор используемых технологий, возможно некоторый опыт в предметной области, этот список можно продолжать достаточно долго, но я позволю себе этого не делать, так как речь сегодня пойдет не об этом. Вместо этого хочу обратить Ваше внимание на более простые и «приземленные» методы оптимизации PHP-кода, которые может быть и не так эффективны по сравнению с указанными выше, но зато не требуют каких-либо усилий со стороны кодера и/или программиста, достаточно лишь воспринимать их как «не вредные» привычки.
Прочитав достаточно солидный объем разного рода документации по PHP, я часто натыкался на статьи и тексты, так или иначе связанные с производительностью PHP-скриптов. Порой в такого рода источниках информации удавалось найти достаточно интересные и неочевидные факты об этом языке программирования, которые не смотря на свою простоту могли дать вполне заметный прирост к производительности итогового приложения. Я почему-то очень серьезно стал относиться к производительности написанных мной скриптов, и довольно часто стал испытывать на практике спорные моменты в реализации, о которых узнавал из Сети или каких-либо других источников, с помощью самописных или opensource benchmark'ов, хотя порой и просто внедряя в реальные приложения. Как ни странно, в большинстве случаев практика подтверждала теорию, и я стал постоянно пользоваться этими простыми правилами, о которых я и хочу Вам рассказать.
Повышения значения индекса с помощью ++$i;
Этот факт был наверное одним из самых удивительных для меня, когда я впервые о нем услышал, но действительно операция ++$i; выполняется несколько быстрее, чем $i++;. или другие вариации на ту же тему вроде $i+=1;. Привычка использовать в качестве индекса цикла переменную под названием i, казалось бы стара как Мир, мне она досталась в наследство от C, а в месте с ней «в комплекте» шла привычка писать выражение i++ в заголовках циклов. Разница в скорости обработки этих выражений, насколько мне известно, обусловлена разным количеством элементарных машинных операций, которые необходимо выполнить процессору (в точных цифрах не уверен, пишу по памяти, но ++$i; требует трех элементарных операций, а $i++; – четырех). В справедливости этого факта не трудно убедиться, достаточно написать простенький скрипт, состоящий из цикла с достаточно большим количеством итераций, и замерить любым способом точное время его выполнения при использовании разных способов инкрементации индекса цикла.
Вывод статического контента без помощи PHP
Сейчас тот факт, что использование интерпретатора PHP для вывода статического контента сильно замедляет этот процесс, кажется мне очевидным, но поначалу я использовал echo там, где он был необходим, ничуть не чаще, чем там, где он лишь замедляет работу скрипта. От использования еще менее эффективного способа — print, меня избавила моя лень: писать каждый раз на одну букву больше дико не хотелось (в отличии от echo, print возвращает информацию об успешности выполнения своей работы, что в большинстве случаев просто-напросто не нужно). Проверить опять же не трудно — нужен лишь объемистый текстовый файл, который достаточно вывести в browser разными способами и засечь уходящее на это время.
Вывод статического контента из отдельного файла
Частенько при желании выполнить указанное в заголовке действие по привычке используют include, require или их _once версии, что является далеко не самой лучшей идеей с точки зрения производительности. Самым быстрыми быстрыми и экономичными поотношению к оперативной памяти являются функции readfile и fpassthru. В качестве доказательства этого факта приведу таблицу, демонстрирующую статистику выполнения этой операции различными методами и позаимствованную с :
| Функция | Время (сек.) | Оперативная память (байт) | ||
|---|---|---|---|---|
| 32Kb файл | 1Mb файл | 32Kb файл | 1Mb файл | |
| file_get_contents | 0.00152 | 0.00564 | 52480 | 1067856 |
| fpassthru | 0.00117 | 0.00184 | 20016 | 20032 |
| fgets | 0.00195 | 0.07190 | 30760 | 30768 |
| file | 0.00157 | 0.06464 | 87344 | 2185624 |
| require_once | 0.00225 | 0.08065 | 67992 | 2067696 |
| readfile | 0.00117 | 0.00191 | 19192 | 19208 |
Вывод переменных
Наверняка вам известно, что переменные можно выводить с помощью конструкции вроде echo «$var text»;, что является одним из самых удобных вариантов решения этой задачи благодаря минимальному количеству символов, которые необходимо набрать, но с точки зрения быстродействия этот вариант далек от идеала, так как влечет за собой достаточно серьезные преобразования в памяти сервера, эффект которых порой бывает заметен невооруженным глазом. Частично ущерб производительности можно сгладить заменой этой конструкции на echo $var.« text»;, что приводит к несколькому усложнению внешнего вида кода и несколько поправляет ситуацию со скоростью выполнения. Но как известно знак . обозначает конкатенацию двух строк, что тоже требует некоторых вычислений и затрат памяти, но и от нее можно избавиться, заменив на запятую. Выражение echo $var,« text»; ничем по своему эффекту не отличается от предложенных ранее вариантов, за исключением максимального быстрого выполнения, обусловленного отсутствием дополнительных преобразований в процессе передачи просто последовательности из константы и переменной.
Избегайте выполнения лишних действий
Достаточно абстрактное утверждение, но тем не мение постоянное напоминание себе о нем может избавить Вас от совершения массы ошибок. Самой широкораспространенной является наверное вызов какой-либо функции (чаще всего count(); или strlen();) в проверке условия выхода из цикла. Когда-нибудь доводилось писать видеть в собственном или чужом коде выражение вида for($i = 0; $i < count($array); ++$i) { ... }? А задумываться о последовательности выполнения действий при его обработке? Стоит только немного начать размышлять и ошибка становится очевидной: count(); выполняется при каждой итерации цикла, что приводит к подсчету количества элементов массива при каждой проверки условия выхода из цикла — почему бы не посчитать это значение заранее и сравнивать значения индекса с переменной, а не с результатом выполнения функции?
@
Использование этого оператора стоит избегать при каждой возможности. Казалось бы такое простое действие, как сокрытие вывода возможного сообщения об ошибке, влечет за собой достаточно трудоемкую последовательность действий: устанавливает значение параметра PHP-интерпретатора error_reporting = 0, выполняет указанное за этим оператором действие, возвращает значение error_reporting в исходное состояние.
Маленькие мелочи
Развивая тему предыдущего подраздела, хочется обратить внимания, что даже на еще более элементарных вещах можно сэкономить драгоценное процессорное время:
- Вместо условия if($variableOne == $variableTwo) { ... } можно написать if($variableOne === $variableTwo) { ... }, что избавит от проверки на соответствие типов данных и приведения их друг к другу, в некоторых случаях эти действия эти случаях эти действия конечно же и бывают необходимы, но бывает это далеко не часто.
- Глядя на выражения вроде if($boolean == true) { ... }, я чаще всего вспоминаю цитату из одного малоизвестного интернет-ресурса: if (b.ToString ().length < 5) { ... }. Хоть и не имет никакого отношения к PHP, но суть проблемы отражает очень ярко.
- Самым очевидным способом проверить попадает ли длина строки в какой-либо диапазон является использование функции strlen(); и сравнение полученного результата с фиксированными значениями, но зачем выполнять лишний вызов функции, если можно воспользоваться услугами конструкцией языка PHP isset(); для определения наличия в строке определенных символов. if(isset($str{5})) { ... } приведет к абсолютно тем же результатам, что и if(strlen($str)>4){ ... }
- Битовые операции выполняются намного быстрее относительно обычных арифметических действий. Об этом факте редко вспоминают, да и работать с ними умеет далеко не каждый, но порой они бывают очень актуальны, особенно при частой работе с числами кратными двойке.
- Угадайте, что делает интерпретатор при виде надписи 1/2? Правильно: делит 1 на 2. Зачем лишний раз утруждать его, когда можно написать просто половину — 0.5.
- При возвращении значения переменной из функции при помощи global выполняется на порядок больше действий, чем при классическом return.
- Конечно же фраза $array[text]; интерпритируется практически точно так же, как и $array['text'];, но зачем выполнять лишнее преобразование из необъявленной константы в строку, проверять, что такой константы все же не существует, выводить сообщение типа E_NOTICE, если можно всего этого не делать?
- По возможности не используйте require_once(); или include_once(); неоднократно по отношению к одному и тому же файлу. При отсутствии какого-либо эффекта, попусту тратится время на обработку повторного запроса.
- Даже «безобидных» ошибок стоит избегать, лишняя проаерка потратит не так много процессорного времени, как генерирование достаточно длинного сообщения об ошибке и вывод его в stdout, stderr или лог-файл, а также не стоит забывать, что даже «безобидные» ошибки могут стать потенциальной угрозой безопасности приложения вцелом.
В заключении...
...хотелось бы упомянуть одну из первых статей по для этого текста. В качестве возможных вариантов продолжения чтения про PHP хотелось бы предложить Вам соответствующие раздел сайта, серию статей, тэг и RSS-ленту.

31 комментарий на запись “На пути к идеалу”
А знаете как это все обходится?
1. Робот заходит на сайт и пытается сделать защищенное каптчей действие
2. Получив сгенерированную каптчу робот регистрирует ее для распознавания на одном из подшефных порносайтов.
3. На порносайт приходит посетитель и с радостью распознает каптчу, чтобы получить возможность бесплатно увидеть «вареник на весь экран».
4. Робот, получив ответ от порносайта — предоставляет его целевому сайту и таким образом проходит защиту.
5. Следует учесть, что посещаемости порносайта хватает для того, чтобы все шаги с 2-го по 4-й выполнить за 1 — 2 минуты, то есть, робот успевает предоставить распознаный текст до обрыва сессии сервером.
Конечно, если Ваш ресурс будут ломать с использованием описаного приема, значит ресурс очень ценен. Так как это дорогой прием
Ага, я читал в свое время об этом методе, но против него есть другая очень действенная мера — бан по IP. Правда и это при желании можно обойти, но войну можно вести до бесконечности...
if (isset ($str{5})) { … }
приведет к абсолютно тем же результатам, что и
if (strlen ($str)>4){ … }
во-первых, читабельность резко ухудшается (тогда уж можно и на Си перейти, хаха)
во-вторых, почему вы думаете что strlen () реализвана медленнее чем взятие элемента строки? и то, и strlen может быть реализована как угодно, в том числе и оптимизированно
в-третьих, textarea слишком маленькая
, 4 строки и границы её еле незаметны (весьма неудобно)
Насчет strlen vs isset: проверить справедливость этих слов можно с помощью любого синтетического теста (ab, siege и т.д.), проведенного на паре простеньких скриптов:
против
< ?php $str="какой-нибудь длинный текст"; if(isset($str{5}))echo "+"; ?>После нескольких миллионов итераций мой ноутбук выполнял первый в среднем за 65-70 мс, а второй — за 25-35.
по поводу циклов, можно вот такой более красивый вариант
поправте пожалуйста последнее еще раз
не пойму почему обрезает
[quote comment="186"]поправте пожалуйста последнее еще раз
не пойму почему обрезает[/quote]Исправил, CMS слишком активно борется с потенциальным вредоносным кодом, который мог бы быть подсунут читателями, и по-этому чистит все подозрительное из комментариев.
[quote comment="184"]по поводу циклов, можно вот такой более красивый вариант[/quote]
Как раз на использование подобных конструкций я и пытался подтолкнуть читателей в одном из абзацев этого поста.
Не ругайте если я не в тему... конечно необходимо знать отличия ращличных функция. Но зачем заморачиваться так с мелочами как уже подмечено коментатором выше?
Код в высокоуровневом языке должен быть в первую очередь создан для удобногт и быстрого понимания с чёткой структурой. Для лудей короче...
Хотя в общем полезность статьи не отрицаю!
[quote comment="193"]Но зачем заморачиваться так с мелочами как уже подмечено коментатором выше?[/quote]При отсутствии каких-либо издержек на проектирование и прочие глобальные вещи, просто привыкнув не совершать мелкие ошибки в коде можно избежать возникновения многих потенциальных проблем и «узких мест» в веб-приложении.
Смешно и глупо, так же как и бежать на другой конец города за помидорами которые стоят на 50 копеек дешевле, за киллограм.
Потому что мы вопервых убъем вагон времени, а во вторых результат будет практически нулевой. Легче потратить 10 минут и привести в порядок бизнес логику, например убрать пару лишних циклов.
А если у вас две сотни запросов к странице в секунду и даже конкатенация строк для вас является критичной — то имхо следует или прикупить еще один сервер или полностью менять бизнес логику (что чаще всего) или перейти на другую платформу.
[quote comment="223"]Смешно и глупо, так же как и бежать на другой конец города за помидорами которые стоят на 50 копеек дешевле, за киллограм.[/quote]Вы наверное не до конца осознали задумку статьи, могу посоветовать перечитать вступление.
Не нужно «убивать вагон времени», я лишь хотел показать читателям, как можно приучить себя не допускать мелких ошибок в коде, которые могут многократно повторяясь стать узким местом системы.
Я понял задумку статьи, и единственный дельный совет в теме про count в теле цикла for, который действительно часто становится тем узким местом по глупости программиста.
А пишешь ли ты $i++ или $array[text] — уже второстепенно, и не важно.
[quote comment="225"]А пишешь ли ты $i++ или $array[text] — уже второстепенно, и не важно.[/quote]Могу поспорить: все упирается в масштабы и цель приложения, а также в частоту возникновения таких ошибок.
В моей скромной практике программирования на PHP были случаи возникновения узких мест в компонентах приложения благодаря очень многим из описанных ошибок, $i++ и $array[text] — в их числе.
2ashofthedream $array['text'] и $array[text] это сильно разные вещи. Если не интересует производительность приложения, то вобще ИМХО тратить время на такие статьи...
2автор Очень интересно было узнать про файлы (чтение из файлов), спасибо... Остальное как-то знал
По поводу ++$i и $i++ окромя лишнего такта (наверное, верю на слово
) они ещё отличаются тем, что во втором случае создаётся новая временная переменная (Совершенный код, сию книгу должен прочитать ИМХО каждый прогер).
[quote comment="255"]2автор Очень интересно было узнать про файлы (чтение из файлов), спасибо... Остальное как-то знал
[/quote]Тем не менее хоть какую-то мелочь, но узнали — значит не зря потратили время
[quote comment="255"]По поводу ++$i и $i++ окромя лишнего такта (наверное, верю на слово
) они ещё отличаются тем, что во втором случае создаётся новая временная переменная[/quote]Cомневаюсь, если честно, в достоверности этой фразы, насколько я знаю указатель на область памяти один и тот же используется, хотя точно гарантировать не могу...
[quote comment="255"]Совершенный код, сию книгу должен прочитать ИМХО каждый прогер[/quote]Хм, а можно оригинальное название книги и автора?
Можно:
Утверждение, что echo “$var text” ЗНАЧИТЕЛЬНо более эффективное, чем echo $var."text” считаю как минимум спорным, если не сказать больше.
Поэтому возникает резонный вопрос, проводил ли автор тест? Я делал тесты на PHP5 и могу утверждать, что разница миминальна (около 1%) и минимальна на столько, что может быть отнесена к статистической прогрешности.
[quote comment="265"]Можно:
[quote comment="266"]Утверждение, что echo “$var text” ЗНАЧИТЕЛЬНо более эффективное, чем echo $var."text” считаю как минимум спорным, если не сказать больше.
Поэтому возникает резонный вопрос, проводил ли автор тест? Я делал тесты на PHP5 и могу утверждать, что разница миминальна (около 1%) и минимальна на столько, что может быть отнесена к статистической прогрешности.[/quote]Можно вопрос: а где Вы в тексте нашли слово значительно?
Да, я проводил синтетические тесты для большинства из упоминавшихся фактов, цифры естественно воспроизвести не могу, так как было это задолго до написания этого поста, но факты подтверждались во всех случаях. Конкретно в этом варианте даже по-моему невооруженным глазом можно было заметить разницу (если мне память не изменяет).
Если говориться, что разницу можно заметить невооруженным глазом, то уже понятно, что разница эта значительно (не менее 0,5 сек, имхо меньше человек просто не в состоянии отследить). Вот и получается, что «значительно» следует из контекста.
Я проводил текст (подчеркиваю! на PHP5) и там не то, что на глаз разницы не видно, разница составила менее 1%. А вариант echo “$var text” значительно более читабельнее и удобнее. Поэтому смысла в echo $var." text” большого не вижу. Читабельность значительно хуже, скорость практически таже самая.
[quote comment="275"]Если говориться, что разницу можно заметить невооруженным глазом, то уже понятно, что разница эта значительно (не менее 0,5 сек, имхо меньше человек просто не в состоянии отследить). Вот и получается, что «значительно» следует из контекста.
Я проводил текст (подчеркиваю! на PHP5) и там не то, что на глаз разницы не видно, разница составила менее 1%. А вариант echo “$var text” значительно более читабельнее и удобнее. Поэтому смысла в echo $var." text” большого не вижу. Читабельность значительно хуже, скорость практически таже самая.[/quote]
Если честно не хочу ставить перед собой цель пытаться Вас переубедить, но если мне не изменяет память, то на достаточно большом количестве текста (FreeBSD Handbook в нескольких экземплярах по-моему использовал) реально можно было получить видимую разницу.
Может быть попробую повторить тест как-нибудь в ближайшем будущем и привести цифру, но сейчас просто-напросто нет ни сил ни времени.
echo “$var text” ЗНАЧИТЕЛЬНо более эффективное, чем echo $var.”text”
в последнем нужно писать так $var.'text'
PHP не разбирает строку, если она заключена в одинарные кавычки. Если строка заключена в двойные кавычки, то php парсит ее, пытаясь найти в ней переменные и т.д. Это даже в официальном руководстве написано. Поэтому при выводе обычного текста заключайте его в одинарные кавычки.
[quote comment="320"]PHP не разбирает строку, если она заключена в одинарные кавычки. Если строка заключена в двойные кавычки, то php парсит ее, пытаясь найти в ней переменные и т.д. Это даже в официальном руководстве написано. Поэтому при выводе обычного текста заключайте его в одинарные кавычки.[/quote]Я лично всегда относил это к мифам о PHP, ссылку на более-менее достоверное подтверждение этого факта ни один сторонник этого утверждения мне так до сих пор и не привел, может быть у Вас получится стать первым?
Касательно строк в одинарных и двойных кавычках — посмотрите как работает лексический сканнер в ZE2 — и сразу все станет понятно
Даже никаких тестов не надо, чтобы убедиться, что print «Foo» работает медленнее, чем print 'Foo'.
Вырезка из сканнера:
scalar: T_STRING { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_RT, 1 TSRMLS_CC); } | T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_constant(&$$, NULL, &$2, ZEND_RT, 0 TSRMLS_CC); } | T_STRING_VARNAME { $$ = $1; } | class_constant { $$ = $1; } | common_scalar { $$ = $1; } | '"' { CG(literal_type) = UG(unicode)?IS_UNICODE:IS_STRING; } encaps_list '"' { $$ = $3; } | T_START_HEREDOC { CG(literal_type) = UG(unicode)?IS_UNICODE:IS_STRING; } encaps_list T_END_HEREDOC { $$ = $3; } | T_BINARY_DOUBLE { CG(literal_type) = IS_STRING; } encaps_list '"' { $$ = $3; } | T_BINARY_HEREDOC { CG(literal_type) = IS_STRING; } encaps_list T_END_HEREDOC { $$ = $3; } ; encaps_list: encaps_list encaps_var { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_add_variable(&$$, &$1, &$2 TSRMLS_CC); } | encaps_list T_ENCAPSED_AND_WHITESPACE { zend_do_add_string(&$$, &$1, &$2 TSRMLS_CC); } | /* empty */ { zend_do_init_string(&$$ TSRMLS_CC); } ; encaps_var: T_VARIABLE { zend_do_begin_variable_parse(TSRMLS_C); fetch_simple_variable(&$$, &$1, 1 TSRMLS_CC); } | T_VARIABLE '[' { zend_do_begin_variable_parse(TSRMLS_C); } encaps_var_offset ']' { fetch_array_begin(&$$, &$1, &$4 TSRMLS_CC); } | T_VARIABLE T_OBJECT_OPERATOR T_STRING { zend_do_begin_variable_parse(TSRMLS_C); fetch_simple_variable(&$2, &$1, 1 TSRMLS_CC); zend_do_fetch_property(&$$, &$2, &$3 TSRMLS_CC); } | T_DOLLAR_OPEN_CURLY_BRACES expr '}' { zend_do_begin_variable_parse(TSRMLS_C); fetch_simple_variable(&$$, &$2, 1 TSRMLS_CC); } | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' { zend_do_begin_variable_parse(TSRMLS_C); fetch_array_begin(&$$, &$2, &$4 TSRMLS_CC); } | T_CURLY_OPEN variable '}' { $$ = $2; } ; encaps_var_offset: T_STRING { $$ = $1; } | T_NUM_STRING { $$ = $1; } | T_VARIABLE { fetch_simple_variable(&$$, &$1, 1 TSRMLS_CC); } ;(продолжение коммента)
Как видите, в случае print «Foo» ZE2 делает разбор строки на предмет наличия в них переменных (скаляров, массивов, объектов, функций) — следовательно разбор скрипта занимает больше времени, по стравнению с print 'Foo'.
Вопрос касательно времени выполнения скрипта _после парсинга_ остается открытым
[quote comment="428"](продолжение коммента)
Как видите, в случае print «Foo» ZE2 делает разбор строки на предмет наличия в них переменных (скаляров, массивов, объектов, функций) — следовательно разбор скрипта занимает больше времени, по стравнению с print 'Foo'.
Вопрос касательно времени выполнения скрипта _после парсинга_ остается открытым
[/quote]Т.е. по-вашему всем выводом данных переменных через echo/print занимается Zend Engine 2?
Хотя все равно хотелось бы все же увидеть цифры или просто какой-либо более достоверный источник...
Вы хотите сказать, что CVS-репозиторий PHP для Вас не является достоверным источником?
[quote comment="435"]Вы хотите сказать, что CVS-репозиторий PHP для Вас не является достоверным источником?
[/quote]Нет, я не вижу ни одного доказательства, что приведенный Вами кусок кода используется при реализации echo. По мне так просто приведен список вызовов функций, которые тоже не сильно понятно что именно делают, так как надо искать их тело...
Копаться в исходниках PHP это конечно хорошо, но оно того не стоит по-моему...
[quote post="25"]alekciy писал:
Можно:
Спасибо![/quote]
по приведенной ссылке скачать могут только зарегистрированные пользователи. привожу ссылку для скачивания без регистрации:
[quote comment="478"][quote post="25"]alekciy писал:
Можно:
Спасибо![/quote]
по приведенной ссылке скачать могут только зарегистрированные пользователи. привожу ссылку для скачивания без регистрации:
[quote comment="430"]Т.е. по-вашему всем выводом данных переменных через echo/print занимается Zend Engine 2?[/quote]
А вы, извините, думали чем занимается ZE2? ZE2 делает полную обработку исходного кода на языке PHP, строит дерево и производит его выполнение.
И как раз разбор строк в разных кавычках входит в процесс парсинга и построения дерева.
[quote comment="438"][quote comment="435"]Вы хотите сказать, что CVS-репозиторий PHP для Вас не является достоверным источником?
[/quote]Нет, я не вижу ни одного доказательства, что приведенный Вами кусок кода используется при реализации echo. По мне так просто приведен список вызовов функций, которые тоже не сильно понятно что именно делают, так как надо искать их тело...
Копаться в исходниках PHP это конечно хорошо, но оно того не стоит по-моему...[/quote]
Посмотрете внимательней, и вы заметите выделенные красным цветом фрагменты. Это именно те места, в которых происходит дополнительный разбор строки в двойных кавычках. Ваша неграмотность относительно построения парсеров еще не означает, что MX2000 не прав.
Насчет «копаться в исходниках PHP» — а как еще вы предлагаете в корне доказывать или опровергать какие-либо заявления? Исходники PHP открыты и можно легко найти и показать истинную логику работы в спорной ситуации.
[quote comment="486"][quote comment="430"]Т.е. по-вашему всем выводом данных переменных через echo/print занимается Zend Engine 2?[/quote]
А вы, извините, думали чем занимается ZE2? ZE2 делает полную обработку исходного кода на языке PHP, строит дерево и производит его выполнение.
И как раз разбор строк в разных кавычках входит в процесс парсинга и построения дерева.
[quote comment="438"][quote comment="435"]Вы хотите сказать, что CVS-репозиторий PHP для Вас не является достоверным источником?
[/quote]Нет, я не вижу ни одного доказательства, что приведенный Вами кусок кода используется при реализации echo. По мне так просто приведен список вызовов функций, которые тоже не сильно понятно что именно делают, так как надо искать их тело...
Копаться в исходниках PHP это конечно хорошо, но оно того не стоит по-моему...[/quote]
Посмотрете внимательней, и вы заметите выделенные красным цветом фрагменты. Это именно те места, в которых происходит дополнительный разбор строки в двойных кавычках. Ваша неграмотность относительно построения парсеров еще не означает, что MX2000 не прав.
Насчет «копаться в исходниках PHP» — а как еще вы предлагаете в корне доказывать или опровергать какие-либо заявления? Исходники PHP открыты и можно легко найти и показать истинную логику работы в спорной ситуации.[/quote]
Верите или нет, но у меня просто нет лишнего свободного времени и желания, чтобы пытаться понять прав он или не прав путем попыток воткнуть в смысл немаленьких объемов кода...
Насчет моей фразы о ZE2 — логика была проста: он стал частью ядра только совсем несколько лет назад, а PHP существовал и раньше и функции там эти были. Не знаю что с тех пор изменилось в их работе, но я всегда считал, что ZE используется для управления памятью и расширяемости языка, хотя возможно этим список банально не заканчивается.