Spec-Zone .ru
спецификации, руководства, описания, API

21.9.8.4. Быстрый запуск и Примеры

Copyright 1997-2012 PHP Documentation Group.

mysqlnd пользовательский плагин обработчика может быть понят как клиентский прокси для всех расширений MySQL PHP (mysqli, mysql, PDO_MYSQL), если они компилируются, чтобы пользоваться mysqlnd библиотекой. Расширения используют mysqlnd библиотека внутренне, на уровне C, чтобы связаться с сервером MySQL. PECL/mysqlnd_uh позволяет этому сцеплять многих mysqlnd вызовы. Поэтому, большинство действий расширений MySQL PHP может контролироваться.

Поскольку контроль происходит на уровне библиотеки в уровне ниже приложения, возможно контролировать приложения, не изменяя их.

На уровне C, mysqlnd библиотека структурируется в модулях или классах. Расширение сцепляет почти все методы mysqlnd внутренний connection class и представляет их через пространство пользователя class MysqlndUhConnection. Несколько методов mysqlnd внутреннего statement class делается доступным для пользователя PHP с class MysqlndUhPreparedStatement. Разделяя классы на подклассы MysqlndUhConnection и MysqlndUhPreparedStatement пользователи получают доступ к mysqlnd внутренние вызовы функции.

Отметить

Внутреннее mysqlnd вызовы функции не разрабатываются, чтобы быть представленными пользователю PHP. Управление их действиями может заставить PHP разрушать или пропускать память. Часто, это не считают ошибкой. Пожалуйста, имейте в виду, что Вы получаете доступ к библиотечным функциям C через PHP, которые, как ожидают, возьмут определенные действия, которые Вы не можете быть в состоянии эмулировать в пространстве пользователя. Поэтому, строго рекомендуется всегда вызвать родительскую реализацию метода, разделяя на подклассы MysqlndUhConnection или MysqlndUhPreparedStatement. Чтобы предотвратить худший случай, расширение выполняет некоторые проверки работоспособности. Пожалуйста, см. также, что Mysqlnd_uh Конфигурирует Опции.

21.9.8.4.1. Установка

Copyright 1997-2012 PHP Documentation Group.

Плагин реализуется как расширение PHP. См. инструкции по установке, чтобы установить расширение PECL/mysqlnd_uh. Затем, загрузите расширение в PHP и активируйте плагин в конфигурационном файле PHP, используя конфигурационную директиву PHP, названную mysqlnd_uh.enable. Ниже примера показывает настройки по умолчанию расширения.

Пример 21.332. Включение плагину (php.ini)

mysqlnd_uh.enable=1mysqlnd_uh.report_wrong_types=1

21.9.8.4.2. Как это работает

Copyright 1997-2012 PHP Documentation Group.

Это описывает фоновые и внутренние работы mysqlnd_uh расширения.

Два класса обеспечиваются расширением: MysqlndUhConnection и MysqlndUhPreparedStatement. MysqlndUhConnection позволяет Вам доступ почти все методы mysqlnd внутренний connection class. Последний представляет некоторые выбранные методы mysqlnd внутренний statement class. Например, MysqlndUhConnection::connect карты к mysqlnd библиотека C функция mysqlnd_conn__connect.

Как mysqlnd плагин, замены расширения PECL/mysqlnd_uh mysqlnd библиотека C функционирует с ее собственными функциями. Всякий раз, когда расширение MySQL PHP, скомпилированное в использование mysqlnd вызывает mysqlnd функцию, функции, установленные плагином, выполняются вместо оригинала mysqlnd . Например, mysqli_connect вызывает mysqlnd_conn__connect, таким образом, соединить функция, установленная PECL/mysqlnd_uh, будет вызвана. Функции, установленные PECL/mysqlnd_uh, являются методами встроенных классов.

Встроенные классы PHP и их методы действительно только вызывают их mysqlnd C дубликаты библиотеки, чтобы вести себя точно как оригинал mysqlnd функционируйте они заменяют. Код ниже иллюстрирует в псевдокоде, что делает расширение.

Пример 21.333. Псевдокод: какой встроенный class делает

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, ...));  }}

Создавание - в классах ведет себя как прозрачный прокси. Для Вас возможно заменить прокси Вашим собственным. Это делается, разделяя на подклассы MysqlndUhConnection или MysqlndUhPreparedStatement расширять функциональность прокси, сопровождаемого, регистрируя новый объект прокси. Объекты прокси устанавливаются mysqlnd_uh_set_connection_proxy и mysqlnd_uh_set_statement_proxy.

Пример 21.334. Установка прокси

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

