Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

Триггер выполняется на сервере MySQL, а не на PHP (даже если они находятся на одном компьютере).

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


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

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

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

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

Ответ 2

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

  • Поскольку мы используем Windows, нам пришлось скомпилировать библиотеку UDF для Windows с помощью инструкций Roland Bouman и установить их на нашем сервере MySQL.
  • Мы создали хранимую процедуру, которая вызывает sys_eval.
  • Мы создали триггер, который вызывает хранимую процедуру.

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

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, срабатывает триггер.

Ответ 3

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

ДОБАВЛЕНО 19.03.2014:

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

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

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

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

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

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

Ответ 5

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

Ответ 6

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

Ответ 7

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

Ответ 8

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

Ответ 9

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

Ответ 10

Как можно больше убежать от процедур хранения. Их довольно сложно поддерживать и ОЧЕНЬ СТАРЫЙ СТУФЛ;)