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.wasme um ou mais carregadores JavaScript, dependendo da configuração. - Transforma a saída padrão
php.jsdo 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:
| Sinalizador | Finalidade | Quando o Playground o usa |
|---|---|---|
-O0 | Desativa a otimização da saída final de WebAssembly e JavaScript. | WITH_DEBUG=yes ou WITH_SOURCEMAPS=yes, substituindo o padrão -O3. |
-g2 | Manté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. |
-g3 | Mantém informações DWARF para depuração no nível do código-fonte. | WITH_DEBUG=yes ou WITH_SOURCEMAPS=yes. |
-gsource-map | Gera 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–yesouno. Compila com informações de depuração DWARF e desativa a otimização final. Consulte Compilações para depuração.WITH_SOURCEMAPS–yesouno. 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 como8.4para selecionar sua versão mais recente na lista de versões do PHP compatíveis, ou uma versão exata como8.4.25. A compilação clona a tagphp-<version>correspondente do php-src.WITH_LIBXML–yesouno, padrão:yes. Define se a compilação incluilibxml2e as extensões PHPdom,xmlesimplexml(DOMDocument,SimpleXML, ...).WITH_LIBZIP–yesouno, padrão:yes. Define se a compilação incluizlib,libzipe a extensão PHPzip(ZipArchive).