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 PHPVersión de PHPVersión del Controlador Nativo de MySQL5.3.05.0.55.3.15.0.55.3.25.0.75.3.35.0.75.3.45.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_IDVersión (parte)EjemploMayor*100005*10000 = 50000Menor*1000*100 = 0Parche7 = 7MYSQLND_VERSION_ID50007
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óduloMódulos de estadísticasmysqlnd_statistics.cConexiónmysqlnd.cConjunto de resultadosmysqlnd_result.cMetadatos de conjuntos de resultadosmysqlnd_result_meta.cSentenciamysqlnd_ps.cRedmysqlnd_net.cProtocolo de cablemysqlnd_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 mysqlndDirección de memoriaContenido0Inicio de la estructura de C del objeto mysqlndnFin de la estructura de C del objeto mysqlndn + (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)MINITNomysqlnd_conn_get_methods()Conjunto de resultados (MYSQLND_RES)MINIT o despuésSímysqlnd_result_get_methods() o manipulación de la tabla de funciones
de métodos de objetosMetadatos de conjunto de resultados (MYSQLND_RES_METADATA)MINITNomysqlnd_result_metadata_get_methods()Sentencia (MYSQLND_STMT)MINITNomysqlnd_stmt_get_methods()Red (MYSQLND_NET)MINIT o despuésSímysqlnd_net_get_methods() o manipulación de la tabla de funciones de métodos de objetosProtocolo de cable (MYSQLND_PROTOCOL)MINIT o despuésSí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 constructorAsignación, construcción, reinicio¿Se puede modificar?LlamadorConexión (MYSQLND)mysqlnd_init()Nomysqlnd_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()NoConnection::init()Protocolo de cable (MYSQLND_PROTOCOL)mysqlnd_protocol_init()NoConnection::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?DestructorConexiónsí, después de la ejecución del métodofree_contents(), end_psession()Conjunto de resultadossí, después de la ejecución del métodofree_result()Metadatos del conjunto de resultadossí, después de la ejecución del métodofree()Sentenciasí, después de la ejecución del métododtor(), free_stmt_content()Redsí, después de la ejecución del métodofree()Protocolo de cablesí, después de la ejecución del métodofree()
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ónExtensiónpuntero de mysqlnd.query()pila de llamdas si se llama al padreext/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
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()