Aller au contenu principal

Compiler PHP

Le processus de compilation se trouve dans un Dockerfile. Il est issu à l’origine d’un fork de seanmorris/php-wasm.

Dans les grandes lignes, ce Dockerfile :

  • Installe tous les paquets Linux nécessaires (comme build-essential).
  • Télécharge PHP et les bibliothèques nécessaires, par exemple sqlite3.
  • Applique quelques correctifs.
  • Compile le tout avec Emscripten, un remplacement direct du compilateur C.
  • Compile php_wasm.c, une API pratique pour JavaScript.
  • Génère un fichier php.wasm et un ou plusieurs chargeurs JavaScript, selon la configuration.
  • Transforme la sortie par défaut php.js d’Emscripten en un module ESM doté de fonctionnalités supplémentaires.

Pour en savoir plus sur chaque étape, consultez directement le Dockerfile.

Compilation​

Une fois Docker lancé et les dépendances du dépôt installées, exécutez ces commandes à la racine du dépôt :

# Compile toutes les versions PHP prises en charge pour le web, aux modes JSPI et Asyncify.
npx nx recompile-php:all php-wasm-web

# Compile uniquement PHP 8.4 pour le web, au mode JSPI.
npx nx recompile-php:jspi php-wasm-web -- --PHP_VERSION=8.4

Remplacez php-wasm-web par php-wasm-node pour compiler pour Node.js, ou recompile-php:jspi par recompile-php:asyncify pour compiler la variante Asyncify. Les fichiers sont générés dans packages/php-wasm/web-builds/<major>-<minor>/<mode>/ ou packages/php-wasm/node-builds/<major>-<minor>/<mode>/.

Compilations de débogage​

Utilisez --WITH_DEBUG=yes pour compiler PHP.wasm avec une sortie JavaScript lisible et des informations de débogage DWARF permettant de parcourir le code C pas à pas dans un débogueur WebAssembly :

# Compile PHP 8.4 pour le débogage dans le navigateur.
npx nx recompile-php:jspi php-wasm-web -- --PHP_VERSION=8.4 --WITH_DEBUG=yes

# Compile PHP 8.4 pour le débogage dans Node.js.
npx nx recompile-php:jspi php-wasm-node -- --PHP_VERSION=8.4 --WITH_DEBUG=yes

La même option fonctionne avec recompile-php:asyncify. Les compilations de débogage génèrent des fichiers plus volumineux et s’exécutent plus lentement que les compilations optimisées. Elles remplacent les artefacts de la version sélectionnée dans le répertoire de sortie décrit ci-dessus. Recompilez avec --WITH_DEBUG=no --WITH_SOURCEMAPS=no pour rétablir une compilation optimisée.

Pour générer des cartes de sources WebAssembly, utilisez --WITH_SOURCEMAPS=yes :

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

Cette option génère un fichier php.wasm.map et copie les fichiers sources nécessaires au débogage dans le répertoire de sortie de la compilation. Pour les compilations web, l’URL de la carte de sources pointe vers le serveur de développement local à l’adresse http://127.0.0.1:5400 ; exécutez npm run dev pour la rendre accessible.

Options d’Emscripten​

Le script de compilation traduit ces options en paramètres du compilateur dans le Dockerfile de PHP :

ParamètreRôleQuand Playground l’utilise
-O0Désactive l’optimisation de la sortie finale WebAssembly et JavaScript.WITH_DEBUG=yes ou WITH_SOURCEMAPS=yes, à la place de la valeur par défaut -O3.
-g2Conserve les noms des fonctions et un JavaScript lisible, sans conserver les informations DWARF dans le module final.Compilations pour Node.js lorsque ni l’une ni l’autre des options de débogage n’est activée.
-g3Conserve les informations DWARF pour le débogage au niveau du code source.WITH_DEBUG=yes ou WITH_SOURCEMAPS=yes.
-gsource-mapGénère une carte de sources WebAssembly à partir des informations de débogage du compilateur.WITH_SOURCEMAPS=yes.

Consultez la référence du compilateur Emscripten pour en savoir plus sur ces paramètres.

Assertions à l’exécution​

Les informations de débogage et les assertions à l’exécution sont des réglages distincts. Playground passe explicitement -s ASSERTIONS=0, y compris dans les compilations de débogage. L’option --WITH_DEBUG=yes n’active donc pas de vérifications supplémentaires à l’exécution.