Вышеупомянутый пример выведет:

proxy::connect(array (  0 => NULL,  1 => 'localhost',  2 => 'root',  3 => '',  4 => 'test',  5 => 3306,  6 => NULL,  7 => 131072,))proxy::connect returns true

21.9.8.4.3. Установка прокси

Copyright 1997-2012 PHP Documentation Group.

Расширение обеспечивает два встроенных класса: MysqlndUhConnection и MysqlndUhPreparedStatement. Классы используются для того, чтобы сцепиться mysqlnd вызовы библиотеки. Их методы соответствуют mysqlnd внутренние функции. По умолчанию они действуют как прозрачный прокси и действительно только вызывают их mysqlnd дубликаты. Разделяя классы на подклассы можно установить свой собственный прокси, чтобы контролировать mysqlnd.

См. также, Как это работает руководство, чтобы узнать о внутренних работах этого расширения.

Прокси соединения являются объектами типа MysqlndUhConnection. Объекты прокси соединения устанавливаются mysqlnd_uh_set_connection_proxy. Если Вы устанавливаете встроенный class MysqlndUhConnection как прокси, ничто не происходит. Это ведет себя как прозрачный прокси.

Пример 21.335. Регистрация прокси, mysqlnd_uh.enable=1

<?phpmysqlnd_uh_set_connection_proxy(new MysqlndUhConnection());$mysqli = new mysqli("localhost", "root", "", "test");?>

PHP_INI_SYSTEM параметр конфигурации mysqlnd_uh.enable средства управления, может ли прокси быть установлен. Если отключено, расширение бросит ошибки типа E_WARNING

Пример 21.336. Установка прокси отключается

mysqlnd_uh.enable=0    
<?phpmysqlnd_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 %dPHP 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

Контролировать mysqlnd, необходимо записать свое собственное разделение на подклассы объекта прокси MysqlndUhConnection. Пожалуйста, см. функциональную ссылку для список методов, которые могут быть разделены на подклассы. Альтернативно, можно использовать отражение, чтобы осмотреть встроенное MysqlndUhConnection.

Создайте новый class proxy. Получите это из встроенного class MysqlndUhConnection. Замените MysqlndUhConnection::connect. метод. Распечатайте значение параметра узла, которое передают к методу. Удостоверьтесь, что Вы вызываете родительскую реализацию connect метод. Сбой сделать так может дать неожиданные и нежелательные результаты, включая утечки памяти и катастрофические отказы.

Зарегистрируйте свой прокси и откройте три соединения, используя расширения MySQL PHP mysqli, mysql, PDO_MYSQL. Если расширения были скомпилированы в использование mysqlnd библиотека, proxy::connect метод вызовут три раза, однажды для каждого открытого соединения.

Пример 21.337. Прокси соединения

<?phpclass proxy extends MysqlndUhConnection {  public function connect($res, $host, $user, $passwd, $db, $port, $socket, $mysql_flags) {   printf("Connection opened to '%s'\n", $host);   /* Always call the parent implementation! */   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'

Использование готовых прокси оператора следует за тем же самым образцом: создайте объект прокси типа MysqlndUhPreparedStatement и установите использование прокси mysqlnd_uh_set_statement_proxy.

Пример 21.338. Готовый прокси оператора

<?phpclass 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)

21.9.8.4.4. Основной контроль запроса

Copyright 1997-2012 PHP Documentation Group.

Основной контроль оператора запроса легок с PECL/mysqlnd_uh. Объединенный с debug_print_backtrace это может стать мощным инструментом, например, чтобы найти источник определенного оператора. Это может требоваться, ища медленные запросы, но также и после перефакторинга базы данных, чтобы найти код, все еще получающий доступ к осуждаемым базам данных или таблицам. Последний может быть сложным вопросом, чтобы сделать иначе, особенно если использование приложения автоматически сгенерированные запросы.

Пример 21.339. Основной Контроль

<?phpclass 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("Proxies installed...\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");?>    

Вышеупомянутый пример выведет:

#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]

Для основного запроса, контролирующего Вас, должен установить соединение и готовый прокси оператора. Прокси соединения должен разделить на подклассы MysqlndUhConnection::query. Все запросы базы данных, не используя собственные готовые операторы вызовут этот метод. В примере query функция вызывается вызовом PDO. По умолчанию, PDO_MySQL использует подготовленную эмуляцию оператора.

Все собственные готовые операторы готовятся с prepare метод mysqlnd экспортируемый через MysqlndUhPreparedStatement::prepare. Подкласс MysqlndUhPreparedStatement и перезапись prepare для собственного готового контроля оператора.