mysqlnd のプラグインAPI

mysqlndプラグインAPI で提供されている関数のリストを以下に示します:

  • mysqlnd_plugin_register()

  • mysqlnd_plugin_count()

  • mysqlnd_plugin_get_plugin_connection_data()

  • mysqlnd_plugin_get_plugin_result_data()

  • mysqlnd_plugin_get_plugin_stmt_data()

  • mysqlnd_plugin_get_plugin_net_data()

  • mysqlnd_plugin_get_plugin_protocol_data()

  • mysqlnd_conn_get_methods()

  • mysqlnd_result_get_methods()

  • mysqlnd_result_meta_get_methods()

  • mysqlnd_stmt_get_methods()

  • mysqlnd_net_get_methods()

  • mysqlnd_protocol_get_methods()

プラグインが何かとか、どのようにプラグインが機能するのか、という疑問に対する公式な定義はありません。

プラグインのメカニズムでよく見つかるコンポーネントは以下の通りです:

  • プラグインマネージャー

  • プラグインAPI

  • アプリケーションサービス(またはモジュール)

  • アプリケーションサービスAPI (またはモジュールAPI)

mysqlndプラグインのコンセプトにはこれらが取り入れられており、追加でオープンなアーキテクチャの恩恵を受けています。

mysqlnd の内部には無制限にアクセスできる

プラグインは mysqlnd の内部にすべてアクセスできます。セキュリティ上の限界や制限はありません。mysqlnd に親和性が高い、または不利なアルゴリズムを実装するためにすべてを置き換えることができます。よって、信頼できる配布元からのプラグインだけをデプロイすることを推奨します。

以前議論したとおり、プラグインはポインタを自由に使えます。これらのポインタはあらゆる点で制限されていないので、別のプラグインのデータを指すこともできます。簡単にオフセットを計算するだけで別のプラグインのデータを使うことができます。

mysqlnd と協調的なプラグインを書くこと、そして開発者はいつも親メソッドを呼び出すことを推奨します。プラグインはいつも mysqlnd と協調的であるべきです。

問題: 呼び出しの連鎖と協調の例
エクステンション mysqlnd.query() の関数ポインタ 親メソッドを呼んだ場合のコールスタック
ext/mysqlnd mysqlnd.query() mysqlnd.query
ext/mysqlnd_cache mysqlnd_cache.query()
  1. mysqlnd_cache.query()

  2. mysqlnd.query

ext/mysqlnd_monitor mysqlnd_monitor.query()
  1. mysqlnd_monitor.query()

  2. mysqlnd_cache.query()

  3. mysqlnd.query

このシナリオでは、キャッシュ(ext/mysqlnd_cache) と モニタ(ext/mysqlnd_monitor) プラグインが読み込まれています。両方とも Connection::query() を継承しています。プラグインの登録が 以前説明したロジックを使って MINIT(モジュール初期化) 時に発生します。PHP はエクステンションをデフォルトではアルファベット順に呼び出します。プラグインはお互いのことを知りませんし、エクステンションの依存性についても設定しません。

デフォルトで、プラグインは派生したメソッドの中で query メソッドの親クラスの実装を呼び出します。

PHP エクステンションの動きを再現する

サンプルのプラグイン ext/mysqlnd_plugin を使うと何が起こるかを以下で再現します。このプラグインは、mysqlnd の CプラグインAPI をPHPに公開しています。

  • PHP で書かれた MySQL アプリケーションが 192.168.2.29 に接続を確立しようとします。

  • PHP アプリケーションは ext/mysql, ext/mysqli または PDO_MYSQL のいずれかを使うでしょう。これら3つの PHP MySQL エクステンションは mysqlnd を使って 192.168.2.29 に接続を確立しようとします。

  • mysqlndext/mysqlnd_plugin を継承した自分自身の connect メソッドを呼び出します。

  • ext/mysqlnd_plugin は ユーザーが登録した ユーザースペースのフックである proxy::connect() を呼び出します。

  • ユーザースペースのフックは接続先のホストIPアドレスを 192.168.2.29 から 127.0.0.1 に書き換え、parent::connect() によって確立された接続を返します。

  • ext/mysqlnd_plugin は オリジナルの mysqlndのメソッドを接続を確立するために呼び出します。これによって、parent::connect(127.0.0.1) を実行するのと同じことをします。

  • ext/mysqlnd は、接続を確立し、ext/mysqlnd_plugin に接続を返します。ext/mysqlnd_plugin も同じことをします。

  • どんな PHP MySQL エクステンションをアプリケーションで使っていても、127.0.0.1 への接続を受け取ります。PHP MySQL エクステンションそれ自体は、PHPアプリケーションにそれを返し、実行は終了します。