Maison > développement back-end > tutoriel php > Début avec le développement de l'extension PHP via PHP-CPP

Début avec le développement de l'extension PHP via PHP-CPP

Lisa Kudrow
Libérer: 2025-02-21 09:06:11
original
415 Les gens l'ont consulté

Début avec le développement de l'extension PHP via PHP-CPP

Dans vos relations avec PHP, vous pouvez envisager d'écrire vous-même une extension PHP. Il y a plusieurs raisons pour lesquelles je peux penser qui me motivent à le faire:

  • pour étendre les fonctionnalités PHP pour une utilisation très particulière (mathématiques, statistiques, géométrique, etc.).
  • pour avoir une performance et une efficacité plus élevées par rapport à une implémentation PHP pure
  • pour tirer parti de la rapidité obtenue de la programmation dans un autre langage précédemment saisi (pour moi, c).

Quand il s'agit de choisir un outil pour créer des extensions de PHP, nous voyons deux approches différentes:

  • Utilisez une sémantique plus pro-php, comme Zephir.
  • Utilisez plus de sémantique pro-C / C, comme PHP-CPP, qui sera abordé dans cet article.

Pour moi, le lecteur principal pour sélectionner la deuxième approche est simple: j'ai commencé mon passe-temps de programmation avec C / C, donc je me sens toujours plus à l'aise d'écrire ces modules de niveau inférieur en C / C. Le site officiel de PHP-CPP donne quelques autres raisons de le faire.

Les plats clés

  • PHP-CPP est une bibliothèque pour développer des extensions PHP qui permet aux développeurs de C d'écrire des extensions de PHP sans les complexités de travail directement avec l'API Zend. Il est écrit en C 11 et propose une collection de classes bien documentées et conviviales.
  • PHP-CPP évolue rapidement et il est recommandé d'utiliser GIT pour cloner le référentiel pour les dernières mises à jour. Il prend en charge les installations de PHP à file unique et nécessite une mise à niveau vers le compilateur G vers la version 4.8.x ou plus pour la compatibilité.
  • PHP-CPP fournit un projet d'extension squelette, qui comprend un fichier main.cpp, un fichier de fabrication de compilation l'extension et un fichier .ini pour le chargement d'extension. Le projet Skeleton peut être personnalisé en fonction des besoins individuels et compilé et installé avec la commande «Make && sudo make install».
  • PHP-CPP prend en charge quatre types de signatures de fonction à l'appel à partir de PHP et permet de passer par les paramètres par valeur sous forme de tableau. Il permet également l'exportation / l'enregistrement de la fonction, la spécification des types de paramètres de fonction et la création d'extensions orientées objet.

Installation et configuration

PHP-CPP évolue rapidement. Au moment de l'écriture de cet article, il se trouve dans la version 0.9.1 (avec 0.9.0 publié environ 2 jours auparavant). Selon sa documentation, "Ceci est une version de congélation de fonctionnalités qui se prépare pour la prochaine version V1.0", nous sommes donc convaincus que nous verrons sa version majeure 1.0 très bientôt.

Il est donc recommandé, au moins pendant cette période provisoire, d'utiliser GIT pour cloner le référentiel et d'obtenir la dernière mise à jour ultérieurement via Git Pull.

Remarque: La documentation PHP-CPP sur l'installation stipule que pour le moment, il «ne prend en charge que les installations PHP à thread unique» parce que «le moteur Zend utilise un système très étrange pour assurer la sécurité des threads». Les versions futures peuvent prendre en charge les installations PHP multi-thread, mais gardons cela à l'esprit pour l'instant et respectez sa limitation actuelle. Heureusement, les «installations de PHP monomodées» devraient être le cas pour la plupart des installations PHP.

PHP-CPP est écrit en C 11. Ainsi, l'ancienne version de G installée dans mon Ubuntu 12.04 LTS ne le prend pas en charge. Nous devons mettre à niveau notre compilateur G vers la version 4.8.x ci-dessus. Il y a un article détaillant les étapes pour effectuer la mise à niveau. Veuillez suivre les instructions répertoriées là-bas.

