Instalar un proxy

La extensión proporciona dos clases internas: MysqlndUhConnection y MysqlndUhPreparedStatement. Estas clases se usan para capturar las llamadas a la biblioteca mysqlnd. Sus métodos se corresponden con las funciones internas de mysqlnd. Por omisión, actúan como un proxy transparente y no hacen nada sino llamar a sus homólogos de mysqlnd. Al derivar estas clases se puede instalar un proxy propio para monitorizar mysqlnd.

Véase también la guía Cómo funciona para aprender sobre el funcionamiento interno de esta extensión.

Los delegados (proxy) de conexiones son objetos de tipo MysqlndUhConnection. Dichos objetos se instalan con mysqlnd_uh_set_connection_proxy(). Si se instala la clase interna MysqlndUhConnection como un proxy, no ocurre nada; se comporta como un delegado transparente.

Ejemplo #1 Registro del proxy, mysqlnd_uh.enable=1

<?php
mysqlnd_uh_set_connection_proxy
(new MysqlndUhConnection());
$mysqli = new mysqli("localhost""root""""test");
?>

La directiva de configuración de PHP_INI_SYSTEM mysqlnd_uh.enable controla si se puede establecer un proxy. Si está deshabilitada, la extensión lanzará errores de tipo E_WARNING

Ejemplo #2 La instalación del proxy deshabilitada

mysqlnd_uh.enable=0
<?php
mysqlnd_uh_set_connection_proxy
(new MysqlndUhConnection());
$mysqli = new mysqli("localhost""root""""test");
?>

El resultado del ejemplo sería:

PHP Warning:  MysqlndUhConnection::__construct(): (Mysqlnd User Handler) The plugin has been disabled by setting the configuration parameter mysqlnd_uh.enabled = false.  You must not use any of the base classes in %s on line %d
PHP Warning:  mysqlnd_uh_set_connection_proxy(): (Mysqlnd User Handler) The plugin has been disabled by setting the configuration parameter mysqlnd_uh.enable = false. The proxy has not been installed  in %s on line %d

Para monitorizar mysqlnd, se ha de escribir un objeto proxy propio derivando MysqlndUhConnection. Por favor, véase la referencia de la función para la lista de métodos que que se pueden derivar. De forma alternativa, se puede usar la reflexión para inspeccionar la clase interna MysqlndUhConnection.

Crear una nueva clase proxy. Derivarla de la clase interna MysqlndUhConnection. Reemplazar el método MysqlndUhConnection::connect(). Imprimir el valor del parámetro 'host' pasado al método. Asegurarse de que se llama a la implementación madre del método connect. No hacer todo esto podría proporcionar resultados inesperados y no deseados, incluyendo pérdidas de memoria y fallos.

Registrar el proxy y abrir tres conexiones usando las extensiones de MySQL para PHP mysqli, mysql, PDO_MYSQL. Si las extensiones han sido compiladas para usar la biblioteca mysqlnd, el método proxy::connect será llamado tres veces, una por cada conexión abierta.

Ejemplo #3 Proxy de conexión

<?php
class proxy extends MysqlndUhConnection {
  public function 
connect($res$host$user$passwd$db$port$socket$mysql_flags) {
   
printf("Conexión abierta con '%s'\n"$host);
   
/* ¡Llame siempre a la implementación madre! */
   
return parent::connect($res$host$user$passwd$db$port$socket$mysql_flags);
  }
}
mysqlnd_uh_set_connection_proxy(new proxy());

$mysqli = new mysqli("localhost""root""""test");
$mysql mysql_connect("localhost""root""");
$pdo = new PDO("mysql:host=localhost;dbname=test""root""");
?>

El resultado del ejemplo sería:

Conexión abierta con 'localhost'
Conexión abierta con 'localhost'
Conexión abierta con 'localhost'

El uso de delegados (proxy) de sentencias preparadas sigue el mismo patrón: crear un objeto proxy del tipo MysqlndUhPreparedStatement e instalar el proxy usando mysqlnd_uh_set_statement_proxy().

Ejemplo #4 Proxy de sentencia preparada

<?php
class stmt_proxy extends MysqlndUhPreparedStatement {
 public function 
prepare($res$query) {
  
printf("%s(%s)\n"__METHOD__$query);
  return 
parent::prepare($res$query);
 }
}
mysqlnd_uh_set_statement_proxy(new stmt_proxy());

$mysqli = new mysqli("localhost""root""""test");
$stmt $mysqli->prepare("SELECT 'mysqlnd hacking made easy' AS _msg FROM DUAL");
?>

El resultado del ejemplo sería:

stmt_proxy::prepare(SELECT 'mysqlnd hacking made easy' AS _msg FROM DUAL)