La monitorización básica de una sentencia de consulta es sencilla con PECL/mysqlnd_uh. Combinada con debug_print_backtrace() puede convertirse en una poderosa herramienta, por ejemplo, para buscar el origen de ciertas sentencias. Esto podría ser necesario cuando se buscan consultas lentas y también después de la refactoriazación de una base de datos para buscar código que aún accede a bases de datos o tablas obsoletas. Esto último podría ser un asunto complicado, especialmente si la aplicación utiliza consultas autogeneradas.
Ejemplo #1 Monitorización básica
<?php
class conn_proxy extends MysqlndUhConnection {
public function query($res, $query) {
debug_print_backtrace();
return parent::query($res, $query);
}
}
class stmt_proxy extends MysqlndUhPreparedStatement {
public function prepare($res, $query) {
debug_print_backtrace();
return parent::prepare($res, $query);
}
}
mysqlnd_uh_set_connection_proxy(new conn_proxy());
mysqlnd_uh_set_statement_proxy(new stmt_proxy());
printf("Delegados instalados...\n");
$pdo = new PDO("mysql:host=localhost;dbname=test", "root", "");
var_dump($pdo->query("SELECT 1 AS _one FROM DUAL")->fetchAll(PDO::FETCH_ASSOC));
$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->prepare("SELECT 1 AS _two FROM DUAL");
?>
El resultado del ejemplo sería:
#0 conn_proxy->query(Resource id #19, SELECT 1 AS _one FROM DUAL) #1 PDO->query(SELECT 1 AS _one FROM DUAL) called at [example.php:19] array(1) { [0]=> array(1) { ["_one"]=> string(1) "1" } } #0 stmt_proxy->prepare(Resource id #753, SELECT 1 AS _two FROM DUAL) #1 mysqli->prepare(SELECT 1 AS _two FROM DUAL) called at [example.php:22]
Para la monitorización básica de consultas se debería instalar un proxy de conexión y otro de sentencias preparadas. El primero debería derivar de MysqlndUhConnection::query(). Todas las consultas de una base de datos que no utilicen sentencias preparadas nativas llamarán a este método. En el ejemplo, la función query es invocada por una llamada a PDO. Por omisión, PDO_MySQL utiliza la emulación de sentencias preparadas.
Todas las sentencias preparadas nativas se preparan con con el método prepare de mysqlnd exportado a través de MysqlndUhPreparedStatement::prepare(). Se ha de derivar MysqlndUhPreparedStatement y sobrescribir prepare para monitorizar sentencias preparadas nativas.