Aquí se describe el funcionamiento de fondo e interno de la extensión mysqlnd_uh.
Se proporcionan dos clases con la extensión: MysqlndUhConnection
y MysqlndUhPreparedStatement. MysqlndUhConnection permite
acceder a casi todos los métodos de la clase interna connection
de mysqlnd
. La última expone algunos métodos
seleccionados de la clase interna statement
de mysqlnd
.
Por ejemplo, MysqlndUhConnection::connect() hace referencia
a la función mysqlnd_conn__connect
en C de la biblioteca
mysqlnd
.
Como complemento de mysqlnd, la extensión PECL/mysqlnd_uh reemplaza las funciones
de la biblioteca en C mysqlnd
con sus propias funciones. Siempre que una
extensión de MySQL para PHP compilada para usar mysqlnd
llame a
una función de mysqlnd, se ejecutarán las funciones instaladas por el complemento
en lugar de las originales de mysqlnd
. Por ejemplo,
mysqli_connect() invoca a mysqlnd_conn__connect
,
por lo que será llamada la función de conexión instaladas por PECL/mysqlnd_uh.
Las funciones instaladas por PECL/mysqlnd_uh son métodos de clases internas.
Las clases de PHP internas y sus métodos no hacen sino llamar a sus homólogos
de la biblioteca en C mysqlnd
, para comportarse exactamente
como la función original de mysqlnd
que sustituyen.
El código de abajo ilustra en pseudocódigo lo que hace la extensión.
Ejemplo #1 Pseudocódigo: qué hace la clase interna
class MysqlndUhConnection { public function connect(($conn, $host, $user, $passwd, $db, $port, $socket, $mysql_flags) { MYSQLND* c_mysqlnd_connection = convert_from_php_to_c($conn); ... return call_c_function(mysqlnd_conn__connect(c_mysqlnd_connection, ...)); } }
Las clases internas se comportan como un procy transparente. Es posible reemplazar dicho procy con uno propio. Esto se lleva a cabo derivando MysqlndUhConnection o MysqlndUhPreparedStatement para extender la funcionalidad del procy, y después registrando un nuevo objeto procy. Los objetos proxy se instalan con mysqlnd_uh_set_connection_proxy() y mysqlnd_uh_set_statement_proxy().
Ejemplo #2 Instalar un proxy
<?php
class proxy extends MysqlndUhConnection {
public function connect($res, $host, $user, $passwd, $db, $port, $socket, $mysql_flags) {
printf("%s(%s)\n", __METHOD__, var_export(func_get_args(), true));
$ret = parent::connect($res, $host, $user, $passwd, $db, $port, $socket, $mysql_flags);
printf("%s returns %s\n", __METHOD__, var_export($ret, true));
return $ret;
}
}
mysqlnd_uh_set_connection_proxy(new proxy());
$mysqli = new mysqli("localhost", "root", "", "test");
?>
El resultado del ejemplo sería:
proxy::connect(array ( 0 => NULL, 1 => 'localhost', 2 => 'root', 3 => '', 4 => 'test', 5 => 3306, 6 => NULL, 7 => 131072, )) proxy::connect returns true