Для чего __halt_compiler в PHP?
Из manual:
void __halt_compiler ( void )
Эта функция останавливает выполнение компилятора. Это может быть полезно для встраивания данных в PHP-скрипты, например, в файлы установки.
Примечание: __halt_compiler()
может использоваться только из внешнего пространства.
Может ли кто-нибудь предоставить фактический случай, когда эта функция полезна?
Ответы
Ответ 1
Предположим, что у вас есть один script с некоторым кодом php и множеством бинарных помех.
<?php doStuff(); __halt_compliler(); [BIG_BINARY_MESS]
тогда вы хотите, чтобы компилятор НЕ пытался анализировать двоичный файл, потому что если есть <?
где-то в двоичном файле, он сломается.
Точка не может просто отправить один файл с двоичными данными и php-кодом.
Для небольшого примера см. этот пост в блоге
Таким образом, вы хотите не только остановить execution
script (например, exit()
), но и остановить parsing
, чтобы вы могли иметь "недопустимый синтаксис" в конце файла и php еще может выполнить первую часть.
Другой пример:
Это будет обработано как действительный php и будет выполняться просто отлично:
<?php $a = 1; echo $a; __halt_compiler(); §RW$FG$%ZDS$TSG$TSZ%U(); §$"§%"§$!!();
Чтобы получить доступ к данным:
<?php
$file = fopen(__FILE__, 'rb');
// Go to the end of the __halt_compiler();
fseek($file, __COMPILER_HALT_OFFSET__);
echo stream_get_contents($file);
__halt_compiler(); §RW$FG$%ZDS$TSG$TSZ%U(); §$"§%"§$!!();
Это приведет к выходу §RW$FG$%ZDS$TSG$TSZ%U(); §$"§%"§$!!();
Ответ 2
Ранее ClassGenerator в библиотеке модульных тестов PhpSpec послужил хорошим примером использования __halt_compiler()
, который PHP-класс содержит шаблон кода для PHP-класса.
Они недавно обновили, чтобы прочитать шаблон из отдельного файла, но сначала метод getTemplate()
попытается прочитать шаблон кода PHP, указанный в файле, который следует за вызовом __halt_compiler()
. Это позволяет избежать токена <?php
при анализе.
/**
* The Class Generator is responsible for generating the classes from a resource
* in the appropriate folder using the template provided
*/
class ClassGenerator
{
//...
/**
* @return string
*/
protected function getTemplate()
{
return file_get_contents(__FILE__, null, null, __COMPILER_HALT_OFFSET__);
}
}
__halt_compiler();<?php%namespace_block%
class %name%
{
}
Ответ 3
Здесь другое возможное использование. У меня есть длинный файл функций PHP. Многие из них в настоящее время не действительны, но могут потребоваться в ближайшее время. Я хочу отключить их, но не полностью удалить их. Я хочу, чтобы код оставался видимым для всех разработчиков, чтобы они могли восстановить код, если он ему нужен. Также любой, кто ищет через grep, все равно найдет код.
Поэтому я перемещаю код в конец файла и хочу "прокомментировать его". Однако сами функции имеют комментарии. Поэтому мне нужно будет начать новый комментарий блока после окончания каждого комментария блока в исходном коде. __HALT_COMPILER(); выполняет работу без изменения других строк.
(Если я удалю код и зафиксирую его в системе управления версиями, это позволит мне восстановить код, но он не будет виден другим разработчикам, если они не будут выглядеть новыми.)