W3docs

__halt_compiler()

Neste artigo, focamos na construção de linguagem __halt_compiler() do PHP, seu funcionamento e exemplos práticos de uso.

Neste artigo, vamos focar na construção de linguagem __halt_compiler() do PHP. Apresentaremos uma visão geral da construção, como ela funciona e exemplos de uso.

Introdução à construção __halt_compiler()

A construção de linguagem __halt_compiler() é um recurso único e poderoso do PHP. Ela permite incorporar dados diretamente no seu código PHP. Esses dados podem ser qualquer coisa, incluindo texto, dados binários ou até mesmo um script completo.

Quando o interpretador PHP encontra a construção __halt_compiler() no seu código, ele interrompe o parser PHP e trata tudo o que vem após a chamada como dados brutos. Isso significa que você pode incorporar qualquer tipo de dado no seu código e acessá-lo posteriormente como string ou dado binário.

__halt_compiler() é uma construção de linguagem, não uma função regular, portanto você a chama sem argumentos e ela não retorna um valor. É mais frequentemente usada para criar ferramentas de arquivo único onde código e dados são distribuídos juntos — por exemplo, arquivos autoextraíveis (o formato PHAR do PHP usa exatamente essa técnica) ou instaladores que carregam seu próprio payload.

Como usar a construção __halt_compiler()

A construção __halt_compiler() é muito fácil de usar. Basta chamá-la no seu código PHP, seguida pelos dados que você deseja incorporar. Veja um exemplo:

Como usar a construção __halt_compiler()?

php— editable, runs on the server

Neste exemplo, temos um script PHP simples que imprime algum texto usando a construção echo. Em seguida, chamamos a construção __halt_compiler() e incorporamos alguns dados brutos após ela. Quando o interpretador PHP encontra a construção __halt_compiler(), ele interrompe o parser e trata tudo que vem depois como dados brutos.

Acessando os dados incorporados com __COMPILER_HALT_OFFSET__

Quando um arquivo contém __halt_compiler(), o PHP define uma constante especial, __COMPILER_HALT_OFFSET__, que guarda a posição em bytes do primeiro caractere após a chamada. Essa é a maneira canônica e mais rápida de ler o payload incorporado de dentro do mesmo arquivo — você não precisa procurar um marcador no arquivo manualmente.

Lendo dados incorporados do mesmo arquivo

<?php
// File: bundle.php
echo "Reading the embedded payload...\n";

// Open this very file and jump straight to the data.
$fp = fopen(__FILE__, 'rb');
fseek($fp, __COMPILER_HALT_OFFSET__);
$data = stream_get_contents($fp);
fclose($fp);

echo $data;

__halt_compiler();
Hello from the embedded data!

Aqui, __COMPILER_HALT_OFFSET__ aponta para o byte logo após __halt_compiler();, então buscamos essa posição e lemos tudo que segue como o payload bruto. A constante só existe em um arquivo que realmente contém a construção.

Acessando os dados incorporados de outro arquivo

Se você precisar ler o payload de um arquivo diferente, o __COMPILER_HALT_OFFSET__ desse arquivo não estará disponível para você, então localize o marcador manualmente com strpos() e extraia os dados com substr() após carregá-los via file_get_contents().

Veja um exemplo de como ler os dados incorporados a partir de um script separado:

Acessando os dados incorporados em PHP

<?php
// File: embed.php
echo "This is some PHP code.";
__halt_compiler();
This is some raw data.
?>
<?php
// File: extract.php
// Read the script file and extract the data
$content = file_get_contents('embed.php');
$pos = strpos($content, '__halt_compiler();');
if ($pos !== false) {
    $offset = $pos + strlen('__halt_compiler();');
    $data = substr($content, $offset);
    echo $data;
}
?>

Neste exemplo, primeiro criamos um arquivo com dados incorporados. Em seguida, usamos um script separado para ler o arquivo original e extrair os dados localizando o marcador __halt_compiler(); e calculando o deslocamento. Por fim, imprimimos os dados extraídos usando a construção echo.

Nota: A constante __COMPILER_HALT_OFFSET__ só é definida dentro do arquivo que realmente contém __halt_compiler(). Ao ler um arquivo diferente, strpos() retorna false se o marcador estiver ausente, por isso sempre verifique a posição com uma checagem !== false antes de calcular o deslocamento.

Restrições e considerações importantes

Tenha em mente estas regras ao usar __halt_compiler():

  • Deve ser chamada no nível superior de um arquivo. Você não pode colocá-la dentro de uma função, método, condicional, laço ou qualquer outro bloco. Fazer isso é um erro fatal.
  • Uma por arquivo. Um arquivo pode conter __halt_compiler() apenas uma vez — ela marca um único ponto de corte.
  • Tudo após ela é ignorado como código. A tag de fechamento ?> (se presente) e qualquer coisa após a chamada são tratados como bytes brutos, nunca analisados. Por isso, geralmente se omite o ?> final e os dados simplesmente seguem.
  • Não é uma função. Você não pode obter seu endereço, passá-la como callback ou chamá-la dinamicamente.

Conclusão

Em conclusão, a construção de linguagem __halt_compiler() é um recurso poderoso e flexível do PHP que permite incorporar dados diretamente no seu código. Ao entender como a construção funciona e como acessar os dados incorporados, você pode aproveitar esse recurso para criar scripts PHP mais poderosos e flexíveis. Os casos de uso práticos mais comuns incluem arquivos autoextraíveis, agrupamento de ativos estáticos (como CSS ou JavaScript) com lógica PHP e criação de aplicações PHP de arquivo único. Se você principalmente precisa importar código de outros arquivos em vez de incorporar dados brutos, consulte include.

Prática

Prática
What is the '__halt_compiler' function in PHP?
What is the '__halt_compiler' function in PHP?
Was this page helpful?