Pour analyser une erreur à l’exécution avec des assertions, modifiez ce réglage dans la commande emcc finale du Dockerfile de PHP et recompilez. Emscripten documente -s ASSERTIONS=1 pour les vérifications à l’exécution et -s ASSERTIONS=2 pour des vérifications supplémentaires, plus lentes. Il n’existe pas d’option de compilation WITH_ASSERTIONS. Consultez la référence des assertions d’Emscripten.

Compilations de PHP next​

Playground peut aussi exécuter la prochaine version de PHP depuis la branche de développement de php-src dans l’environnement web. Ces compilations sont publiées séparément du dépôt principal, car les fichiers WebAssembly générés sont volumineux et changent souvent.

Le workflow de mise à jour nocturne compile la branche de développement de php-src, écrit les artefacts web dans le répertoire packages/playground/website/public/php-next/, ignoré par Git, et publie le résultat dans la branche php-next-builds. Les déploiements du site et le serveur de développement local synchronisent cette branche avant de servir ?php=next.

Pour actualiser manuellement la copie locale, exécutez :

npm run sync:php-next

Pour recompiler localement les artefacts web depuis la branche de développement de php-src, exécutez :

npm run recompile:php:web:next

Actuellement, php=next ne distribue que des modules principaux pour le web. Les modules secondaires des extensions correspondantes et la prise en charge de la CLI de Playground feront l’objet de travaux ultérieurs distincts.

Extensions PHP​

PHP est compilé avec plusieurs extensions répertoriées dans le Dockerfile.

Certaines extensions, comme zip, peuvent être activées ou désactivées lors de la compilation. D’autres, comme sqlite3, sont définies directement dans le code.

Si vous devez désactiver une extension définie directement dans le code, vous pouvez ouvrir un ticket dans ce dépôt. Mieux encore : ce projet a besoin de contributions. Vous pouvez ouvrir une PR et implémenter la modification dont vous avez besoin.

PHP.wasm peut aussi charger des extensions dynamiques .so avant le démarrage de PHP. Les extensions dynamiques intégrées, comme intl, xdebug, redis et memcached, sont distribuées avec le paquet Node. Les extensions externes peuvent être fournies avec un manifeste qui sélectionne l’artefact correspondant à la version de PHP et au mode asynchrone actifs. Consultez Charger des extensions PHP pour découvrir l’API d’exécution.

API C exposée à JavaScript​

L’API C exposée à JavaScript se trouve dans le fichier php_wasm.c. Les fonctions les plus importantes sont :

  • void phpwasm_init() – Crée un nouveau contexte PHP et doit être appelée avant d’exécuter du code PHP.
  • int phpwasm_run(char *code) – Exécute un script PHP et écrit la sortie dans /tmp/stdout et /tmp/stderr. Renvoie le code de sortie.
  • void phpwasm_refresh() – Détruit le contexte PHP actuel et en démarre un nouveau. Appelez-la après l’exécution d’un script PHP et avant d’en exécuter un autre.

Consultez la documentation dans le code de php_wasm.c pour en savoir plus.

Configuration de la compilation​

La compilation est configurable avec la fonctionnalité --build-arg de Docker. Vous pouvez définir les options avec le script build.js ; exécutez cette commande pour afficher les instructions d’utilisation :

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

Sélection d’options de compilation :

Cette liste présente les réglages de débogage et de compilation de base. Pour consulter toutes les options, exécutez la commande d’aide ci-dessus ; consultez le script de compilation pour les valeurs par défaut propres à chaque plateforme.

  • WITH_DEBUG – yes ou no. Compile avec les informations de débogage DWARF et désactive l’optimisation finale. Consultez Compilations de débogage.
  • WITH_SOURCEMAPS – yes ou no. Génère des cartes de sources WebAssembly et désactive l’optimisation finale. Consultez Compilations de débogage.
  • PHP_VERSION – La version de PHP à compiler. Utilisez une version majeure/mineure comme 8.4 pour sélectionner sa dernière version dans les versions de PHP prises en charge, ou une version exacte comme 8.4.25. La compilation clone le tag php-<version> correspondant de php-src.
  • WITH_LIBXML – yes ou no, par défaut : yes. Indique s’il faut compiler avec libxml2 et les extensions PHP dom, xml et simplexml (DOMDocument, SimpleXML, ...).
  • WITH_LIBZIP – yes ou no, par défaut : yes. Indique s’il faut compiler avec zlib, libzip et l’extension PHP zip (ZipArchive).