<?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 => 'de',
  ),
  'this' => 
  array (
    0 => 'mysqlnd.plugin.api.php',
    1 => 'Die Plugin-API von mysqlnd',
    2 => 'Die Plugin-API von mysqlnd',
  ),
  'up' => 
  array (
    0 => 'mysqlnd.plugin.php',
    1 => 'Plugin-API des MySQL Native Drivers',
  ),
  'prev' => 
  array (
    0 => 'mysqlnd.plugin.architecture.php',
    1 => 'Plugin-Architektur des MySQL Native Drivers',
  ),
  'next' => 
  array (
    0 => 'mysqlnd.plugin.developing.php',
    1 => 'Einf&uuml;hrung in die Erstellung eines mysqlnd-Plugins',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'de',
    '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">Die Plugin-API von mysqlnd</h2>
  <p class="simpara">
   Es folgt eine Liste der Funktionen, die in der Plugin-API von
   <code class="literal">mysqlnd</code> zur Verfügung stehen:
  </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">
   Es gibt keine formale Definition dafür, was ein Plugin ist und wie ein
   Plugin-Mechanismus funktioniert.
  </p>
  <p class="simpara">
   Folgende Komponenten werden häufig in Plugin-Mechanismen verwendet:
  </p>
  <ul class="itemizedlist">
   <li class="listitem">
    <span class="simpara">
     Ein Plugin-Manager
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Eine Plugin-API
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Anwendungsdienste (oder Module)
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Anwendungsdienst-APIs (oder Modul-APIs)
    </span>
   </li>
  </ul>
  <p class="simpara">
   Das Plugin-Konzept von <code class="literal">mysqlnd</code> nutzt diese Merkmale und
   zeichnet sich zudem durch eine offene Architektur aus.
  </p>
  <p class="simpara">
   <strong>Keine Einschränkungen</strong>
  </p>
  <p class="simpara">
   Ein Plugin hat uneingeschränkten Zugriff auf die inneren Abläufe von
   <code class="literal">mysqlnd</code>. Es gibt keine Sicherheitsbeschränkungen oder
   Einschränkungen. Alles kann überschrieben werden, um nützliche oder
   schädliche Algorithmen zu implementieren. Es wird empfohlen, nur Plugins
   aus einer vertrauenswürdigen Quelle einzusetzen.
  </p>
  <p class="simpara">
   Wie bereits erwähnt, können Plugins Zeiger beliebig verwenden. Diese Zeiger
   sind in keiner Weise eingeschränkt und können auf die Daten eines anderen
   Plugins zeigen. Mit einer einfachen Offset-Berechnung können die Daten
   eines anderen Plugins gelesen werden.
  </p>
  <p class="simpara">
   Es wird empfohlen, kooperative Plugins zu schreiben und immer die
   Elternmethode aufzurufen. Die Plugins sollten immer mit
   <code class="literal">mysqlnd</code> selbst zusammenarbeiten.
  </p>
  <table id="mysqlnd.plugin.chaining" class="doctable table">
   <caption><strong>Zum Thema: Ein Beispiel für Verkettung und Kooperation</strong></caption>
   
    <thead>
     <tr>
      <th>Erweiterung</th>
      <th>mysqlnd.query()-Zeiger</th>
      <th>Aufrufstapel (Call Stack) bei Aufruf der Elternmethode</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 diesem Szenario werden ein Cache-Plugin
   (<code class="literal">ext/mysqlnd_cache</code>) und ein Überwachungs-Plugin
   (<code class="literal">ext/mysqlnd_monitor</code>) geladen. Beide sind Unterklassen
   von <code class="literal">Connection::query()</code>. Die Registrierung der Plugins
   erfolgt während <code class="literal">MINIT</code> gemäß der zuvor gezeigten Logik.
   PHP ruft Erweiterungen standardmäßig in alphabetischer Reihenfolge auf. Die
   Plugins wissen nichts voneinander und definieren keine Abhängigkeiten von
   den Erweiterungen.
  </p>
  <p class="simpara">
   Standardmäßig rufen die Plugins die übergeordnete Implementierung der
   Abfragemethode in ihrer abgeleiteten Version der Methode auf.
  </p>
  <p class="simpara">
   <strong>Zusammenfassung des Verhaltens einer PHP-Erweiterung</strong>
  </p>
  <p class="simpara">
   Die folgende Zusammenfassung zeigt, was passiert, wenn das Beispiel-Plugin
   <code class="literal">ext/mysqlnd_plugin</code> verwendet wird, das die C-Plugin-API
   von <code class="literal">mysqlnd</code> für PHP verfügbar macht:
  </p>
  <ul class="itemizedlist">
   <li class="listitem">
    <span class="simpara">
     Jede PHP-Anwendung, die MySQL verwendet, versucht, eine Verbindung zu
     192.168.2.29 herzustellen
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Die PHP-Anwendung verwendet entweder <code class="literal">ext/mysql</code>,
     <code class="literal">ext/mysqli</code> oder <code class="literal">PDO_MYSQL</code>. Alle
     drei PHP-MySQL-Erweiterungen verwenden <code class="literal">mysqlnd</code>, um die
     Verbindung zu 192.168.2.29 herzustellen.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     <code class="literal">Mysqlnd</code> ruft seine Verbindungsmethode auf, die von
     <code class="literal">ext/mysqlnd_plugin</code> abgeleitet wurde.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     <code class="literal">ext/mysqlnd_plugin</code> ruft den vom Benutzer registrierten
     Userspace-Hook, die Methode <code class="literal">proxy::connect()</code>, auf.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Dieser Userspace-Hook ändert die IP-Adresse des Hosts, zu dem eine
     Verbindung aufgebaut werden soll, von 192.168.2.29 auf 127.0.0.1 und gibt
     die von <code class="literal">parent::connect()</code> hergestellte Verbindung
     zurück.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     <code class="literal">ext/mysqlnd_plugin</code> bewirkt dasselbe wie
     <code class="literal">parent::connect(127.0.0.1)</code>, indem es die ursprüngliche
     <code class="literal">mysqlnd</code>-Methode aufruft, um eine Verbindung
     herzustellen.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
    <code class="literal">ext/mysqlnd</code> stellt die Verbindung her und gibt sie
    an <code class="literal">ext/mysqlnd_plugin</code> zurück, das sie seinerseits
    zurückgibt.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Unabhängig davon, welche PHP-MySQL-Erweiterung die Anwendung verwendet,
     erhält sie eine Verbindung zu 127.0.0.1. Die PHP-MySQL-Erweiterung
     übergibt die Kontrolle wieder an die PHP-Anwendung. Der Zyklus ist
     geschlossen.
    </span>
   </li>
  </ul>
 </div><?php manual_footer($setup); ?>