Compilar PHP
El proceso de compilación se encuentra en un Dockerfile. Originalmente se derivó de seanmorris/php-wasm.
A grandes rasgos, ese Dockerfile:
- Instala todos los paquetes de Linux necesarios (como
build-essential). - Descarga PHP y las bibliotecas necesarias, como
sqlite3. - Aplica algunos parches.
- Compila todo con Emscripten, un sustituto directo del compilador de C.
- Compila
php_wasm.c, una API práctica para JavaScript. - Genera un archivo
php.wasmy uno o varios cargadores JavaScript, según la configuración. - Transforma la salida predeterminada
php.jsde Emscripten en un módulo ESM con funciones adicionales.
Para obtener más información sobre cada paso, consulta directamente el Dockerfile.
Compilación
Con Docker en ejecución y las dependencias del repositorio instaladas, ejecuta estos comandos desde la raíz del repositorio:
# Compila todas las versiones compatibles de PHP para la web, en los modos JSPI y Asyncify.
npx nx recompile-php:all php-wasm-web
# Compila solo PHP 8.4 para la web, en modo JSPI.
npx nx recompile-php:jspi php-wasm-web -- --PHP_VERSION=8.4
Sustituye php-wasm-web por php-wasm-node para compilar para Node.js, o recompile-php:jspi por recompile-php:asyncify para compilar la variante Asyncify. Los archivos se generan en packages/php-wasm/web-builds/<major>-<minor>/<mode>/ o packages/php-wasm/node-builds/<major>-<minor>/<mode>/.
Compilaciones para depuración
Usa --WITH_DEBUG=yes para compilar PHP.wasm con una salida JavaScript legible e información de depuración DWARF que permita recorrer el código C paso a paso en un depurador WebAssembly:
# Compila PHP 8.4 para depurarlo en el navegador.
npx nx recompile-php:jspi php-wasm-web -- --PHP_VERSION=8.4 --WITH_DEBUG=yes
# Compila PHP 8.4 para depurarlo en Node.js.
npx nx recompile-php:jspi php-wasm-node -- --PHP_VERSION=8.4 --WITH_DEBUG=yes
La misma opción funciona con recompile-php:asyncify. Las compilaciones para depuración generan archivos más grandes y se ejecutan más lentamente que las compilaciones optimizadas. Sustituyen los artefactos de la versión seleccionada en el directorio de salida descrito anteriormente. Vuelve a compilar con --WITH_DEBUG=no --WITH_SOURCEMAPS=no para restaurar una compilación optimizada.
Para generar mapas de código fuente de WebAssembly, usa --WITH_SOURCEMAPS=yes:
npx nx recompile-php:jspi php-wasm-web -- --PHP_VERSION=8.4 --WITH_SOURCEMAPS=yes
Esto genera un archivo php.wasm.map y copia los archivos de código fuente necesarios para la depuración en el directorio de salida de la compilación. En las compilaciones para la web, la URL del mapa de código fuente apunta al servidor de desarrollo local en http://127.0.0.1:5400; ejecuta npm run dev para servirlo.
Opciones de Emscripten
El script de compilación convierte estas opciones en indicadores del compilador en el Dockerfile de PHP:
| Indicador | Finalidad | Cuándo lo usa Playground |
|---|---|---|
-O0 | Desactiva la optimización de la salida final de WebAssembly y JavaScript. | WITH_DEBUG=yes o WITH_SOURCEMAPS=yes, en lugar del valor predeterminado -O3. |
-g2 | Conserva los nombres de las funciones y el JavaScript legible, sin retener información DWARF en el módulo final. | Compilaciones para Node.js cuando ninguna de las opciones de depuración está activada. |
-g3 | Conserva la información DWARF para depurar a nivel de código fuente. | WITH_DEBUG=yes o WITH_SOURCEMAPS=yes. |
-gsource-map | Genera un mapa de código fuente de WebAssembly a partir de la información de depuración del compilador. | WITH_SOURCEMAPS=yes. |
Consulta la referencia del compilador Emscripten para obtener más información sobre estos indicadores.
Aserciones en tiempo de ejecución
La información de depuración y las aserciones en tiempo de ejecución son ajustes independientes. Playground pasa explícitamente -s ASSERTIONS=0, incluso en las compilaciones para depuración, por lo que --WITH_DEBUG=yes no activa comprobaciones adicionales en tiempo de ejecución.
Para investigar un fallo en tiempo de ejecución con aserciones, cambia ese ajuste en el comando emcc final del Dockerfile de PHP y vuelve a compilar. Emscripten documenta -s ASSERTIONS=1 para comprobaciones en tiempo de ejecución y -s ASSERTIONS=2 para comprobaciones adicionales, más lentas. No existe una opción de compilación WITH_ASSERTIONS. Consulta la referencia de aserciones de Emscripten.
Compilaciones de PHP next
Playground también puede ejecutar la próxima versión de PHP desde la rama de desarrollo de php-src en el entorno web. Estas compilaciones se publican por separado del repositorio principal porque los archivos WebAssembly generados son grandes y cambian con frecuencia.
El flujo de actualización nocturno compila la rama de desarrollo de php-src, escribe los artefactos para la web en el directorio packages/playground/website/public/php-next/, ignorado por Git, y publica el resultado en la rama php-next-builds. Los despliegues del sitio web y el servidor de desarrollo local sincronizan esa rama antes de servir ?php=next.
Para actualizar la copia local manualmente, ejecuta:
npm run sync:php-next
Para recompilar localmente los artefactos para la web desde la rama de desarrollo de php-src, ejecuta:
npm run recompile:php:web:next
Actualmente, php=next solo distribuye módulos principales para la web. Los módulos auxiliares de extensiones correspondientes y la compatibilidad con la CLI de Playground se abordarán en trabajos posteriores independientes.
Extensiones de PHP
PHP se compila con varias extensiones que se enumeran en el Dockerfile.
Algunas extensiones, como zip, pueden activarse o desactivarse durante la compilación. Otras, como sqlite3, están definidas directamente en el código.
Si necesitas desactivar una de las extensiones definidas directamente en el código, puedes abrir una incidencia en este repositorio. Mejor aún: este proyecto necesita colaboradores. Puedes abrir una PR e implementar el cambio que necesitas.
PHP.wasm también puede cargar extensiones dinámicas .so antes de iniciar PHP. Las extensiones dinámicas integradas, como intl, xdebug, redis y memcached, se distribuyen con el paquete de Node, y las extensiones externas pueden proporcionarse con un manifiesto que seleccione el artefacto correspondiente a la versión de PHP y al modo asíncrono activos. Consulta Cargar extensiones de PHP para conocer la API de ejecución.
API de C expuesta a JavaScript
La API de C expuesta a JavaScript se encuentra en el archivo php_wasm.c. Las funciones más importantes son:
void phpwasm_init()– Crea un nuevo contexto de PHP y debe llamarse antes de ejecutar cualquier código PHP.int phpwasm_run(char *code)– Ejecuta un script PHP y escribe la salida en /tmp/stdout y /tmp/stderr. Devuelve el código de salida.void phpwasm_refresh()– Destruye el contexto de PHP actual e inicia uno nuevo. Llámala después de ejecutar un script PHP y antes de ejecutar otro.
Consulta la documentación incluida en php_wasm.c para obtener más información.
Configuración de la compilación
La compilación se puede configurar mediante la opción --build-arg de Docker. Puedes definir los ajustes mediante el script build.js; ejecuta este comando para ver las instrucciones de uso:
npx nx recompile-php:jspi php-wasm-web -- --help
Opciones de compilación seleccionadas:
Esta lista destaca los ajustes de depuración y compilación básicos. Para consultar todas las opciones, ejecuta el comando de ayuda anterior; consulta el script de compilación para conocer los valores predeterminados de cada plataforma.
WITH_DEBUG–yesono. Compila con información de depuración DWARF y desactiva la optimización final. Consulta Compilaciones para depuración.WITH_SOURCEMAPS–yesono. Genera mapas de código fuente de WebAssembly y desactiva la optimización final. Consulta Compilaciones para depuración.PHP_VERSION– La versión de PHP que se compilará. Usa una versión mayor/menor como8.4para seleccionar su última versión de las versiones de PHP compatibles, o una versión exacta como8.4.25. La compilación clona la etiquetaphp-<version>correspondiente de php-src.WITH_LIBXML–yesono, predeterminado:yes. Indica si se incluyelibxml2y las extensiones de PHPdom,xmlysimplexml(DOMDocument,SimpleXML, ...).WITH_LIBZIP–yesono, predeterminado:yes. Indica si se incluyezlib,libzipy la extensión de PHPzip(ZipArchive).