繁体   English   中英

从MySQL触发器调用PHP脚本

[英]Invoking a PHP script from a MySQL trigger

将记录插入MySQL数据库表时,有没有办法调用PHP页面/函数? 我们无法控制记录插入过程。 是否有可以调用PHP脚本的触发器机制?

触发器在MySQL服务器上执行,而不是在PHP服务器上执行(即使它们都在同一台机器上)。

所以,我想说这不太可能 - 至少不是简单的。


考虑到MySQL触发器常见问题解答中的这一条目

23.5.11:触发器可以通过UDF调用外部应用程序吗?

是。 例如,触发器可以调用此处提供的sys_exec() UDF: https//github.com/mysqludf/lib_mysqludf_sys#readme

因此,可能有一种方法可以通过UDF函数启动php可执行文件/脚本。 不是那么容易,但似乎有可能。 ;-)

我和朋友已经想出如何调用Bernardo Damele的sys_eval UDF,但解决方案并不像我想的那样优雅。 这是我们做的:

  1. 由于我们使用的是Windows,因此我们必须使用Roland Bouman的说明为Windows编译UDF库,并将它们安装在我们的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);

我对使用存储过程并不感到兴奋,我不知道它是否会产生额外的开销,但它确实有效。 每次向某个表添加一行时,触发器都会触发。

从数据库触发器调用PHP代码应该被认为是一种非常糟糕的编程习惯 如果您将使用这种“疯狂”技巧解释您尝试解决的任务,我们可能会提供令人满意的解决方案。

新增19.03.2014:

我本来应该先加一些推理,但现在才有时间做这件事。 感谢@cmc的重要评论。 因此,PHP触发器为您的应用程序添加了以下复杂性:

  • 正如@Johan所说,向应用程序添加了一定程度的安全问题(外部PHP脚本调用,权限设置,可能是SELinux设置等)。

  • 为您的应用程序增加了额外的复杂程度(了解数据库如何工作,您现在需要知道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脚本不得不继续轮询数据库。 轮询需要在某个地方完成,内存可能是最好的。 因此,如果某种程度上触发器可以将信息放入像memcache这样的东西,那么php可以进行轮询,这将会大大减少整体密集度。 只需要一个mysql的方法来使用memcache。 也许进入具有特定用户ID的预定义变量。 一旦数据被检索,php就可以重置var,直到db再次设置它为止。 虽然不确定时间问题。 也许第二个变量用于存储选定的上一个键。

如果MySQL中有事务日志,则可以创建触发器以创建日志实例。 一个cronjob可以监视这个日志,并根据你的触发器创建的事件,它可以调用一个PHP脚本。 那就是如果你绝对无法控制你的插入。

为了从数据库获取通知,我使用websocket编写了一个命令行脚本,以检查每秒的最新更新时间戳。 这在服务器上作为无限循环运行。 如果有更改,则可以向所有连接的客户端发送通知。

我不知道是否可能,但我总是想象自己能够使用MySQL中的CSV存储引擎来做到这一点。 我不知道这个引擎的细节: http//dev.mysql.com/doc/refman/5.7/en/csv-storage-engine.html但你可以查看它并在你的操作中有一个文件监视器如果文件被修改则触发PHP调用的系统。

一个cronjob可以监视这个日志,并根据你的触发器创建的事件,它可以调用一个PHP脚本。 也就是说,如果您完全无法控制插入..如果MySQL中有事务日志,则可以创建触发器以创建日志实例。

尽可能远离商店程序。 他们很难维护,非常老了;)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM