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