De plus, la compilation PHP-CPP utilisera le fichier d'en-tête PHP.H. Ce fichier est normalement manquant dans une boîte Ubuntu, à moins que PHP-DEV ne soit installé. Nous pouvons installer des fichiers de développement liés à PHP5 en émettant cette commande:

<span>sudo apt-get install php5-dev</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion

Après la mise à niveau de G et l'installation des fichiers d'en-tête nécessaires, nous pouvons émettre la commande suivante pour compiler et installer le fichier de bibliothèque PHP-CPP (libphpcpp.so):

<span>make && sudo make install</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

La compilation sera assez rapide. Après l'installation, le fichier libphpcpp.so sera copié sur / usr / lib, et tous les fichiers d'en-tête PHP-CPP seront copiés sur / usr / include et / usr / include / phpcpp les dossiers.

L'installation de PHP-CPP LIB est maintenant terminée. Il est assez simple et nous pouvons maintenant passer à la partie de programmation.

Avant de le faire, nous discuterons de quelques concepts et terminologies importants utilisés dans PHP-CPP. La documentation complète peut être trouvée sur son site officiel, et tout le monde est encouragé à le lire avant de faire une véritable programmation.

Squelette (vide) Fichiers du projet d'extension

PHP-CPP fournit un projet d'extension squelette, contenant les 3 fichiers suivants:

  • main.cpp: le fichier CPP principal contenant une fonction get_module (sera discuté plus en détail plus tard)
  • Makefile: l'échantillon de fabrication de fichiers pour compiler l'extension
  • youExtension.ini: contient une seule ligne pour le chargement d'extension

Makefile

Si vous connaissez * Nix Development, vous connaissez ce makefile. Quelques légères modifications doivent être apportées pour personnaliser ce fichier pour répondre à nos besoins:

  • Changer Nom = YouExtension en un plus significatif, comme name = squelette.
  • Modifiez ini_dir = /etc/php5/conf.d pour correspondre à la configuration de votre système. Dans mon cas, c'est INI_DIR = /etc/php5/cli/conf.d. J'ai modifié le chemin INI pour activer d'abord l'extension de l'environnement CLI de PHP.

Ce sont toutes les modifications que j'ai apportées. Le reste du makefile peut être conservé tel quel.

youExtension.ini

J'ai renommé ce fichier à squeleton.ini et modifié la seule ligne dans ce fichier comme ceci:

<span>sudo apt-get install php5-dev</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion

main.cpp

Dans le projet vide fourni par PHP-CPP, ce fichier ne contient qu'une seule fonction: get_module (), qui est extrait ci-dessous:

<span>make && sudo make install</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Pour l'instant, changeons simplement cette ligne pour correspondre au nom d'extension que nous avons l'intention de créer:

<span>extension=skeleton.so</span>
Copier après la connexion
Copier après la connexion

get_module () est appelé par PHP lorsque ce dernier essaie de charger une bibliothèque requise. Il est considéré comme le point d'entrée pour une lib. Il est déclaré en utilisant le modificateur "C" externe pour se conformer aux besoins en lib php pour la fonction get_module (). Il utilise également une macro phpcpp_export qui s'assure que get_module () est exportée publiquement, et donc appelée par php.

Jusqu'à présent, nous avons apporté quelques modifications au projet vide en fonction de nos besoins. Nous pouvons maintenant compiler et installer ce projet et installer l'extension:

<span><span>#include <phpcpp.h></span>
</span>
<span>/**
</span><span> *  tell the compiler that the get_module is a pure C function
</span><span> */
</span><span>extern "C" {
</span>
    <span>/**
</span><span>     *  Function that is called by PHP right after the PHP process
</span><span>     *  has started, and that returns an address of an internal PHP
</span><span>     *  strucure with all the details and features of your extension
</span><span>     *
</span><span>     *  @return void*   a pointer to an address that is understood by PHP
</span><span>     */
</span>    PHPCPP_EXPORT <span>void *get_module() 
</span>    <span>{
</span>        <span>// static(!) Php::Extension object that should stay in memory
</span>        <span>// for the entire duration of the process (that's why it's static)
</span>        <span>static Php::Extension extension("yourextension", "1.0");
</span>
        <span>// @todo    add your own functions, classes, namespaces to the extension
</span>
        <span>// return the extension
</span>        <span>return extension;
</span>    <span>}
</span><span>}  </span>
Copier après la connexion
Copier après la connexion

