Pular para o conteúdo principal

Compilando PHP

O processo de compilação está em um Dockerfile. Ele foi originalmente derivado de seanmorris/php-wasm.

Em linhas gerais, esse Dockerfile:

  • Instala todos os pacotes Linux necessários (como build-essential).
  • Baixa o PHP e as bibliotecas necessárias, como sqlite3.
  • Aplica algumas correções.
  • Compila tudo usando Emscripten, um substituto direto para o compilador C.
  • Compila php_wasm.c – uma API conveniente para JavaScript.
  • Gera um arquivo php.wasm e um ou mais carregadores JavaScript, dependendo da configuração.
  • Transforma a saída padrão php.js do Emscripten em um módulo ESM com recursos adicionais.

Para saber mais sobre cada etapa, consulte diretamente o Dockerfile.

Compilação​

Com o Docker em execução e as dependências do repositório instaladas, execute estes comandos na raiz do repositório:

# Compila todas as versões suportadas do PHP para a web, nos modos JSPI e Asyncify.
npx nx recompile-php:all php-wasm-web

# Compila apenas o PHP 8.4 para a web, no modo JSPI.
npx nx recompile-php:jspi php-wasm-web -- --PHP_VERSION=8.4

Substitua php-wasm-web por php-wasm-node para compilar para Node.js, ou recompile-php:jspi por recompile-php:asyncify para compilar a variante Asyncify. A saída é gravada em packages/php-wasm/web-builds/<major>-<minor>/<mode>/ ou packages/php-wasm/node-builds/<major>-<minor>/<mode>/.

Compilações para depuração​

Use --WITH_DEBUG=yes para compilar PHP.wasm com saída JavaScript legível e informações de depuração DWARF para executar o código C passo a passo em um depurador WebAssembly:

# Compila o PHP 8.4 para depuração no navegador.
npx nx recompile-php:jspi php-wasm-web -- --PHP_VERSION=8.4 --WITH_DEBUG=yes

# Compila o PHP 8.4 para depuração no Node.js.
npx nx recompile-php:jspi php-wasm-node -- --PHP_VERSION=8.4 --WITH_DEBUG=yes

A mesma opção funciona com recompile-php:asyncify. As compilações para depuração geram arquivos maiores e são mais lentas que as compilações otimizadas. Elas substituem os artefatos da versão selecionada no diretório de saída descrito acima. Compile novamente com --WITH_DEBUG=no --WITH_SOURCEMAPS=no para restaurar uma compilação otimizada.

Para gerar mapas de código-fonte WebAssembly, use --WITH_SOURCEMAPS=yes:

npx nx recompile-php:jspi php-wasm-web -- --PHP_VERSION=8.4 --WITH_SOURCEMAPS=yes

Isso gera um arquivo php.wasm.map e copia os arquivos de código-fonte necessários para depuração para o diretório de saída da compilação. Nas compilações para a web, o URL do mapa de código-fonte aponta para o servidor de desenvolvimento local em http://127.0.0.1:5400; execute npm run dev para disponibilizá-lo.

Opções do Emscripten​

O script de compilação converte essas opções em sinalizadores do compilador no Dockerfile do PHP:

SinalizadorFinalidadeQuando o Playground o usa
-O0Desativa a otimização da saída final de WebAssembly e JavaScript.WITH_DEBUG=yes ou WITH_SOURCEMAPS=yes, substituindo o padrão -O3.
-g2Mantém os nomes das funções e o JavaScript legível, sem reter informações DWARF no módulo final.Compilações para Node.js quando nenhuma das opções de depuração está ativada.
-g3Mantém informações DWARF para depuração no nível do código-fonte.WITH_DEBUG=yes ou WITH_SOURCEMAPS=yes.
-gsource-mapGera um mapa de código-fonte WebAssembly a partir das informações de depuração do compilador.WITH_SOURCEMAPS=yes.

Consulte a referência do compilador Emscripten para saber mais sobre esses sinalizadores.

Asserções em tempo de execução​

As informações de depuração e as asserções em tempo de execução são configurações separadas. O Playground passa explicitamente -s ASSERTIONS=0, inclusive nas compilações para depuração, portanto --WITH_DEBUG=yes não ativa verificações adicionais em tempo de execução.

