## API плагинов mysqlnd

API-интерфейс плагинов `mysqlnd` поддерживает следующие функции:

- 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.query() | Стек вызова, если вызывается родитель
--- | --- | ---
ext/mysqlnd | mysqlnd.query() | mysqlnd.query
ext/mysqlnd_cache | mysqlnd_cache.query() | mysqlnd_cache.query() mysqlnd.query
ext/mysqlnd_monitor | mysqlnd_monitor.query() | mysqlnd_monitor.query() mysqlnd_cache.query() mysqlnd.query

В этом сценарии загружены плагины кеша (`ext/mysqlnd_cache`) и мониторинга (`ext/mysqlnd_monitor`). Оба наследуют класс `Connection::query()`. регистрация плагинов происходит на этапе `MINIT` в соответствии с описанной выше логикой. PHP, по умолчанию, вызывает модули в алфавитном порядке. Плагины не знают друг о друге и не накладывают каких-либо зависимостей.

По умолчанию, плагины вызывают родительский метод query из своей, переопределённой, версии этого метода.

Резюме по модулю PHP

Повторение пройденного материала на примере поведения плагина `ext/mysqlnd_plugin`, использующего API плагинов `mysqlnd` для PHP:

- Любое приложение PHP, использующее MySQL пытается установить соединение по адресу 192.168.2.29
- Приложение использует одно из следующих модулей `ext/mysql`, `ext/mysqli` или `PDO_MYSQL`. Все три модуля используют `mysqlnd` для соединения с 192.168.2.29.
- `Mysqlnd` вызывает метод соединения, который наследуется плагином `ext/mysqlnd_plugin`.
- `ext/mysqlnd_plugin` вызывает зарегистрированный пользователем метод `proxy::connect()`.
- Этот метод подменяет IP адрес соединения с 192.168.2.29 на 127.0.0.1 и возвращает установленное `parent::connect()` соединение.
- `ext/mysqlnd_plugin` делает то же самое, что и `parent::connect(127.0.0.1)`, вызывая оригинальный метод `mysqlnd` для соединения.
- `ext/mysqlnd` устанавливает соединение и возвращает его `ext/mysqlnd_plugin`. `ext/mysqlnd_plugin`, в свою очередь, передаёт его дальше.
- Без разницы, какой модуль был использован, он всё равно получит соединение к 127.0.0.1. После этого, модуль возвращает это соединение приложению. Круг замкнулся.

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open