Écrire une extension PHP de base en C
Créez et chargez votre propre extension native.
Écrire une extension PHP de base en C est une leçon PHP Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage PHP Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours PHP Academy comprend 4 leçons au total.
Code natif en PHP
Lorsque le PHP pur est trop lent ou que vous devez lier une bibliothèque C, vous écrivez une extension PHP en C à l'aide de l'API Zend. L'extension expose des fonctions et des classes natives que PHP appelle directement, sans le coût de la VM.
Cette leçon construit une extension hello minimale de bout en bout : squelette, fonction, compilation, chargement et test.
La chaîne d’outils de compilation
Les extensions sont compilées avec phpize, qui prépare une compilation autoconf à l’aide des en-têtes de votre installation PHP. Vous avez besoin de php-dev/php-devel (qui fournit phpize et php-config), ainsi que d’un compilateur C et de make.
# Install build prerequisites (Debian/Ubuntu)
sudo apt install php-dev build-essential
# Confirm the tools exist
phpize --version
php-config --extension-dir # where the .so will be installedconfig.m4
Chaque extension a besoin d’un fichier config.m4 qui enregistre une option de compilation et déclare les fichiers sources. phpize l’utilise pour générer le script de configuration.
dnl config.m4 for the 'hello' extension
PHP_ARG_ENABLE([hello],
[whether to enable hello support],
[AS_HELP_STRING([--enable-hello], [Enable hello])],
[no])
if test "$PHP_HELLO" != "no"; then
PHP_NEW_EXTENSION(hello, hello.c, $ext_shared)
fiEn-têtes de l’extension
Le code source C inclut les en-têtes de Zend/PHP et déclare le point d’entrée du module. php.h inclut l’API principale ; ext/standard/info.h sert à produire la sortie de phpinfo(). Chaque extension définit un zend_module_entry.
/* hello.c — includes */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "ext/standard/info.h"
#include "hello_arginfo.h" /* generated from stub */Squelettes des informations d’arguments
Les versions modernes de PHP génèrent les métadonnées des arguments à partir d’un fichier .stub.php. Vous écrivez la signature de la fonction dans une syntaxe proche de PHP ; gen_stub.php produit hello_arginfo.h. Cela garantit l’exactitude de la réflexion et des informations de type.
<?php
// hello.stub.php — describes the native function's signature
/** @generate-class-entries */
function hello_greet(string $name): string {}
?>Implémentation de la fonction
Une fonction native est une fonction C marquée avec PHP_FUNCTION. Vous analysez les arguments reçus avec les macros ZEND_PARSE_PARAMETERS et renvoyez les valeurs au moyen des macros RETURN_*. Ici, nous construisons une chaîne de salutation.
/* hello.c — the native function */
PHP_FUNCTION(hello_greet)
{
char *name;
size_t name_len;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STRING(name, name_len)
ZEND_PARSE_PARAMETERS_END();
/* Build "Hello, <name>!" into a new zend_string */
zend_string *result = strpprintf(0, "Hello, %s!", name);
RETURN_STR(result); /* hands ownership to the engine */
}Point d’entrée du module
Le zend_module_entry relie tous les éléments : le nom, la version, la table des fonctions (issue des informations d’arguments) et les fonctions du cycle de vie (MINIT, RINIT, MINFO). ZEND_GET_MODULE exporte le symbole d’entrée recherché par le chargeur.
/* hello.c — module wiring */
zend_module_entry hello_module_entry = {
STANDARD_MODULE_HEADER,
"hello", /* extension name */
ext_functions, /* function table from arginfo */
NULL, /* MINIT (module startup) */
NULL, /* MSHUTDOWN */
NULL, /* RINIT (per-request) */
NULL, /* RSHUTDOWN */
PHP_MINFO(hello), /* phpinfo section */
"0.1.0",
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_HELLO
ZEND_GET_MODULE(hello)
#endifMémoire : emalloc ou malloc
Dans une extension, allouez la mémoire dont la durée de vie est limitée à la requête avec emalloc/efree (suivie par le gestionnaire de mémoire Zend et libérée à la fin de la requête), et non avec malloc. Pour les allocations persistantes (entre les requêtes), utilisez pemalloc. Le renvoi d’une chaîne zend_string via RETURN_STR cède sa propriété au moteur, qui la libère.
/* Request-scoped buffer the engine will clean up on error/shutdown */
char *buf = emalloc(64);
/* ... use buf ... */
efree(buf);
/* Persistent allocation surviving the request (rare) */
/* char *cfg = pemalloc(128, 1); ... pefree(cfg, 1); */Compilation
La compilation classique en trois étapes : phpize pour créer la structure initiale, ./configure avec votre option d’activation, puis make. Pensez à exécuter d’abord gen_stub.php pour produire l’en-tête des informations d’arguments.
# Generate arginfo from the stub
php /path/to/php-src/build/gen_stub.php hello.stub.php
# Scaffold + configure + compile
phpize
./configure --enable-hello
make
# Result lands in modules/hello.so
ls -la modules/hello.soChargement et tests
Chargez le fichier compilé .so avec -d extension=... (ou ajoutez-le à un fichier ini). Appelez ensuite la fonction native depuis PHP exactement comme une fonction intégrée. Voici à quoi ressemble votre script de test et de vérification une fois l’extension installée.
<?php
// After: php -d extension=./modules/hello.so test.php
if (!extension_loaded('hello')) {
fwrite(STDERR, "hello extension not loaded\n");
exit(1);
}
echo hello_greet('Zend') . PHP_EOL; // Hello, Zend!
var_dump(extension_loaded('hello')); // bool(true)
?>Quand (ne pas) en créer une
Les extensions natives impliquent des coûts de maintenance : bugs de mémoire en C, recompilations pour chaque version mineure de PHP et ruptures de l’ABI. Avant de passer au natif, envisagez FFI (appeler des bibliothèques C depuis PHP sans compiler d’extension) ou une optimisation en PHP pur. Choisissez une extension C lorsque vous avez besoin d’une vitesse maximale, d’une intégration étroite au moteur ou d’encapsuler proprement une bibliothèque C complexe.
<?php
// FFI alternative: call a C library directly, no extension build
$ffi = FFI::cdef(
"int abs(int);", // declare the symbol
"libc.so.6"
);
echo $ffi->abs(-42) . PHP_EOL; // 42
?>Vérification rapide
Dans une extension, quel allocateur doit gérer la mémoire dont la durée de vie est limitée à la requête ?
Récapitulatif
Vous avez créé une extension C minimale : config.m4 enregistre la compilation, un fichier .stub.php génère les informations d’arguments, PHP_FUNCTION implémente la logique en analysant les arguments avec ZEND_PARSE_PARAMETERS et en renvoyant une valeur via RETURN_STR, tandis qu’un zend_module_entry relie les fonctions du cycle de vie. Compilez avec phpize → configure → make, chargez le fichier .so et effectuez des tests depuis PHP. Utilisez emalloc pour la mémoire de requête — et envisagez FFI avant de vous engager dans du code natif.
Questions Fréquemment Posées
La leçon « Écrire une extension PHP de base en C » est-elle gratuite ?
Oui — le texte complet de « Écrire une extension PHP de base en C » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours PHP Academy, passe à CoddyKit PRO. Le cours PHP Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Écrire une extension PHP de base en C » ?
Créez et chargez votre propre extension native. Tu pratiques PHP Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer PHP Academy ?
Aucune expérience préalable n'est requise. PHP Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Écrire une extension PHP de base en C » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon PHP Academy ?
Oui. Chaque leçon PHP Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Fonctionnement du moteur Zend
- Gestion de la mémoire et récupération des déchets
- OPcache et compilation JIT
- Écrire une extension PHP de base en C