API de Complementos del Controlador Nativo de MySQL La API de Complementos del Controlador Nativo de MySQL es una característica del Controlador Nativo de MySQL, o mysqlnd. Los complementos de mysqlnd operan en la capa que hay entre las aplicaciones de PHP y el servidor MySQL. Es comparable al Proxy de MySQL. El Proxy de MySQL opera sobre una capa entre cualquier aplicación cliente de MySQL, por ejemplo, una aplicación de PHP, y el servidor de MySQL. Los complementos de mysqlnd can undertake typical MySQL Proxy tasks such as load balancing, monitorizan y optimizan el rendimiento. A causa de la arquitectura y ubicación diferentes, los complementos de mysqlnd no tienen algunas de las desventajas del Proxy de MySQL. Por ejemplo, con los complementos no existe un único punto de fallo, ni un servidor proxy para el despliegue, y no hace falta aprender un nuevo lenguaje de programación (Lua). Se puede pensar en un complemento de mysqlnd como una extensión de mysqlnd. Los complementos pueden interceptar la mayoría de las funciones de mysqlnd. Las funciones de mysqlnd son llamadas por las extensiones de MySQl de PHP, como ext/mysql, ext/mysqli, y PDO_MYSQL. Como resultado, es posible que un complemento de mysqlnd intercepte todas las llamadas hechas a estas extensiones desde la apliacación cliente. Las llamadas a funciones internas de mysqlnd también pueden ser interceptadas o reemplazadas. No existen restricciones en la manipulación de tablas de funciones internas de mysqlnd. Es posible configurar cosas, y así cuando ciertas funciones de mysqlnd son llamadas por extensiones que utilizan mysqlnd, la llamada es dirigida a la función apropiada del complemento de mysqlnd. La capacidad de manipular tablas de funciones internas de mysqlnd de esta manera permite una flexibilidad máxima para los complementos. Los complementos de mysqlnd son de hecho Extensiones de PHP, escritos en C, que utilizan la API de complementos de mysqlnd (la cual está construida dentro del Controlador Nativo de MySQL, mysqlnd). Los complementos se pueden hacer 100% transparentes a las aplicaciones de PHP. No es necesario hacer ningún cambio a las aplicaciones ya que los complementos operan en una capa diferente. Se puede pensar en los complementos de mysqlnd como en una operación en una capa por debajo de mysqlnd. La siguiente lista representa algunas aplicaciones posibles de los complementos de mysqlnd. Equilibrio de Carga División de Lectura/Escritura. Un ejemplo de esto es la extensión PECL/mysqlnd_ms (Maestro Esclavo). Esta extensión divide las consultas de lectura/escritura para una configuración de réplica. Tolerancia a fallos Rotación de servidores para evitar la sobrecarga ("Round-Robin") Monitorización Registro de Consultas Análisis de Consultas Audición de Consultas. Un ejemplo de esto es la extensión PECL/mysqlnd_sip (Protección contra la Inyección SQL). Esta extensión inspecciona las consultas y ejecuta únicamente aquellas que están permitidas según un cojunto de reglas. Rendimiento Almacenamiento en Caché. Un ejemplo de esto es la extenión PECL/mysqlnd_qc (Caché de Consultas). Estrangulamiento ("Throttling") Fragmentación. Un ejemplo de esto es la extensión PECL/mysqlnd_mc (Multiconexión). Esta extensión intentará dividir una sentencia SELECT en n partes, usando SELECT ... LIMIT parte_1, SELECT LIMIT parte_n. Envía las consultas a diferentes servidores MySQL y combina el resultado en el cliente. Complementos del Controlador Nativo de MySQL disponibles Hay varios complementos de mysqlnd ya disponibles. Estos incluyen: PECL/mysqlnd_mc - Complemento de Multiconexión. PECL/mysqlnd_ms - Complemento Maestro Esclavo. PECL/mysqlnd_qc - Complemento de Caché de Consultas. PECL/mysqlnd_pscache - Complemento de Caché de Gestores de Sentencias Preparadas. PECL/mysqlnd_sip - Complemento de Protección contra Inyección SQL. PECL/mysqlnd_uh - Complemento de Gestor de Usuarios.
Una comparación de los complementos de mysqlnd y el Proxy de MySQL Los complementos de mysqlnd y el Proxy de MySQL son diferentes tecnologías que utilizan diferentes enfoques. Ambos son herramientas válidas para resolver una variedad de tareas comunes tales como el equilibrio de carga, monitorización, y mejoras en el rendimiento. Una diferencia importante es que el Proxy de MySQL funciona con todos los clientes de MySQL, mientras que los complementos de mysqlnd son específicos de aplicaciones de PHP. Al igual que una Extensión de PHP, un complemento de mysqlnd se instala en el servidor de aplicaciones de PHP, junto con el resto de PHP. El Proxy de MySQL puede ejecutarse sobre el servidor de aplicaciones de PHP o ser instalado en una máquina dedicada para manejar múltiples servidores de aplicaciones de PHP. El despliegue del Proxy de MySQL sobre un servidor de aplicaciones tiene dos ventajas: No tiene un único punto de fallo Fácil escalabilidad (escalabilidad horizontal, escalabilidad por cliente) El Proxy de MySQL (y los complementos de mysqlnd) pueden resolver problemas fácilmente que de otro modo requerirían cambios en las aplicaciones existentes. Sin embargo, el Proxy de MySQL tiene algunas desventajas: El Proxy de MySQL es un componente y una tecnología nuevos que son necesarios llegar a dominar y desplegar. El Proxy de MySQL requiere conocimientos del lenguaje de scripts Lua. El Proxy de MySQL puede ser personalizado con programación en C y Lua. Lua es el lenguaje de scripts preferido del Proxy de MySQL. Para la mayoría de los expertos en PHP, Lua es un nuevo lenguaje que aprender. Un complemento de mysqlnd puede ser escrito en C. También es posible escribir complementos en PHP usando PECL/mysqlnd_uh. El Proxy de MySQL se ejecuta como un demonio - un proceso en segundo plano. El Proxy de MySQL puede recordar decisiones anteriores, ya que todos los estados pueden ser guardados. Sin embargo, un complemento de mysqlnd está vinculado al ciclo de vida basado en peticiones de PHP. El Proxy de MySQL también comparte resultados computados una única vez entre múltiples servidores de aplicaciones. Un complemento de mysqlnd necesitaría almacenar los datos en un medio persistente para poder hacer esto. Sería necesario otro demonio para este propósito, tal como Memcache. Esto otorga al Proxy de MySQL una ventaja en este caso. El Proxy de MySQL funciona en lo más alto del protocolo de cable. Con el Proxy de MySQL se ha de analizar y usar ingenierá inversa con el Protocolo Cliente Servidor de MySQL. Las acciones están limitadas a aquellas que pueden realizarse manipulando el protocolo de comunicación. Si el protocolo de calbe cambia (lo que ocurre muy raramente), los scripts del Proxy de MySQL necesitarían cambiarse también. Los complementos de Mysqlnd funcionan en lo más alto de la API en C, la cual refleja el cliente libmysqlclient y las APIs Connector/C. ESta API en C es básicamente una envoltura sobre el protocolo Cliente Servidor de MySQL, o protocolo de cable, como es llamado a veces. Se pueden interceptar todas las llamadas a la API en C. PHP hace uso de la API en C, por lo que se pueden enganchar todas las llamadas de PHP, sin necesidad de programar en el nivel del protocolo de cable. Mysqlnd implementa el protocolo de cable. Los complementos pueden, por lo tanto, analizar, usar ingeniería inversa, manipular e incluso reemplazar el protocolo de comunicación. Sin embargo, esto normalmente no es necesario. Ya que los complementos permiten crear implementaciones que utilizan dos niveles (la API en C y el protocolo de cable), tienen más flexibilidad que el Proxy de MySQL. Si un complemento de mysqlnd es implementado usando la API en C, cualquier cambio subsiguiente al protocolo de cable no requerirá cambios en el complemento en sí.
Obtener la API de complementos de mysqlnd La API de complementos de mysqlnd es sencillamente parte de la extensión del Controlador Nativo de MySQL de PHP, ext/mysqlnd. El desarrollo de la API de complementos de mysqlnd comenzó en diciembre de 2009. Está desarrollado como parte del repositorio fuente de PHP, y como tal está disponible al público vía Git, o a través de las descargas de instantáneas del código fuente. La siguiente tabla muestra las versiones de PHP y la versión correspondiente de mysqlnd contenida dentro. La versión incluída de mysqlnd por versión de PHP Versión de PHP Versión del Controlador Nativo de MySQL 5.3.0 5.0.5 5.3.1 5.0.5 5.3.2 5.0.7 5.3.3 5.0.7 5.3.4 5.0.7
Los desarrolladores de complementos pueden determinar la versión de mysqlnd accediendo a MYSQLND_VERSION, que es una cadena en el formato mysqlnd 5.0.7-dev - 091210 - $Revision: 300535, o a través de MYSQLND_VERSION_ID, que es un valor integer tal como 50007. Los desarrolladores pueden calcular el número de versión como sigue: Tabla de cálculo de MYSQLND_VERSION_ID Versión (parte) Ejemplo Mayor*10000 5*10000 = 50000 Menor*100 0*100 = 0 Parche 7 = 7 MYSQLND_VERSION_ID 50007
Durante el desarrollo, los desarroladores deberían consultar el número de versión de mysqlnd por compatibilidad y pruebas de versión, ya que varias iteraciones de mysqlnd podrían ocurrir durante el ciclo de vida de una rama de desarrollo de PHP con un número de versión de PHP único.
Arquitectura de los Complementos del Controlador Nativo de MySQL Esta sección proporciona información general de la arquitectura de los complementos de mysqlnd. Información general del Controlador Nativo de MySQL Antes de desarrollar complementos de mysqlnd, es útil conocer un poco cómo mysqlnd está organizado. Mysqlnd consiste en los siguientes módulos: La gráfica de organización de mysqlnd, por módulo Módulos de estadísticas mysqlnd_statistics.c Conexión mysqlnd.c Conjunto de resultados mysqlnd_result.c Metadatos de conjuntos de resultados mysqlnd_result_meta.c Sentencia mysqlnd_ps.c Red mysqlnd_net.c Protocolo de cable mysqlnd_wireprotocol.c
Paradigma de la orientación a objetos de C A nivel de código, mysqlnd utiliza un patrón de C para implementar la orientación a objetos. En C se utiliza una estrucutra (struct) para representar un objeto. Los miembros de la estructura representan las propiedades del objeto. Los miembros de la estrucutra que apuntan a funciones representan los métodos. A diferencia de otros lenguajes como C++ o Java, no existen reglas fijas sobre herencia en el paradigma de la orientación a objetos de C. Sin embargo, existen algunas convenciones que se han de seguir y serán discutidas más tarde. El ciclo de vida de PHP Al considerar el ciclo de vida de PHP existen dos ciclos básicos: El ciclo de inicio y cierre del motor de PHP El ciclo de peticiones Cuando se inicia el motor de PHP, éste llamará a la función de inicialización de módulos (MINIT) para cada extensión registrada. Esto permite a cada módulo establecer variables y asignar recursos que existirán durante el tiempo de vida del proceso del motor de PHP. Al cerrar el motor de PHP, éste llamará a las funciones de cierre de módulos (MSHUTDOWN) para cada extensión. Durante el tiempo de vida del motor de PHP, éste recibirá varias peticiones. Cada petición constituye otro ciclo de vida. En cada petición, el motor de PHP llamará a la función de inicialización de peticiones para cada extensión. La extensión puede realizar cualquier establecimiento de variables y asignación de recursos necesarios para el proceso de petición. Al finalizar el ciclo de peticiones, el motor llama a la función de cierre de peticiones (RSHUTDOWN) de cada extensión, por lo que la extensión puede realizar cualquier limpieza necesaria. Cómo funciona un complemento Un complemento de mysqlnd funciona interceptando llamada realizadas a mysqlnd por extensiones que utilizan mysqlnd. Esto se lleva a cabo obteniendo la tabla de funciones de mysqlnd, haciendo una copia de seguridad de ella, y reemplazándola por una tabla de funciones personalizada, la cual llamará a las funciones del complemento cuando sea necesario. El siguiente código muestra cómo se reemplaza la tabla de funciones de mysqlnd: query = MYSQLND_METHOD(my_conn_class, query); } ]]> La manipulación de la tabla de funciones de conexión debe hacerse durante la Inicialización de Módulos (MINIT). La tabla de funciones es un recurso global compartido. En un entorno multihilo, con un TSRM construido, la manipulación de un recurso global compartido durante el proceso de peticiones resultará en conflictos casi con toda seguridad. No utilice cualquier lógica de tamaña fijo al manipular la tablas de funciones de mysqlnd: los métodos nuevos se pueden añadir al final de la tabla de funciones. La tabla de funciones puede cambiar en cualquier momento en el futuro. Llamar a métodos padre Si las entradas de la tabla de funciones original está copiada, aún es posible llamar a las entradas de la tabla de funciones original - los métodos padre. En algunos casos, como en Connection::stmt_init(), es vital llamar al método padre antes de realizar cualquier otra actividad en el método derivado. Extender propiedades Un objeto mysqlnd está representado por una estrucutra de C. No es posible añadir un miembro a una estructura de C en tiempo de ejecución. Los usuarios de objetos mysqlnd no pueden simplemente añadir propiedades a los objetos. Se pueden añadir datos arbitrarios (propiedades) a objetos mysqlnd usando la función apropiada de la familia de mysqlnd_plugin_get_plugin_<object>_data(). Cuando se asigna un objeto, mysqlnd reserva espacio al final del objeto para que contenga un puntero void * a datos arbitrarios. mysqlnd reserva espacio para un puntero void * por complemento. La siguiente tabla muestra cómo calcular la posición del puntero para un complemento específico: Cálculos de puntero para mysqlnd Dirección de memoria Contenido 0 Inicio de la estructura de C del objeto mysqlnd n Fin de la estructura de C del objeto mysqlnd n + (m x sizeof(void*)) void* a los datos del objeot del complemento m-ésimo
Si se planea usar cualquier constructor de objetos mysqlnd en subclases, lo cual está permitido, ¡se debe tener esto en cuenta! El siguiente código muestra la extensión de propiedades: persistent); (*props)->query_counter = 0; } return props; } ]]> El desarrollador del complemento es responsable de la gestión de memoria de lo datos del complemento. Se recomienda el uso del asignador de memoria de mysqlnd para los datos del complemento. Estas funciones son nombradas usando la convención: mnd_*loc(). El asignador de mysqlnd tiene algunas características útiles, como la capacidad de usar un asignador de depuración en una construcción de no depuración. Cuándo y cómo usar subclases ¿Cuándo usar subclases? ¿Cada instancia tiene su propia tabla de funciones privada? ¿Cómo usar subclases? Conexión (MYSQLND) MINIT No mysqlnd_conn_get_methods() Conjunto de resultados (MYSQLND_RES) MINIT o después mysqlnd_result_get_methods() o manipulación de la tabla de funciones de métodos de objetos Metadatos de conjunto de resultados (MYSQLND_RES_METADATA) MINIT No mysqlnd_result_metadata_get_methods() Sentencia (MYSQLND_STMT) MINIT No mysqlnd_stmt_get_methods() Red (MYSQLND_NET) MINIT o después mysqlnd_net_get_methods() o manipulación de la tabla de funciones de métodos de objetos Protocolo de cable (MYSQLND_PROTOCOL) MINIT o después mysqlnd_protocol_get_methods() o manipulación de la tabla de funciones de métodos de objetos
No se deben manipular las tablas de funciones en ningún momento posterior a MINIT si no está permitido según la tabla de arriba. Algunas clases contienen un puntero a la tabla de funciones de métodos. Todas las instancias de esas clases compartirán la misma tabla de funciones. Para evitar el caos, en particular en entornos de hilos, tales tablas de funciones deben ser manipuladas solamente durante MINIT. Otras clases usan copias de una tabla de funciones compartida globalmente. La copia de la tabla de funciones de la clase se crea junto con el objeto. Cada objeto usa su propia tabla de funciones. Esto proporciona dos opciones: se puede manipular la tabla de funciones predetermiada de un objeto durante MINIT, y además se pueden perfeccionar métodos de un objeto sin impactar otras instancias de la misma clase. La ventaja del enfoque de la tabla de funciones compartida es el rendimiento. No hay necesidad de copiar una tabla de funciones para cada objeto. Estado del constructor Asignación, construcción, reinicio ¿Se puede modificar? Llamador Conexión (MYSQLND) mysqlnd_init() No mysqlnd_connect() Conjunto de resultados (MYSQLND_RES) Asignación: Connection::result_init() Reinicio y reinicialización durante: Result::use_result() Result::store_result Sí, ¡pero se ha de llamar al padre! Connection::list_fields() Statement::get_result() Statement::prepare() (Solamente metadatos) Statement::resultMetaData() Metadatos de conjunto de resultados (MYSQLND_RES_METADATA) Connection::result_meta_init() Sí, ¡pero se ha de llamar al padre! Result::read_result_metadata() Sentecia (MYSQLND_STMT) Connection::stmt_init() Sí, ¡pero se ha de llamar al padre! Connection::stmt_init() Red (MYSQLND_NET) mysqlnd_net_init() No Connection::init() Protocolo de cable (MYSQLND_PROTOCOL) mysqlnd_protocol_init() No Connection::init()
Se recomienda encarecidamente que no se reemplace completamente un constructor. Los constructores realizan asignaciones de memoria. Las asignaciones de memoria son vitales para la API de complementos de mysqlnd y la lógida de objetos de mysqlnd. Si no se tiene cuidado con las advertencias y se insiste en enganchar los constructores, se debería, al menos, llamar al constructor padre antes de hacer nada en el constructor derivado. A pesar de todas las advertencias, puede ser útil usar subclases para los constructores. Éstos son el lugar perfecto para modificar las tablas de funciones de objetos con tablas de objetos no compartidas, como Conjunto de resultados, Red, Protocolo de cable. Estado de la destrucción ¿Debe el método derivado llamar al padre? Destructor Conexión sí, después de la ejecución del método free_contents(), end_psession() Conjunto de resultados sí, después de la ejecución del método free_result() Metadatos del conjunto de resultados sí, después de la ejecución del método free() Sentencia sí, después de la ejecución del método dtor(), free_stmt_content() Red sí, después de la ejecución del método free() Protocolo de cable sí, después de la ejecución del método free()
Los destructores son los lugares apropiados para liberar propiedades mysqlnd_plugin_get_plugin_<objeto>_data(). Los destructores listados podrían no ser equivalentes a los métodos reales de mysqlnd que liberan el objeto en sí. Sin embargo, son el mejor lugar posible para enganchar y liberar los datos de los complementos. Como sucede con los constructores se pueden reemplazar los métodos completamente, pero no se recomienda. Si se listan múltiles métodos en la tabla de arriba, se necesitará enganchar todos esos métodos y liberar los datos del complemento en el método correspondiente que sea llamado primero por mysqlnd. El método recomendado para los complementos es simplemente enganchar los métodos, liberar la memoria y llamar a la implementación padre inmediatamente después de esto. Debido a un error en las versiones de PHP 5.3.0 hasta 5.3.3, los complementos no asocian los datos de los complementos con una conexión persistente. Esto es debido a que ext/mysql y ext/mysqli no desencadenan las llamadas necesarias al método end_psession() de mysqlnd, y el complemento podría, por lo tanto, perder memoria. Esto ha sido corregido en PHP 5.3.4.
La API de complementos de mysqlnd La siguiente es una lista de funciones proporcionadas en la API de complementos de 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() No existe una definción formal de lo que es un complemento y cómo funciona el mecanismo de un complemento. Los componentes que se encuentran a menudo en los mecanismos de los complementos son: Un gestor de complemento Una API de complemento Servicios de aplicación (o módulos) APIs de servicios de aplicación (o APIs de módulos) El concepto de complemento de mysqlnd emplea estas características, y además disgruta de una arquitectura abierta. Sin restricciones Un complemento tiene acceso completo al funcionamiento interno de mysqlnd. No existen límites de seguridad o restricciones. Todo puede ser sobrescrito para implementar algoritmos amistosos u hostiles. Se recomienda que se desplieguen complementos desde una fuente de confianza. Como se discutió anteriormente, los complementos puede usar punteros libremente. Estos punteros no están restringidos de ninguna manera, y pueden apuntar a los datos de otros complementos. Se puede usar una sencilla aritmética de índices para leer los datos de otros complementos. Se recomienda que se escriban complementos cooperativos, y que siempre se llame al método padre. Los complemento deberían siempre cooperar con mysqlnd. Cuestiones: un ejemplo de encadenamiento y cooperación Extensión puntero de mysqlnd.query() pila de llamdas si se llama al padre ext/mysqlnd mysqlnd.query() mysqlnd.query ext/mysqlnd_cache mysqlnd_cache.query() mysqlnd_cache.query() mysqlnd.query ext/mysqlnd_monitor mysqlnd_monitor.query() mysqlnd_monitor.query() mysqlnd_cache.query() mysqlnd.query
En este escenario, se cargan una caché (ext/mysqlnd_cache) y un complemento monitor (ext/mysqlnd_monitor). Ambos subclases de Connection::query(). El registro del complemento sucede en MINIT usando la lógica mostrada anteriormente. PHP llama a las extensiones en orden alfabético de manera predeterminada. Los complementos no son conscientes de los demás complementos y no establecen dependencias de extensiones. Por omisión, los complementos llaman a la implementación padre del método de consulta en sus versiones derivadas del método. Resumen de las extensiones de PHP Este es un resumen de lo que sucede cuando se usa un complemento de ejemplo, ext/mysqlnd_plugin, el cual expone la API de complementos en C de mysqlnd a PHP: Cualquier apliacación de MySQL de PHP intenta establecer una conexión con 192.168.2.29 La aplicación de PHP usará ext/mysql, ext/mysqli o PDO_MYSQL. Estas tres extensiones de MySQL de PHP utilizan mysqlnd para establecer la conexión con 192.168.2.29. Mysqlnd llama a sus método de conexión, los cuales han sido derivados por ext/mysqlnd_plugin. ext/mysqlnd_plugin llama al gancho del espacio de usuario proxy::connect() registrado por el usuario. El gancho del espacio de usuario cambia la IP de conexión del anfitrión de 192.168.2.29 a 127.0.0.1 y devuelve la conexión establecida por parent::connect(). ext/mysqlnd_plugin realiza el equivalente de parent::connect(127.0.0.1) llamando al método original de mysqlnd para establecer una conexión. ext/mysqlnd establece una conexión y devuelve a ext/mysqlnd_plugin. ext/mysqlnd_plugin devuelve también. Cualquiera que sea la extensión de MySQL de PHP que haya sido usada por la aplicación, ésta recibe una conexión a 127.0.0.1. La extensión de MySQL de PHP en sí devuelve a la aplicación de PHP. El círculo se cierra.
Empezar a construir un complemento de mysqlnd Es importante recordar que un complemento de mysqlnd es una extensión de PHP en sí mismo. El siguiente código muestra la estructura básica de la función MINIT que se usará en el típico complemento de mysqlnd: query = MYSQLND_METHOD(mysqlnd_plugin_conn, query); conn_m->connect = MYSQLND_METHOD(mysqlnd_plugin_conn, connect); } ]]> Análisis de tareas: de C al espacio de usuario Proceso: PHP: el usuario registra la llamada de retorno del complemento PHP: el usuario llama a cualquier API de MySQL de PHP para conectarse a MySQL C: ext/*mysql* llama al método de mysqlnd C: mysqlnd finaliza en ext/mysqlnd_plugin C: ext/mysqlnd_plugin Llama a la llamada de retorno del espacio de usuario O al método original de mysqlnd, si la llamada de retorno del espacio de usuario no está establecida Es necesario realizar lo siguiente: Escribir una clase "mysqlnd_plugin_connection" en C Aceptar y registrar el objeto proxy a través de "mysqlnd_plugin_set_conn_proxy()" Llamar a los métodos del proxy del espacio de usuario desde C (optimización - zend_interfaces.h) Se pueden llamar a los métodos del objeto del espacio de usuario usando call_user_function() o se puede operar a nivel cercano al Motor Zend y usar zend_call_method(). Optimización: llamar a los métodos desde C usando zend_call_method El siguiente trozo de código muestra el prototipo para la función zend_call_method, tomado de zend_interfaces.h. La API Zend solamente soporta dos argumentos. Se pueden necesitar más, por ejemplo: Para evitar este problema se necesitará realizar una copia de zend_call_method() y añadir la facilidad para parámetros adicionales. Se puede hacer esto creando un conjunto de macros MY_ZEND_CALL_METHOD_WRAPPER. Llamar al espacio de usuario de PHP Este trozo de código muestra el método optimizado para llamar a una función del espacio de usuario desde C: Llamar al espacio de usuario: argumentos simples Llamar al espacio de usuario: estrucutras como argumentos El primer argumento de la mayoría de los métodos de mysqlnd es un "objeto" de C. Por ejemplo, el primer argumento del método connect() es un puntero a MYSQLND. La estructura MYSQLND representa un objeto de conexión de mysqlnd. El puntero del objeto de conexión de mysqlnd puede ser comparado con un gestor de ficheros de E/S estándar. Al igual que un gestor de ficheros de E/S estándar, un objeto de conexión de mysqlnd será vinculado al espacio de usuario usando el tipo de variable de recurso de PHP. Desde C al espacio de usuario y volver Los usuario de PHP pueden llamar a la implementación padre de un método sobrescrito. Como resultado de la derivación, es posible refinar solamente los métodos seleccionados, y se puede optar por tener "pre" o "post" enganches. Contruir la clase: mysqlnd_plugin_connection::connect()