<?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 => 'it',
  ),
  'this' => 
  array (
    0 => 'mysqlnd.plugin.api.php',
    1 => 'The mysqlnd plugin API',
    2 => 'The mysqlnd plugin API',
  ),
  'up' => 
  array (
    0 => 'mysqlnd.plugin.php',
    1 => 'MySQL Native Driver Plugin API',
  ),
  'prev' => 
  array (
    0 => 'mysqlnd.plugin.architecture.php',
    1 => 'MySQL Native Driver Plugin Architecture',
  ),
  'next' => 
  array (
    0 => 'mysqlnd.plugin.developing.php',
    1 => 'Getting started building a mysqlnd plugin',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'en',
    '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">The mysqlnd plugin API</h2>
  <p class="simpara">
   The following is a list of functions provided in the
   <code class="literal">mysqlnd</code> plugin API:
  </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">
   There is no formal definition of what a plugin is and how a plugin
   mechanism works.
  </p>
  <p class="simpara">
   Components often found in plugins mechanisms are:
  </p>
  <ul class="itemizedlist">
   <li class="listitem">
    <span class="simpara">
     A plugin manager
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     A plugin API
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Application services (or modules)
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Application service APIs (or module APIs)
    </span>
   </li>
  </ul>
  <p class="simpara">
   The <code class="literal">mysqlnd</code> plugin concept employs these features,
   and additionally enjoys an open architecture.
  </p>
  <p class="simpara">
   <strong>No Restrictions</strong>
  </p>
  <p class="simpara">
   A plugin has full access to the inner workings of
   <code class="literal">mysqlnd</code>. There are no security limits or
   restrictions. Everything can be overwritten to implement friendly or
   hostile algorithms. It is recommended you only deploy plugins from a
   trusted source.
  </p>
  <p class="simpara">
   As discussed previously, plugins can use pointers freely. These
   pointers are not restricted in any way, and can point into another
   plugin&#039;s data. Simple offset arithmetic can be used to read another
   plugin&#039;s data.
  </p>
  <p class="simpara">
   It is recommended that you write cooperative plugins, and that you
   always call the parent method. The plugins should always cooperate
   with <code class="literal">mysqlnd</code> itself.
  </p>
  <table id="mysqlnd.plugin.chaining" class="doctable table">
   <caption><strong>Issues: an example of chaining and cooperation</strong></caption>
   
    <thead>
     <tr>
      <th>Extension</th>
      <th>mysqlnd.query() pointer</th>
      <th>call stack if calling parent</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">
   In this scenario, a cache (<code class="literal">ext/mysqlnd_cache</code>) and
   a monitor (<code class="literal">ext/mysqlnd_monitor</code>) plugin are loaded.
   Both subclass <code class="literal">Connection::query()</code>. Plugin
   registration happens at <code class="literal">MINIT</code> using the logic
   shown previously. PHP calls extensions in alphabetical order by
   default. Plugins are not aware of each other and do not set extension
   dependencies.
  </p>
  <p class="simpara">
   By default the plugins call the parent implementation of the query
   method in their derived version of the method.
  </p>
  <p class="simpara">
   <strong>PHP Extension Recap</strong>
  </p>
  <p class="simpara">
   This is a recap of what happens when using an example plugin,
   <code class="literal">ext/mysqlnd_plugin</code>, which exposes the
   <code class="literal">mysqlnd</code> C plugin API to PHP:
  </p>
  <ul class="itemizedlist">
   <li class="listitem">
    <span class="simpara">
     Any PHP MySQL application tries to establish a connection to
     192.168.2.29
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     The PHP application will either use <code class="literal">ext/mysql</code>,
     <code class="literal">ext/mysqli</code> or <code class="literal">PDO_MYSQL</code>. All
     three PHP MySQL extensions use <code class="literal">mysqlnd</code> to
     establish the connection to 192.168.2.29.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     <code class="literal">Mysqlnd</code> calls its connect method, which has been
     subclassed by <code class="literal">ext/mysqlnd_plugin</code>.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     <code class="literal">ext/mysqlnd_plugin</code> calls the userspace hook
     <code class="literal">proxy::connect()</code> registered by the user.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     The userspace hook changes the connection host IP from 192.168.2.29
     to 127.0.0.1 and returns the connection established by
     <code class="literal">parent::connect()</code>.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     <code class="literal">ext/mysqlnd_plugin</code> performs the equivalent of
     <code class="literal">parent::connect(127.0.0.1)</code> by calling the
     original <code class="literal">mysqlnd</code> method for establishing a
     connection.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     <code class="literal">ext/mysqlnd</code> establishes a connection and returns
     to <code class="literal">ext/mysqlnd_plugin</code>.
     <code class="literal">ext/mysqlnd_plugin</code> returns as well.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Whatever PHP MySQL extension had been used by the application, it
     receives a connection to 127.0.0.1. The PHP MySQL extension itself
     returns to the PHP application. The circle is closed.
    </span>
   </li>
  </ul>
 </div><?php manual_footer($setup); ?>