Вызов PHP-скрипта из триггера MySQL



есть ли способ, как вызвать PHP-страницу / функцию, когда запись вставляется в таблицу базы данных MySQL? У нас нет контроля над процедурой вставки записей. Есть спусковой механизм, который может вызвать PHP-скрипт обратно?

949   10  

10 ответов:

триггер выполняется на сервере MySQL, а не на PHP (даже если они оба находятся на одной машине).

Итак, я бы сказал, что это не вполне возможно-по крайней мере, не просто.


Тем не менее, учитывая эта запись из MySQL FAQ по триггерам:

23.5.11: могут ли триггеры вызывать внешнее приложение через UDF?

да. Например, триггер может вызвать sys_exec() UDF доступно здесь: https://github.com/mysqludf/lib_mysqludf_sys#readme

таким образом, может быть способ с помощью функции UDF, которая запускает исполняемый файл/скрипт php. Не так просто, но кажется возможным. ; -)

друг и я выяснили, как назвать sys_eval UDF Бернардо Дамеле, но решение не так элегантно, как хотелось бы. Вот что мы сделали:

  1. так как мы используем Windows, нам пришлось скомпилировать библиотеку UDF для Windows с помощью инструкции Роланда Бумана и установить их на нашем сервере MySQL.
  2. мы создали хранимую процедуру, которая вызывает sys_eval.
  3. мы создали триггер, который вызывает хранимую процедура.

код хранимой процедуры:

DELIMITER $$
CREATE PROCEDURE udfwrapper_sp
(p1   DOUBLE,
 p2   DOUBLE,
 p3 BIGINT)
BEGIN
 DECLARE cmd CHAR(255);
 DECLARE result CHAR(255);
 SET cmd = CONCAT('C:/xampp/php/php.exe -f "C:/xampp/htdocs/phpFile.php" ', p1, ' ', p2, ' ', p3);
 SET result = sys_eval(cmd);
END$$;

триггер код:

CREATE TRIGGER udfwrapper_trigger AFTER INSERT ON sometable
FOR EACH ROW
CALL udfwrapper_sp(NEW.Column1, NEW.Column2, NEW.Column3);

Я не в восторге от наличия хранимой процедуры, и я не знаю, создает ли она дополнительные накладные расходы, но она работает. Каждый раз, когда строка добавляется в sometable, триггер.

Это следует считать очень плохая практика программирования для вызова PHP кода из триггера базы данных. Если вы объясните задачу, которую вы пытаетесь решить с помощью таких "безумных" трюков, мы могли бы обеспечить удовлетворительное решение.

добавлена 19.03.2014:

Я должен был добавить некоторые рассуждения раньше, но только нашел время, чтобы сделать это сейчас. Спасибо @cmc за важное замечание. Итак, PHP триггеры добавляют следующие сложности к вашим применение:

  • добавляет определенную степень проблем безопасности в приложение (внешние вызовы PHP-скриптов, настройка разрешений, возможно, настройка SELinux и т. д.), Как говорит @Johan.

  • добавляет дополнительный уровень сложности к вашему приложению (чтобы понять, как работает база данных, вам теперь нужно знать как SQL, так и PHP, а не только SQL), и вам придется отлаживать PHP, а не только SQL.

  • добавляет дополнительную точку отказа ваше приложение ( например, неправильная конфигурация PHP), которое также должно быть диагностировано (я думаю, что триггер должен содержать некоторый отладочный код, который будет регистрировать somwewhere все неуспешные вызовы интерпретатора PHP и их причины).

  • добавляет дополнительную точку анализа производительности. Каждый вызов PHP стоит дорого, так как вам нужно запустить интерпретатор, скомпилировать скрипт для байт-кода, выполнить его и т. д. Поэтому каждый запрос, связанный с этим триггером, будет выполняться медленнее. И иногда это будет трудно изолировать проблемы с производительностью запроса, так как EXPLAIN ничего не говорит вам о том, что запрос медленнее из-за производительности триггера. И я не уверен, как время триггера сбрасывается в медленный журнал запросов.

  • добавляет некоторые проблемы для тестирования приложений. SQL можно проверить довольно легко. Но чтобы проверить SQL + PHP триггеры, вам придется применить некоторые навыки.

Я нашел вот это:

http://forums.mysql.com/read.php?99,170973, 257815#msg-257815

DELIMITER $$
CREATE TRIGGER tg1 AFTER INSERT ON `test`
FOR EACH ROW
BEGIN
\! echo "php /foo.php" >> /tmp/yourlog.txt
END $$
DELIMITER ;

Я думал об этой точной проблеме для случая с длинным опросом, где я не хотел, чтобы PHP-скрипт постоянно опрашивал БД. Опрос должен быть сделан где-то, память, вероятно, будет лучше всего. Поэтому, если каким-то образом триггер может поместить информацию в нечто вроде memcache, то php может опросить, что было бы гораздо менее интенсивным в целом. Просто нужен метод для mysql, чтобы использовать memcache. Возможно, в предопределенную переменную с определенным идентификатором пользователя. Как только данные будут восстановленный php может сбросить var, пока БД не установит его снова. Не уверен в вопросах времени, хотя. Возможно, вторая переменная для хранения предыдущего выбранного ключа.

Если у вас есть журналы транзакций в MySQL, вы можете создать триггер для создания экземпляра журнала. Cronjob может отслеживать этот журнал и на основе событий, созданных вашим триггером, он может вызвать PHP-скрипт. То есть, если вы абсолютно не контролируете свою вставку.

чтобы получить уведомление из базы данных, я написал сценарий командной строки с помощью websocket для проверки последней обновленной метки времени каждую секунду. Это выполнялось как бесконечный цикл на сервере. Если есть изменения, все подключенные клиенты могут быть отправлены уведомление.

Я не знаю, возможно ли это, но я всегда представлял себе, что могу сделать это с помощью механизма хранения CSV в MySQL. Я не знаю деталей этого двигателя: http://dev.mysql.com/doc/refman/5.7/en/csv-storage-engine.html но вы можете заглянуть в него и иметь файловый наблюдатель в своей операционной системе, который запускает вызов PHP, если файл изменен.

cronjob может отслеживать этот журнал и на основе событий, созданных вашим триггером, он может вызвать PHP-скрипт. То есть, если вы абсолютно не контролируете свою вставку.. Если у вас есть журналы транзакций в MySQL, вы можете создать триггер для создания экземпляра журнала.

убегайте от процедур хранения как можно больше. Они довольно трудно поддерживать и очень старые вещи ;)

Comments

    Ничего не найдено.