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:
Quand il s'agit de choisir un outil pour créer des extensions de PHP, nous voyons deux approches différentes:
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.
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>
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>
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.
PHP-CPP fournit un projet d'extension squelette, contenant les 3 fichiers suivants:
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:
Ce sont toutes les modifications que j'ai apportées. Le reste du makefile peut être conservé tel quel.
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>
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>
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>
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>
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>
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:
(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.
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>
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>
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 ¶ms) </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>
Veuillez prendre le temps de regarder la sortie:
Nous reviendrons à ce que nous avons observé ici plus tard.
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>
et exportez également la fonction en spécifiant le nombre de paramètres et leur type:
<span>make && sudo make install</span>
Nous disons explicitement que:
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>
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>
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>
Le code de test sera comme ceci:
<span>make && sudo make install</span>
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.
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.
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é.
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.
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'.
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.
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.
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.
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.
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.
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.
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!