<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/mysqlnd.plugin.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ru',
  ),
  'this' => 
  array (
    0 => 'mysqlnd.plugin.api.php',
    1 => 'API плагинов mysqlnd',
    2 => 'API плагинов mysqlnd',
  ),
  'up' => 
  array (
    0 => 'mysqlnd.plugin.php',
    1 => 'API интеграции плагинов в драйвер MySQL Native Driver',
  ),
  'prev' => 
  array (
    0 => 'mysqlnd.plugin.architecture.php',
    1 => 'Архитектура плагинов MySQL Native Driver',
  ),
  'next' => 
  array (
    0 => 'mysqlnd.plugin.developing.php',
    1 => 'Начинаем разработку плагина mysqlnd',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ru',
    'path' => 'reference/mysqlnd/plugin.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="mysqlnd.plugin.api" class="section">
  <h2 class="title">API плагинов mysqlnd</h2>
  <p class="simpara">
   API-интерфейс плагинов <code class="literal">mysqlnd</code> поддерживает следующие функции:
  </p>
  <ul class="itemizedlist">
   <li class="listitem">
    <span class="simpara">
     mysqlnd_plugin_register()
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     mysqlnd_plugin_count()
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     mysqlnd_plugin_get_plugin_connection_data()
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     mysqlnd_plugin_get_plugin_result_data()
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     mysqlnd_plugin_get_plugin_stmt_data()
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     mysqlnd_plugin_get_plugin_net_data()
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     mysqlnd_plugin_get_plugin_protocol_data()
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     mysqlnd_conn_get_methods()
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     mysqlnd_result_get_methods()
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     mysqlnd_result_meta_get_methods()
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     mysqlnd_stmt_get_methods()
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     mysqlnd_net_get_methods()
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     mysqlnd_protocol_get_methods()
    </span>
   </li>
  </ul>
  <p class="simpara">
   Нет стандартных определений того, что такое плагин и как он работает.
  </p>
  <p class="simpara">
   Часто встречающиеся в плагинах компоненты:
  </p>
  <ul class="itemizedlist">
   <li class="listitem">
    <span class="simpara">
     Менеджер плагина
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     API плагина
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Сервисы приложения (или модули)
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     API сервисов приложения (или API модулей)
    </span>
   </li>
  </ul>
  <p class="simpara">
   Концепция плагина <code class="literal">mysqlnd</code> эксплуатирует эту функциональность и,
   кроме того, радует нас открытой архитектурой.
  </p>
  <p class="simpara">
   <strong>Нет запретов </strong>
  </p>
  <p class="simpara">
   Плагин имеет полный доступ ко всем внутренностям <code class="literal">mysqlnd</code>.
   Нет ограничений или запретов, связанных с безопасностью. Все что угодно можно
   переписать для реализации дружественных или враждебных алгоритмов, так что
   рекомендуется ставить плагины только из доверенных источников.
  </p>
  <p class="simpara">
   Как обсуждалось выше, плагины могут свободно использовать указатели. Эти указатели
   ничем не ограничены и могут указывать на данные другого плагина. Простейшая
   арифметическая операция позволит получить доступ к данным другого плагина.
  </p>
  <p class="simpara">
   Рекомендуется писать сотрудничающие плагины, которые могут работать сообща с другими
   плагинами и всегда вызывать родительские методы. Плагины никогда не должны вести себя
   враждебно к самому <code class="literal">mysqlnd</code>.
  </p>
  <table id="mysqlnd.plugin.chaining" class="doctable table">
   <caption><strong>Проблемы: пример сотрудничества и построения цепочки</strong></caption>
   
    <thead>
     <tr>
      <th>Модуль</th>
      <th>Указатель mysqlnd.query()</th>
      <th>Стек вызова, если вызывается родитель</th>
     </tr>

    </thead>

    <tbody class="tbody">
     <tr>
      <td>ext/mysqlnd</td>
      <td>mysqlnd.query()</td>
      <td>mysqlnd.query</td>
     </tr>

     <tr>
      <td>ext/mysqlnd_cache</td>
      <td>mysqlnd_cache.query()</td>
      <td><ol type="1">
       <li class="listitem">
        <span class="simpara">
         mysqlnd_cache.query()
        </span>
       </li>
       <li class="listitem">
        <span class="simpara">
         mysqlnd.query
        </span>
       </li>
       </ol></td>
     </tr>

     <tr>
      <td>ext/mysqlnd_monitor</td>
      <td>mysqlnd_monitor.query()</td>
      <td><ol type="1">
       <li class="listitem">
        <span class="simpara">
         mysqlnd_monitor.query()
        </span>
       </li>
       <li class="listitem">
        <span class="simpara">
         mysqlnd_cache.query()
        </span>
       </li>
       <li class="listitem">
        <span class="simpara">
         mysqlnd.query
        </span>
       </li>
       </ol></td>
     </tr>

    </tbody>
   
  </table>

  <p class="simpara">
   В этом сценарии загружены плагины кеша (<code class="literal">ext/mysqlnd_cache</code>) и
   мониторинга (<code class="literal">ext/mysqlnd_monitor</code>).
   Оба наследуют класс <code class="literal">Connection::query()</code>. регистрация плагинов
   происходит на этапе <code class="literal">MINIT</code> в соответствии с описанной
   выше логикой. PHP, по умолчанию, вызывает модули в алфавитном порядке.
   Плагины не знают друг о друге и не накладывают каких-либо зависимостей.
  </p>
  <p class="simpara">
   По умолчанию, плагины вызывают родительский метод query из своей, переопределённой,
   версии этого метода.
  </p>
  <p class="simpara">
   <strong>Резюме по модулю PHP</strong>
  </p>
  <p class="simpara">
   Повторение пройденного материала на примере поведения плагина
   <code class="literal">ext/mysqlnd_plugin</code>, использующего API плагинов
   <code class="literal">mysqlnd</code> для PHP:
  </p>
  <ul class="itemizedlist">
   <li class="listitem">
    <span class="simpara">
     Любое приложение PHP, использующее MySQL пытается установить соединение по
     адресу 192.168.2.29
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Приложение использует одно из следующих модулей <code class="literal">ext/mysql</code>,
     <code class="literal">ext/mysqli</code> или <code class="literal">PDO_MYSQL</code>. Все
     три модуля используют <code class="literal">mysqlnd</code> для соединения с 192.168.2.29.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     <code class="literal">Mysqlnd</code> вызывает метод соединения, который наследуется
     плагином <code class="literal">ext/mysqlnd_plugin</code>.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     <code class="literal">ext/mysqlnd_plugin</code> вызывает зарегистрированный
     пользователем метод <code class="literal">proxy::connect()</code>.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Этот метод подменяет IP адрес соединения с 192.168.2.29
     на 127.0.0.1 и возвращает установленное <code class="literal">parent::connect()</code> соединение.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     <code class="literal">ext/mysqlnd_plugin</code> делает то же самое, что и
     <code class="literal">parent::connect(127.0.0.1)</code>, вызывая оригинальный метод
     <code class="literal">mysqlnd</code> для соединения.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     <code class="literal">ext/mysqlnd</code> устанавливает соединение и возвращает его
     <code class="literal">ext/mysqlnd_plugin</code>.
     <code class="literal">ext/mysqlnd_plugin</code>, в свою очередь, передаёт его дальше.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Без разницы, какой модуль был использован, он всё равно получит
     соединение к 127.0.0.1. После этого, модуль возвращает это соединение
     приложению. Круг замкнулся.
    </span>
   </li>
  </ul>
 </div><?php manual_footer($setup); ?>