Cómo funciona

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($rettrue));
   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