Есть ли способ вызвать страницу / функцию PHP, когда запись вставлена в таблицу базы данных MySQL? У нас нет контроля над процедурой ввода записей. Есть триггерный механизм, который может вызвать PHP-скрипт?
Триггер выполняется на сервере MySQL, а не на PHP (даже если они оба находятся на одной машине).
Поэтому я бы сказал, что это не совсем возможно – по крайней мере, не просто.
Тем не менее, учитывая эту запись из MySQL FAQ о триггерах :
23.5.11: Может ли триггер вызвать внешнее приложение через UDF?
Да. Например, триггер может ссылаться на
sys_exec()
UDF, доступный здесь: https://github.com/mysqludf/lib_mysqludf_sys#readme
Таким образом, может существовать способ через функцию UDF, которая запускает исполняемый файл / скрипт php. Не так просто, но кажется возможным. 😉
Мы с другом выяснили, как назвать Sys_eval UDF Бернардо Дамела, но решение не так элегантно, как хотелось бы. Вот что мы сделали:
Код хранимой процедуры:
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), которая также должна быть диагностирована (я думаю, что триггер должен содержать некоторый код отладки, который будет записывать где-нибудь все неуспешные вызовы 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-скрипт должен постоянно опробовать db. Опрос нужно было бы сделать где-то, память, вероятно, была бы лучше. Поэтому, если какой-то триггер может помещать информацию в нечто вроде memcache, то php мог бы опросить, что было бы намного менее интенсивным в целом. Просто нужен метод mysql для использования memcache. Возможно, в предопределенную переменную с определенным идентификатором пользователя. Как только данные будут восстановлены, php может сбросить значение var до тех пор, пока db не установит его снова. Однако не уверены в сроках. Возможно, вторая переменная для сохранения предыдущего выбранного ключа.
Если в вашем MySQL есть журналы транзакций, вы можете создать триггер для создания экземпляра журнала. Cronjob может контролировать этот журнал и на основе событий, созданных вашим триггером, может вызвать скрипт php. То есть, если вы абсолютно не имеете контроля над вставкой.
Чтобы получить уведомление из базы данных, я написал сценарий командной строки, используя websocket, чтобы проверять последнюю обновленную временную метку каждую секунду. Это выполнялось как бесконечный цикл на сервере. Если есть изменение, все подключенные клиенты могут отправить уведомление.
Я не знаю, возможно ли это, но я всегда представлял себе возможность сделать это с помощью механизма хранения CSV в MySQL. Я не знаю подробностей этого движка: http://dev.mysql.com/doc/refman/5.7/en/csv-storage-engine.html, но вы можете изучить его и иметь наблюдателя файлов в своей операционной система, которая запускает вызов PHP, если файл изменен.
Cronjob может контролировать этот журнал и на основе событий, созданных вашим триггером, может вызвать скрипт php. То есть, если вы абсолютно не имеете контроля над вставкой. Если у вас есть журналы транзакций в вашем MySQL, вы можете создать триггер для создания экземпляра журнала.
Как можно больше убежать от процедур магазина. Их довольно сложно поддерживать и ОЧЕНЬ СТАРЫЙ СТУФ;)