Para investigar uma falha em tempo de execução com asserções, altere essa configuração no comando emcc final do Dockerfile do PHP e compile novamente. O Emscripten documenta -s ASSERTIONS=1 para verificações em tempo de execução e -s ASSERTIONS=2 para verificações adicionais, mais lentas. Não existe uma opção de compilação WITH_ASSERTIONS. Consulte a referência de asserções do Emscripten.

Compilações do PHP next​

O Playground também pode executar a próxima versão do PHP a partir do branch de desenvolvimento do php-src no ambiente web. Essas compilações são publicadas separadamente do repositório principal porque os arquivos WebAssembly gerados são grandes e mudam com frequência.

O fluxo de atualização noturno compila o branch de desenvolvimento do php-src, grava os artefatos para a web no diretório packages/playground/website/public/php-next/, ignorado pelo Git, e publica o resultado no branch php-next-builds. As implantações do site e o servidor de desenvolvimento local sincronizam esse branch antes de servir ?php=next.

Para atualizar a cópia local manualmente, execute:

npm run sync:php-next

Para recompilar localmente os artefatos para a web a partir do branch de desenvolvimento do php-src, execute:

npm run recompile:php:web:next

Atualmente, php=next distribui apenas módulos principais para a web. Os módulos auxiliares de extensões correspondentes e o suporte à CLI do Playground serão tratados em trabalhos separados.

Extensões PHP​

O PHP é compilado com várias extensões listadas no Dockerfile.

Algumas extensões, como zip, podem ser ativadas ou desativadas durante a compilação. Outras, como sqlite3, são definidas diretamente no código.

Se você precisa desativar uma das extensões definidas diretamente no código, fique à vontade para abrir uma issue neste repositório. Melhor ainda: este projeto precisa de colaboradores. Você pode abrir um PR e implementar a alteração de que precisa.

PHP.wasm também pode carregar extensões dinâmicas .so antes de iniciar o PHP. Extensões dinâmicas integradas, como intl, xdebug, redis e memcached, são distribuídas com o pacote Node, e extensões externas podem ser fornecidas com um manifesto que seleciona o artefato correspondente à versão do PHP e ao modo assíncrono ativos. Consulte Carregando extensões PHP para conhecer a API de execução.

API C exposta ao JavaScript​

A API C exposta ao JavaScript está no arquivo php_wasm.c. As funções mais importantes são:

  • void phpwasm_init() – Cria um novo contexto PHP e deve ser chamada antes de executar qualquer código PHP.
  • int phpwasm_run(char *code) – Executa um script PHP e grava a saída em /tmp/stdout e /tmp/stderr. Retorna o código de saída.
  • void phpwasm_refresh() – Destrói o contexto PHP atual e inicia um novo. Chame-a após executar um script PHP e antes de executar outro.

Consulte a documentação no código de php_wasm.c para saber mais.

Configuração da compilação​

A compilação é configurável pelo recurso --build-arg do Docker. Você pode definir as opções pelo script build.js; execute este comando para ver as instruções de uso:

npx nx recompile-php:jspi php-wasm-web -- --help

Opções de compilação selecionadas:

Esta lista destaca as configurações de depuração e compilação básicas. Para consultar todas as opções, execute o comando de ajuda acima; consulte o script de compilação para ver os valores padrão de cada plataforma.

  • WITH_DEBUG – yes ou no. Compila com informações de depuração DWARF e desativa a otimização final. Consulte Compilações para depuração.
  • WITH_SOURCEMAPS – yes ou no. Gera mapas de código-fonte WebAssembly e desativa a otimização final. Consulte Compilações para depuração.
  • PHP_VERSION – A versão do PHP a compilar. Use uma versão principal/secundária como 8.4 para selecionar sua versão mais recente na lista de versões do PHP compatíveis, ou uma versão exata como 8.4.25. A compilação clona a tag php-<version> correspondente do php-src.
  • WITH_LIBXML – yes ou no, padrão: yes. Define se a compilação inclui libxml2 e as extensões PHP dom, xml e simplexml (DOMDocument, SimpleXML, ...).
  • WITH_LIBZIP – yes ou no, padrão: yes. Define se a compilação inclui zlib, libzip e a extensão PHP zip (ZipArchive).