Ensuite, nous devons copier les fichiers requis dans les dossiers appropriés:

<span>static Php::Extension extension("skeleton", "1.0"); // To be humble, we can change the version number to 0.0.1</span>
Copier après la connexion
Copier après la connexion

Nous devons simplement nous assurer que le squelette.So lib est copié à la bonne emplacement des extensions de PHP (dans ma configuration d'Ubuntu, il devrait être / usr / lib / php5 / 20121212 comme indiqué ci-dessus).

Nous pouvons alors vérifier que l'extension est chargée en CLI par php -i | squelette grep, et le terminal doit afficher quelque chose comme ceci:

Début avec le développement de l'extension PHP via PHP-CPP

(Rappelez-vous que le squelette.ini est le fichier que nous avons modifié ci-dessus, qui contient la ligne d'extension = squelette.so.)

Nous avons jusqu'à présent compilé et installé notre première extension PHP à l'aide de PHP-CPP. Bien sûr, cette extension ne fait encore rien. Nous allons maintenant créer nos premières fonctions pour mieux comprendre le processus de création d'extensions de PHP.

"Hello, Taylor" Fonction

La première fonction que nous créons sera une version légèrement modifiée de "Hello, World". Voyons d'abord le code complet de main.cpp:

<span>make && sudo make install</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Selon la documentation PHP-CPP sur «Registre des fonctions natives», il prend en charge quatre types de signatures de fonction à appeler à partir de PHP:

<span>cp -f skeleton.so /usr/lib/php5/20121212
</span><span>cp -f skeleton.ini /etc/php5/cli/conf.d</span>
Copier après la connexion

Dans ce cas, j'utilise la deuxième signature et les paramètres sont passés par valeur dans un formulaire de tableau (fonctionnalité PHP).

Cependant, dans Helloworld, nous avons spécifiquement utilisé C Type C STD :: String pour saisir le premier paramètre. Nous avons également utilisé C STD LIB pour diffuser un message accueillant.

Dans la fonction get_module (), après avoir déclaré la variable d'extension, nous ajoutons la fonction que nous aimerions exporter (Helloworld ()) et attribuons un nom visible au script PHP (Helloworld).

Maintenant, compilons et installons l'extension. Si tout se passe bien, le nouveau fichier squelette.so sera copié dans le répertoire d'extension.

Nous pouvons écrire un script simple pour tester la fonction juste créée:

<span><span>#include <phpcpp.h></span>
</span><span><span>#include <iostream></span>
</span>
<span>void helloWorld (Php::Parameters &params)
</span><span>{
</span>    std<span>::string name=params[0];
</span>    std<span>::cout<<"Hello "<<name<<"!"<<std::endl;
</span>
<span>}
</span>
<span>extern "C" {
</span>
    PHPCPP_EXPORT <span>void *get_module() 
</span>    <span>{
</span>        <span>static Php::Extension extension("skeleton", "1.0");
</span>        extension<span>.add("helloWorld", helloWorld);
</span>
        <span>return extension;
</span>    <span>}
</span><span>}</span>
Copier après la connexion

Veuillez prendre le temps de regarder la sortie:

Début avec le développement de l'extension PHP via PHP-CPP

Nous reviendrons à ce que nous avons observé ici plus tard.

Paramètres de fonction par référence

Ensuite, nous verrons une autre fonction qui transmet les paramètres par référence, une fonction swap (). Dans cette fonction, nous essaierons également de spécifier le nombre de paramètres et leur type.

Dans main.cpp, nous ajoutons une autre fonction swap ():

<span>sudo apt-get install php5-dev</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion

et exportez également la fonction en spécifiant le nombre de paramètres et leur type:

<span>make && sudo make install</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Nous disons explicitement que:

  • Il y aura deux paramètres (a et b);
  • Ils doivent être transmis par référence (plutôt que par valeur);
  • Ils devraient être de type numérique.

Compilons et installons à nouveau l'extension mise à jour et écrivons des extraits de code pour voir comment fonctionne ces nouvelles fonctions:

<span>extension=skeleton.so</span>
Copier après la connexion
Copier après la connexion

Swap ($ a) échouera. Cela est attendu et inattendu. La partie attendue est que nous avons besoin de deux paramètres et qu'un seul est donné. Mais, cette erreur ne devrait-elle pas être capturée par PHP lors de l'appel de l'échange de fonction et de nous inviter quelque chose comme pas assez de paramètres?

Le premier appel (swap ($ a, $ b)) montre le résultat attendu: 20 | 10. La fonction échange les deux nombres passés.

Le deuxième appel est en quelque sorte inattendu: nous avons dit à PHP que nous devons échanger deux numéros! Mais il ignore simplement le fait que le 2ème paramètre passé est une chaîne et fait l'échange de toute façon!

Eh bien, en quelque sorte, il est toujours prévu. PHP ne distingue pas vraiment un type de nombre et un type de chaîne. Ce comportement est conforme à la norme PHP. Également en raison de ce comportement, nous n'avons pas utilisé et ne pouvons pas utiliser C types internes pour la variable temporaire utilisée dans la fonction (TEMP) mais que nous avons utilisé la valeur PHP :: comme type de variable.

Le troisième appel fonctionnera. Le premier var_dump affichera l'objet DateTime et le second affichera l'entier. C'est en quelque sorte très inattendu (du moins pour moi). Après tout, un objet est assez différent d'un nombre / chaîne. Mais après avoir considéré que ce comportement de «swap» est également faisable en PHP, il correspond aux bizarreries de PHP.

donc, cela signifie-t-il que la spécification «type» n'aura aucun impact? Pas vraiment. Pour élaborer davantage cela, nous créons une troisième fonction:

<span><span>#include <phpcpp.h></span>
</span>
<span>/**
</span><span> *  tell the compiler that the get_module is a pure C function
</span><span> */
</span><span>extern "C" {
</span>
    <span>/**
</span><span>     *  Function that is called by PHP right after the PHP process
</span><span>     *  has started, and that returns an address of an internal PHP
</span><span>     *  strucure with all the details and features of your extension
</span><span>     *
</span><span>     *  @return void*   a pointer to an address that is understood by PHP
</span><span>     */
</span>    PHPCPP_EXPORT <span>void *get_module() 
</span>    <span>{
</span>        <span>// static(!) Php::Extension object that should stay in memory
</span>        <span>// for the entire duration of the process (that's why it's static)
</span>        <span>static Php::Extension extension("yourextension", "1.0");
</span>
        <span>// @todo    add your own functions, classes, namespaces to the extension
</span>
        <span>// return the extension
</span>        <span>return extension;
</span>    <span>}
</span><span>}  </span>
Copier après la connexion
Copier après la connexion

et nous enregistrons cette fonction comme ceci:

<span>static Php::Extension extension("skeleton", "1.0"); // To be humble, we can change the version number to 0.0.1</span>
Copier après la connexion
Copier après la connexion

Le code de test sera comme ceci:

<span>make && sudo make install</span>
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion
Copier après la connexion

Le premier appel à SwapObject () fonctionnera au fur et à mesure que nous passions dans le type de classe correct (SampleClass). La seconde échouera, affichant «PHP Ratchable Error: Argument 1 transmis à SwapObject () doit être une instance de SampleClass, instance d'une autre classe donnée ...».

Le segment de code ci-dessus illustre un aspect important sur la restriction de type: les types scalaires La déclaration n'est pas vraiment implémentée. PHP et donc PHP-CPP n'appliquent que la déclaration de type objet. De plus, le nombre de paramètres n'est pas vraiment appliqué du côté PHP.

Conclusion

Dans cet article, nous avons illustré les étapes pour préparer PHP-CPP pour travailler pour notre environnement PHP. Nous avons également discuté de certaines étapes de base pour créer une extension PHP en utilisant PHP-CPP (et C Semantics).

Nous avons couvert les fichiers du projet d'extension, les signatures de fonction, l'exportation / l'enregistrement de la fonction et les types de paramètres de fonction.

Dans notre prochain article, nous élaborerons davantage quelques fonctionnalités clés de PHP-CPP et fournirons un cas d'utilisation réel démontrant l'utilisation de la classe C et des implémentations d'espace de noms à l'aide de PHP-CPP.

Questions fréquemment posées (FAQ) sur le développement d'extension PHP

Qu'est-ce que PHP-CPP et en quoi diffère-t-il de PHP?

PHP-CPP est une bibliothèque pour développer des extensions de PHP. Il propose une collection de classes bien documentées et conviviales, permettant aux développeurs de C d'écrire des extensions PHP sans les complexités de travail directement avec l'API Zend. Contrairement à PHP, qui est une langue interprétée, PHP-CPP vous permet d'écrire du code en C, une langue compilée. Cela peut entraîner des améliorations des performances, car le code compilé s'exécute généralement plus rapidement que le code interprété.

Comment installer PHP-CPP sur mon système?

Pour installer PHP-CPP sur votre système, vous Besoin de cloner le référentiel PHP-CPP de GitHub. Après le clonage, accédez au répertoire et exécutez la commande «Make». Une fois le processus de construction terminé, installez la bibliothèque à l'aide de la commande «Making Installer». N'oubliez pas que vous devez avoir des privilèges racine pour installer la bibliothèque.

Comment créer une extension PHP de base à l'aide de PHP-CPP?

La création d'une extension PHP à l'aide de PHP-CPP implique plusieurs étapes. Tout d'abord, vous devez créer un répertoire pour votre extension et y naviguer. Ensuite, créez un «MakeFile» et un fichier source C pour votre extension. Le «MakeFile» contiendra des instructions pour la construction de votre extension, tandis que le fichier source C contiendra le code réel de votre extension. Après avoir écrit votre code, vous pouvez créer votre extension à l'aide de la commande 'Make'.

Comment puis-je déboguer mon extension PHP?

Le débogage d'une extension PHP peut être un peu délicat, car vous ' Répondez à une langue compilée. Cependant, vous pouvez utiliser des outils comme GDB (GNU Debugger) pour déboguer votre extension. GDB vous permet de définir des points d'arrêt, de parcourir votre code et d'inspecter les variables, qui peuvent être très utiles lorsque vous essayez de retrouver les bogues.

Puis-je utiliser PHP-CPP pour créer des extensions pour PHP 7?

Oui, PHP-CPP est compatible avec PHP 7. Cependant, vous devez vous assurer que vous utilisez la dernière version de PHP-CPP, car les versions antérieures peuvent ne pas prendre en charge PHP 7.

Comment puis-je gérer les exceptions dans PHP-CPP?

PHP-CPP fournit une classe appelée PHP :: Exception, que vous pouvez utiliser pour lancer des exceptions à partir de votre code C. Ces exceptions peuvent ensuite être capturées et manipulées dans votre code PHP, comme toute autre exception PHP.

Puis-je utiliser PHP-CPP pour créer des extensions orientées objet?

Oui, PHP-CPP prend en charge la programmation orientée objet. Vous pouvez définir des classes dans votre code C, et ces classes peuvent ensuite être utilisées dans votre code PHP. Cela vous permet d'écrire un code modulaire propre et facile à entretenir.

Comment puis-je appeler les fonctions PHP à partir de mon code C?

PHP-CPP fournit une classe appelée php :: appel, qui Vous pouvez utiliser pour appeler les fonctions PHP à partir de votre code C. Cela vous permet de tirer parti de la puissance des fonctions intégrées de PHP dans votre extension.

Puis-je utiliser PHP-CPP pour créer des extensions qui interagissent avec les bases de données?

Oui, vous pouvez utiliser PHP- CPP pour créer des extensions qui interagissent avec les bases de données. Cependant, vous devrez utiliser une bibliothèque de base de données C, car PHP-CPP ne fournit aucune fonctionnalité de base de données intégrée.

Comment puis-je distribuer mon extension PHP?

Une fois que vous VE a construit votre extension PHP, vous pouvez le distribuer en l'emballant en tant que package PECL. PECL est un référentiel pour les extensions de PHP, et il fournit un moyen standard de distribuer et d'installer des extensions.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal