文字

Installing a proxy

The extension provides two built-in classes: MysqlndUhConnection and MysqlndUhPreparedStatement. The classes are used for hooking mysqlnd library calls. Their methods correspond to mysqlnd internal functions. By default they act like a transparent proxy and do nothing but call their mysqlnd counterparts. By subclassing the classes you can install your own proxy to monitor mysqlnd.

See also the How it works guide to learn about the inner workings of this extension.

Connection proxies are objects of the type MysqlndUhConnection. Connection proxy objects are installed by mysqlnd_uh_set_connection_proxy() . If you install the built-in class MysqlndUhConnection as a proxy, nothing happens. It behaves like a transparent proxy.

Example #1 Proxy registration, mysqlnd_uh.enable=1

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

The PHP_INI_SYSTEM configuration setting mysqlnd_uh.enable controls whether a proxy may be set. If disabled, the extension will throw errors of type E_WARNING

Example #2 Proxy installation disabled

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

以上例程会输出:

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

To monitor mysqlnd, you have to write your own proxy object subclassing MysqlndUhConnection. Please, see the function reference for a the list of methods that can be subclassed. Alternatively, you can use reflection to inspect the built-in MysqlndUhConnection.

Create a new class proxy. Derive it from the built-in class MysqlndUhConnection. Replace the MysqlndUhConnection::connect() . method. Print out the host parameter value passed to the method. Make sure that you call the parent implementation of the connect method. Failing to do so may give unexpected and undesired results, including memory leaks and crashes.

Register your proxy and open three connections using the PHP MySQL extensions mysqli, mysql, PDO_MYSQL. If the extensions have been compiled to use the mysqlnd library, the proxy::connect method will be called three times, once for each connection opened.

Example #3 Connection proxy

<?php
class  proxy  extends  MysqlndUhConnection  {
  public function 
connect ( $res $host $user $passwd $db $port $socket $mysql_flags ) {
   
printf ( "Connection opened to '%s'\n" $host );
   

   
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" "" );
?>

以上例程会输出:

Connection opened to 'localhost'
Connection opened to 'localhost'
Connection opened to 'localhost'

The use of prepared statement proxies follows the same pattern: create a proxy object of the type MysqlndUhPreparedStatement and install the proxy using mysqlnd_uh_set_statement_proxy() .

Example #4 Prepared statement proxy

<?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" );
?>

以上例程会输出:

stmt_proxy::prepare(SELECT 'mysqlnd hacking made easy' AS _msg FROM DUAL)
上一篇: 下一篇: