API du plugin du driver natif MySQL
L'API du plugin du driver natif MySQL est une fonctionnalité
du driver natif MySQL, ou mysqlnd.
Le plugin Mysqlnd opère sur la couche entre
les applications PHP et le serveur MySQL. Il est comparable
à un proxy MySQL. Un proxy MySQL opère sur une couche entre toutes
les applications clientes MySQL, par exemple, une application PHP
et un serveur MySQL. Le plugin Mysqlnd
peut entreprendre des tâches typiques de proxy MySQL comme
l'équilibrage de charge, ainsi que le suivi et l'optimisation
des performances. En raison d'une architecture et d'une localisation
différente, le plugin mysqlnd n'a pas tous les
inconvénients d'un proxy MySQL. Par exemple, avec le plugin, il
n'y a pas qu'un seul point d'échec, pas de serveur de proxy dédié
à déployer, et pas de nouveau langage à apprendre (Lua).
Un plugin mysqlnd peut être exécuté comme une extension
à mysqlnd. Un plugin peut intercepter la majorité des
fonctions mysqlnd. Les fonctions mysqlnd
sont appelées par l'extension PHP MySQL comme
ext/mysql, ext/mysqli, et
PDO_MYSQL. Comme résultat, il est possible pour un
plugin mysqlnd d'intercepter tous les appels effectués
par ces extensions depuis une application cliente.
Les appels aux fonctions internes mysqlnd peuvent
également être interceptés ou remplacés. Il n'y a aucune restriction
sur la manipulation des tables de fonctions internes mysqlnd.
Il est possible de définir des actions pour faire que lorsque
certaines fonctions mysqlnd sont appelées
par l'extension qui utilise mysqlnd, l'appel
est redirigé vers la fonction appropriée du plugin
mysqlnd. La possibilité de manipuler les tables
de fonctions internes mysqlnd dans ce sens permet
un maximum de flexibilité.
Le plugin Mysqlnd est en fait, une extension PHP,
écrite en C, qui utilise l'API du plugin mysqlnd
(qui est compilé dans le driver natif MySQL, mysqlnd).
Le plugin peut être à 100% transparent pour les applications PHP. Aucune
modification aux applications n'est nécessaire car le plugin opère
sur une couche différente. Le plugin mysqlnd
peut être utilisé dans une couche en dessous de mysqlnd.
La liste suivante représente quelques applications possibles
du plugin mysqlnd.
L'équilibrage de charge.
Séparation des lectures et des écritures. Un exemple de cette fonctionnalité
est l'extension PECL/mysqlnd_ms (Maître/esclave). Cette extension sépare
les requêtes de lecture et d'écriture pour une configuration de réplication.
Basculement
Round-Robin, le moins chargé
Surveillance
Journalisation des requêtes
Analyse de requêtes
Audit de requêtes. Un exemple de ceci est l'extension
PECL/mysqlnd_sip (SQL Injection Protection). Cette extension
inspecte les requêtes et exécute uniquement celles qui sont
autorisées suivant des ensembles de règles.
Performance
La mise en cache. Un exemple de ceci est l'extension
PECL/mysqlnd_qc (Query Cache).
Étranglement
Fragmentation. Un exemple de ceci est l'extension
PECL/mysqlnd_mc (Multi Connect). Cette extension tente
de séparer une requête SELECT en n parties, en utilisant
des requêtes du type SELECT ... LIMIT part_1, SELECT LIMIT part_n.
L'extension envoie les requêtes à des serveurs MySQL distincts
et fusionne ensuite le résultat à destination du client.
Plugins du driver natif MySQL disponibles
Il y a déjà plusieurs plugins mysqlnd de disponibles.
PECL/mysqlnd_mc -Plugin Multi Connexion.
PECL/mysqlnd_ms - Plugin Maître Esclave.
PECL/mysqlnd_qc - Plugin de mise en cache de requêtes.
PECL/mysqlnd_pscache - Plugin de mise en cache de gestionnaire
de requêtes préparées.
PECL/mysqlnd_sip - Plugin permettant la protection
contre les injections SQL.
PECL/mysqlnd_uh - Plugin de gestionnaire d'utilisateurs.
Comparaison des plugins mysqlnd avec proxy MySQL
Les plugins Mysqlnd et le proxy MySQL sont
des technologies différentes utilisant différentes approches.
Les deux sont des outils valides pour résoudre bon nombre
de tâches classiques, comme l'équilibrage de charge, la surveillance,
et l'amélioration des performances. Une importante différence est
que le proxy MySQL fonctionne avec tous les clients MySQL alors que
les plugins mysqlnd sont spécifiques aux
applications PHP.
Comme une extension PHP, un plugin mysqlnd
doit être installé sur le serveur d'applications PHP, en plus du
reste de PHP. Un proxy MySQL peut soit fonctionner sur le serveur
d'applications PHP, soit être installé sur une machine dédiée pour
gérer plusieurs serveurs d'applications PHP.
Le déploiement d'un proxy MySQL sur un serveur d'applications
a 2 avantages :
Pas un seul point d'échec
Facile à redimensionner (redimensionnement horizontal,
redimensionnement par le client)
Un proxy MySQL (et les plugins mysqlnd) peut
résoudre des problèmes facilement, qui sinon, auraient dû nécessiter
des modifications aux applications existantes.
Cependant, un proxy MySQL a quelques désavantages :
Un proxy MySQL est un nouveau composant, une nouvelle technologie à
appliquer au maître et à déployer.
Un proxy MySQL nécessite la connaissance du langage de script Lua.
Un proxy MySQL peut être personnalisé en utilisant les langages de
programmation C et Lua. Lua est le langage préféré pour un proxy MySQL.
Pour la plupart des experts PHP, Lua est un nouveau langage à apprendre.
Un plugin mysqlnd peut être écrit en C. Il est également
possible d'écrire un plugin en PHP en utilisant
PECL/mysqlnd_uh.
Un proxy MySQL fonctionne comme un démon - un processus en arrière-plan.
Un proxy MySQL peut rappeler des décisions prises antérieurement,
vu que tous les états peuvent être conservés. Cependant, un plugin
mysqlnd est lié au cycle de vie d'une requête PHP.
Un proxy MySQL peut également partager des résultats calculés une seule fois
sur plusieurs serveurs d'applications. Un plugin mysqlnd
peut donc avoir besoin de stocker des données dans un médium persistant.
Un autre démon peut être utilisé dans ce but, par exemple
Memcache. Ce mécanisme donne un avantage au proxy MySQL.
Un proxy MySQL fonctionne au-dessus de la couche physique. Avec un
proxy MySQL, il faut analyser et effectuer du "reverse engineering"
du protocole client serveur MySQL. Les actions sont limitées à celles
qui peuvent être effectuées par la manipulation du protocole
de communication. Si la couche physique change (ce qui arrive très rarement),
les scripts du proxy MySQL peuvent devoir être adaptés.
Les plugins Mysqlnd fonctionnent au-dessus de l'API C,
reflétant ainsi les APIs client libmysqlclient.
Cette API C est essentiellement une enveloppe du protocole Serveur Client MySQL,
ou de la couche physique, vu qu'elle est appelée quelques fois. L'on peut
intercepter tous les appels à l'API C. PHP utilise l'API C, toutefois,
il est possible de connecter tous les appels PHP, sans avoir besoin de programmer
au niveau de la couche physique.
Mysqlnd implémente la couche physique. Les plugins
peuvent toutefois analyser, effectuer un "reverse engineering", manipuler
et toujours remplacer le protocole de communication. Cependant, ce n'est
généralement pas nécessaire.
Vu que les plugins permettent de créer des implémentations qui
utilisent les 2 niveaux (API C et couche physique), ils ont plus de flexibilité
que le proxy MySQL. Si un plugin mysqlnd est implémenté
en utilisant l'API C, toutes les modifications ultérieures à la couche
physique ne nécessiteront pas de modification au plugin en tant que tel.
Obtenir l'API du plugin mysqlnd
L'API du plugin mysqlnd est simplement une partie
de l'extension du driver PHP Natif MySQL, ext/mysqlnd.
Le développement de l'API du plugin mysqlnd commença
en décembre 2009. Il est développé comme une partie du dépôt source de PHP,
et ainsi, est disponible depuis soit le dépôt public Git, soit depuis
le téléchargement des sources.
Les développeurs de plugin peuvent déterminer la version de
mysqlnd via la variable
MYSQLND_VERSION,
au format mysqlnd 8.3.17,
ou via MYSQLND_VERSION_ID, qui est un entier
par exemple 50007. Les développeurs peuvent calculer le numéro
de version comme ceci :
Table de calcul des MYSQLND_VERSION_IDVersion (partie)ExempleMajeur*100005*10000 = 50000Mineur*1000*100 = 0Patch7 = 7MYSQLND_VERSION_ID50007
Lors du développement, les développeurs doivent se référer
au numéro de version mysqlnd pour des tests
de compatibilité et de version, sachant que plusieurs
versions de mysqlnd peuvent survenir durant
un cycle de vie de la branche de développement de PHP.
Architecture du plugin du driver natif
Cette section fournit un aperçu de l'architecture du plugin
mysqlnd.
Aperçu du driver natif MySQL
Avant de développer des plugins mysqlnd,
il est utile d'avoir une connaissance minimale sur l'organisation
de mysqlnd. Mysqlnd est composé
des modules suivants :
Schéma de l'organisation mysqlnd, par moduleModules de statistiquesmysqlnd_statistics.cConnexionmysqlnd.cJeu de résultatsmysqlnd_result.cDonnées méta du jeu de résultatsmysqlnd_result_meta.cRequêtemysqlnd_ps.cRéseaumysqlnd_net.cCouche physiquemysqlnd_wireprotocol.c
Objet C orienté paradigme
Au niveau du code, mysqlnd utilise un masque C
pour implémenter l'orientation de l'objet.
En C, on utilise une structure (struct)
pour représenter un objet. Les membres de cette structure
représentent les propriétés de l'objet. Les membres de la
structure pointant vers des fonctions représentent les méthodes.
Contrairement aux autres langages comme C++ ou Java, il n'y a
pas de règles fixes sur l'héritage dans les objets C orientés paradigme.
Cependant, il y a quelques conventions qui doivent être suivies
qui seront abordées ultérieurement.
Le cycle de vie PHP
Le cycle de vie de PHP comporte 2 cycles basiques :
Le cycle de démarrage et d'arrêt du moteur PHP
Le cycle d'une demande
Lorsque le moteur PHP démarre, il appelle la fonction d'initialisation
du module (MINIT) de chaque extension enregistrée. Ceci
permet à chaque module de définir les variables et d'allouer les
ressources qui doivent exister pour la durée de vie du processus
correspondant au moteur PHP. Lorsque le moteur PHP s'arrête,
il appelle la fonction d'arrêt du module (MSHUTDOWN) pour chaque extension.
Pendant la durée de vie du moteur PHP, il recevra des demandes.
Chaque demande constitue un autre cycle de vie. Pour chaque
requête, le moteur PHP appellera la fonction d'initialisation
de chaque extension. L'extension peut effectuer toutes les définitions
de variables ainsi que les allocations de ressources nécessaires pour
traiter la demande. Lorsque le cycle de la demande se termine, le moteur
appelle la fonction d'arrêt (RSHUTDOWN) pour chaque extension,
ainsi, l'extension peut lancer tout le nettoyage nécessaire.
Comment fonctionne un plugin
Un plugin mysqlnd fonctionne en interceptant les appels
effectués à mysqlnd par les extensions qui utilisent
mysqlnd. Ceci est possible en obtenant la table
de fonction mysqlnd, en la sauvegardant, et en la
remplaçant par une table de fonction personnalisée, qui appelle les fonctions
du plugin.
Le code suivant montre la façon dont la table de fonction
mysqlnd est remplacée :
query = MYSQLND_METHOD(my_conn_class, query);
}
]]>
Les manipulations de la table de fonction de connexion doivent
être effectuées lors de l'initialisation du module (MINIT).
La table de fonction est une ressource globale partagée. Dans
un environnement multithread, avec une compilation TSRM, la
manipulation d'une ressource globale partagée lors d'un processus
de demande entraînera la plupart du temps des conflits.
N'utiliser aucune logique de taille fixe lors de la manipulation
de la table de fonction mysqlnd : les nouvelles
méthodes peuvent être ajoutées à la fin de la table de fonction.
La table de fonction peut être modifiée à tout moment par la suite.
Appel des méthodes parents
Si la table de fonction originale est sauvegardée, il est toujours
possible d'appeler les entrées de la table de fonction originale -
les méthodes parents.
Dans ce cas, tout comme pour Connection::stmt_init(),
il est vital d'appeler la méthode parent avant toute autre activité
dans la méthode dérivée.
Étendre des propriétés
Un objet mysqlnd est représenté par une structure C.
Il n'est pas possible d'ajouter un membre à une structure C au moment
de l'exécution. Les utilisateurs d'objets mysqlnd
ne peuvent pas ajouter simplement des propriétés aux objets.
Les données arbitraires (propriétés) peuvent être ajoutées aux objets
mysqlnd en utilisant une fonction appropriée de la
famille mysqlnd_plugin_get_plugin_<object>_data().
Lors de l'allocation d'un objet, mysqlnd réserve
un espace à la fin de l'objet pour accueillir un pointeur
void * vers des données arbitraires.
mysqlnd réserve un espace pour un pointeur
void * par plugin.
La table suivante montre comment calculer la position d'un pointeur
pour un plugin spécifique :
Calcul des pointeurs pour mysqlndAdresse mémoireContenus0Début de la structure C de l'objet mysqlndnFin de la structure C de l'objet mysqlndn + (m x sizeof(void*))void* vers les données de l'objet du m-ème plugin
Si l'on prévoit de faire des sous-classes des constructeurs
des objets mysqlnd, ce qui est autorisé,
il faut conserver ceci en mémoire !
Le code suivant montre la façon dont on étend des propriétés :
persistent);
(*props)->query_counter = 0;
}
return props;
}
]]>
Le développeur du plugin est responsable de la gestion de la mémoire
associée aux données du plugin.
L'utilisation de l'allocateur de mémoire mysqlnd
est recommandée pour les données du plugin. Ces fonctions sont nommées
en utilisant la convention suivante : mnd_*loc().
L'allocateur mysqlnd a quelques fonctionnalités bien utiles,
comme la possibilité d'utiliser un allocateur de débogage dans une compilation
non-débogue.
Quand et comment faire une sous-classeQuand faire une sous-classe ?Est-ce que chaque instance a sa table de fonction privée ?Comment faire une sous-classe ?Connexion (MYSQLND)MINITNonmysqlnd_conn_get_methods()Jeu de résultats (MYSQLND_RES)MINIT ou aprèsOuimysqlnd_result_get_methods() ou méthode de l'objet de manipulation de la table de fonctionMéta du jeu de résultats (MYSQLND_RES_METADATA)MINITNonmysqlnd_result_metadata_get_methods()Requête (MYSQLND_STMT)MINITNonmysqlnd_stmt_get_methods()Réseau (MYSQLND_NET)MINIT ou aprèsOuimysqlnd_net_get_methods() ou méthode de l'objet de manipulation de la table de fonctionCouche physique (MYSQLND_PROTOCOL)MINIT ou aprèsOuimysqlnd_protocol_get_methods() ou méthode de l'objet de manipulation de la table de fonction
Il ne faut pas manipuler les tables de fonction après MINIT si
ce n'est pas autorisé suivant la table ci-dessus.
Quelques classes contiennent un pointeur vers une méthode de la table
de fonction. Toutes les instances d'une telle classe partageront
la même table de fonction. Pour éviter le chaos, en particulier
dans les environnements threadés, ce genre de tables de fonction
ne doit être manipulé que lors du MINIT.
Les autres classes utilisent une copie de la table de fonction
globale partagée. Cette copie est créée en même temps que l'objet.
Chaque objet utilise sa propre table de fonction. Ceci donne
2 options : il est possible de manipuler la table de fonction par défaut
d'un objet au moment du MINIT, et il est également possible d'affiner des
méthodes d'un objet sans impacter les autres instances de la même
classe.
L'avantage de l'approche avec une table de fonction partagée est
la performance. Il n'est pas nécessaire de copier une table de fonction
pour chaque objet.
Statut du constructeurTypeAllocation, construction, réinitialisationPeut-être modifié ?AppelantConnexion (MYSQLND)mysqlnd_init()Nonmysqlnd_connect()Jeu de résultats(MYSQLND_RES)
Allocation :
Connection::result_init()
Reset et réinitialisation lors de :
Result::use_result()
Result::store_result
Oui, mais appel du parent !
Connection::list_fields()
Statement::get_result()
Statement::prepare() (Méta-données uniquement)
Statement::resultMetaData()
Méta du jeu de résultats (MYSQLND_RES_METADATA)Connection::result_meta_init()Oui, mais appel du parent !Result::read_result_metadata()Statement (MYSQLND_STMT)Connection::stmt_init()Oui, mais appel du parent !Connection::stmt_init()Réseau (MYSQLND_NET)mysqlnd_net_init()NonConnection::init()Couche physique (MYSQLND_PROTOCOL)mysqlnd_protocol_init()NonConnection::init()
Il est vivement recommandé de ne pas remplacer entièrement un constructeur.
Les constructeurs effectuent les allocations mémoires. Les allocations
mémoires sont vitales pour l'API du plugin mysqlnd
ainsi que pour la logique de l'objet mysqlnd. Si
l'on ne se soucie pas des alertes et que l'on insiste pour
remplacer les constructeurs, il est recommandé d'au moins appeler
le constructeur parent avant de faire quoi que ce soit dans le
constructeur.
Au niveau de toutes les alertes, il peut être utile de faire des
sous-classes des constructeurs. Les constructeurs sont les endroits
parfaits pour modifier les tables de fonction des objets avec les
tables d'objets non partagés, comme les jeux de résultats, le
réseau ou encore la couche physique.
Statut du destructeurTypeLa méthode dérivée doit appeler le parent ?DestructeurConnexionoui, après l'exécution de la méthodefree_contents(), end_psession()Jeu de résultatsoui, après l'exécution de la méthodefree_result()Méta du jeu de résultatsoui, après l'exécution de la méthodefree()Requêteoui, après l'exécution de la méthodedtor(), free_stmt_content()Réseauoui, après l'exécution de la méthodefree()Couche physiqueoui, après l'exécution de la méthodefree()
Les destructeurs sont les endroits parfaits pour libérer les propriétés,
mysqlnd_plugin_get_plugin_<object>_data().
Les destructeurs listés peuvent ne pas être les équivalents aux
méthodes actuelles mysqlnd libérant l'objet lui-même.
Cependant, ils sont les meilleurs endroits pour libérer
les données du plugin. Tout comme les constructeurs, il est possible de
remplacer les méthodes entières mais ce n'est pas recommandé.
Si plusieurs méthodes sont listées dans la table ci-dessus, il faut
modifier toutes les méthodes listées et libérer les données du
plugin dans la méthode appelée en premier par mysqlnd.
La méthode recommandée pour les plugins est de modifier simplement les méthodes,
libérer la mémoire et appeler l'implémentation du parent immédiatement après.
L'API du plugin mysqlnd
Voici la liste des fonctions fournies dans l'API plugin
mysqlnd :
mysqlnd_plugin_register()
mysqlnd_plugin_count()
mysqlnd_plugin_get_plugin_connection_data()
mysqlnd_plugin_get_plugin_result_data()
mysqlnd_plugin_get_plugin_stmt_data()
mysqlnd_plugin_get_plugin_net_data()
mysqlnd_plugin_get_plugin_protocol_data()
mysqlnd_conn_get_methods()
mysqlnd_result_get_methods()
mysqlnd_result_meta_get_methods()
mysqlnd_stmt_get_methods()
mysqlnd_net_get_methods()
mysqlnd_protocol_get_methods()
Il n'y a pas de définition formelle de ce qu'est un plugin
ainsi de la façon dont fonctionne un plugin.
Les composants les plus souvent trouvés dans les mécanismes de plugin sont :
Un gestionnaire de plugin
Une API du plugin
Les services applicatifs (ou modules)
Les APIs des services applicatifs (ou APIs du module)
Le concept d'un plugin mysqlnd utilise ces fonctionnalités,
ainsi que d'autres joyeusetés d'architecture ouverte.
Aucune restriction
Un plugin a un accès total aux travaux internes de
mysqlnd. Il n'y a aucune limite de sécurité
ou de restrictions. Tout peut être écrasé pour implémenter des
algorithmes utiles ou hostiles. Il est recommandé de ne déployer
que des plugins depuis des sources de confiance.
Tel que discuté précédemment, les plugins peuvent utiliser librement
des pointeurs. Ces pointeurs ne sont restreints en aucune manière,
aussi, il est possible de pointer vers les données d'un autre plugin.
Une simple position arithmétique peut être utilisée pour lire
les données d'un autre plugin.
Il est recommandé d'écrire des plugins coopératifs, et ainsi, appeler
toujours la méthode parent. Les plugins devraient toujours coopérer avec
mysqlnd.
Enjeux : un exemple de chaînage et de coopérationExtensionPointeur mysqlnd.query()Pile d'appel si on appelle le parentext/mysqlndmysqlnd.query()mysqlnd.queryext/mysqlnd_cachemysqlnd_cache.query()
mysqlnd_cache.query()
mysqlnd.query
ext/mysqlnd_monitormysqlnd_monitor.query()
mysqlnd_monitor.query()
mysqlnd_cache.query()
mysqlnd.query
Dans ce scénario, un plugin cache (ext/mysqlnd_cache) et
un plugin de surveillance (ext/mysqlnd_monitor)
sont chargés. Les 2 ont une sous-classe de Connection::query().
L'enregistrement du plugin survient lors du MINIT
en utilisant la logique évoquée précédemment. PHP appelle les extensions
dans un ordre alphabétique par défaut. Les plugins ne sont pas au courant
les uns les autres et ne peuvent fixer de dépendances.
Par défaut, les plugins appellent l'implémentation du parent de la
méthode de requête dans leur version de la méthode dérivée.
Récapitulatif de l'extension PHP
Voici un récapitulatif de ce qui survient lors de l'utilisation
d'un plugin d'exemple, ext/mysqlnd_plugin,
qui expose l'API C du plugin mysqlnd à PHP :
Toutes les applications PHP MySQL tentent d'établir une connexion
à l'adresse 192.168.2.29
L'application PHP utilisera ext/mysql,
ext/mysqli ou PDO_MYSQL.
Ces 3 extensions PHP MySQL utilisent mysqlnd pour
établir la connexion à l'adresse 192.168.2.29.
Mysqlnd appelle sa méthode de connexion, qui a été sous-classée
par ext/mysqlnd_plugin.
ext/mysqlnd_plugin appelle la méthode de l'espace utilisateur
proxy::connect() enregistrée par l'utilisateur.
L'espace utilisateur modifie l'hôte de connexion de 192.168.2.29
à 127.0.0.1 et retourne la connexion établie par
parent::connect().
ext/mysqlnd_plugin exécute l'équivalent de
parent::connect(127.0.0.1) en appelant la méthode
originale de mysqlnd pour établir une connexion.
ext/mysqlnd établit une connexion et redonne la main
à ext/mysqlnd_plugin.
ext/mysqlnd_plugin retourne également.
Quelle que soit l'extension PHP MySQL utilisée par l'application,
elle reçoit une connexion à 127.0.0.1. L'extension PHP MySQL
redonne la main à l'application PHP. Le cycle est clos.
Bien commencer la compilation d'un plugin mysqlnd
Il est important de se souvenir qu'un plugin mysqlnd
est lui-même une extension PHP.
Le code suivant montre la structure basique d'une fonction MINIT
utilisée dans un plugin typique mysqlnd :
query = MYSQLND_METHOD(mysqlnd_plugin_conn, query);
conn_m->connect = MYSQLND_METHOD(mysqlnd_plugin_conn, connect);
}
]]>
Tâche d'analyse : depuis C vers l'espace utilisateur
Processus :
PHP : l'utilisateur enregistre une fonction de rappel pour le plugin
PHP : l'utilisateur appelle une méthode de l'API PHP MySQL pour se connecter à MySQL
C : ext/*mysql* appelle la méthode mysqlnd
C : mysqlnd se termine dans ext/mysqlnd_plugin
C : ext/mysqlnd_plugin
Appel de la fonction de rappel de l'espace utilisateur
Ou la méthode originale mysqlnd, si l'espace
utilisateur n'a pas défini de fonction de rappel
Il faut effectuer les opérations suivantes :
Écrire une classe "mysqlnd_plugin_connection" en C
Accepter et enregistrer l'objet proxy via
"mysqlnd_plugin_set_conn_proxy()"
Appeler les méthodes de proxy de l'espace utilisateur
depuis C (optimisation - zend_interfaces.h)
Les méthodes de l'objet de l'espace utilisateur peuvent soit être
appelées en utilisant call_user_function(),
soit il est possible d'opérer à un niveau en dessous du moteur Zend et
utiliser zend_call_method().
Optimisation : appel des méthodes depuis C en utilisant
zend_call_method
Le code suivant montre un prototype pour la fonction
zend_call_method, issue de
zend_interfaces.h.
L'API Zend supporte 2 arguments. Il est possible d'en avoir besoin de plus, par
exemple :
Pour contourner ce problème, il faudra faire une copie
de zend_call_method() et ajouter une
fonctionnalité pour ajouter des paramètres. L'on peut
réaliser ceci en créant un jeu de macros
MY_ZEND_CALL_METHOD_WRAPPER.
Appel de l'espace utilisateur PHP
Le code ci-dessous montre la méthode optimisée pour effectuer un
appel à une fonction de l'espace utilisateur depuis C :
Appel de l'espace utilisateur: arguments simplesAppel de l'espace utilisateur : structures comme arguments
Le premier argument de toutes les méthodes mysqlnd
est un objet C. Par exemple, le premier argument de la méthode
connect() est un pointeur vers MYSQLND.
La structure MYSQLND représente un objet de connexion
mysqlnd.
Le pointeur de l'objet de connexion mysqlnd
peut être comparé à un pointeur de fichier standard I/O.
Tout comme un pointeur de fichier standard I/O, un objet de
connexion mysqlnd doit être lié à l'espace
utilisateur en utilisant une variable PHP de type ressource.
Depuis C vers l'espace utilisateur, puis, retour
Les utilisateurs PHP doivent pouvoir appeler l'implémentation
du parent d'une méthode écrasée.
Comme résultat d'un sous-classement, il est possible de
redéfinir uniquement les méthodes sélectionnées, et l'on
peut choisir d'avoir des actions "pre" ou "post".
Construction d'une classe : mysqlnd_plugin_connection::connect()