从MySQL触发器调用PHP脚本

Shy*_*yju 60 php mysql triggers

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

Pas*_*TIN 33

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

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


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

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

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

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

  • 或者你可以打电话给卷毛? (6认同)

小智 25

我和朋友已经想出如何调用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$$;
Run Code Online (Sandbox Code Playgroud)

触发代码:

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

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


Vla*_*sny 15

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

新增19.03.2014:

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

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

  • 为您的应用程序增加了额外的复杂程度(了解数据库如何工作,您现在需要知道SQL和PHP,而不仅仅是SQL),您还必须调试PHP,而不仅仅是SQL.

  • 为您的应用程序添加额外的故障点(例如PHP配置错误),这也需要进行诊断(我认为触发器需要保存一些调试代码,这些代码将记录所有不成功的PHP解释器调用及其原因).

  • 添加额外的性能分析点.每个PHP调用都很昂贵,因为你需要启动解释器,将脚本编译为字节码,执行它等等.因此涉及此触发器的每个查询执行速度都会变慢.有时候很难分离查询性能问题,因为EXPLAIN没有告诉你任何关于查询由于触发器例程性能而变慢的事情.而且我不确定如何将触发时间转储到慢速查询日志中.

  • 在应用程序测试中添加了一些问题.SQL可以很容易地测试.但是要测试SQL + PHP触发器,您必须应用一些技巧.

  • 我不认为这是一个"非常糟糕的编程习惯"......它只是一种非传统的方式.在我的情况下,我需要从MySQL-> PHP-> Javascript(使用HTML5网络套接字)一直"实时"响应.由于ws服务器和Web服务器在不同的端口运行,我没有其他"简单"的方法来实现它.(和...)每秒查询数据库对我来说似乎不切实际,因为数据不会每秒都改变(它可能不会在几小时内改变). (29认同)
  • 为什么?看起来它可能非常实用.例如,php脚本插入到远程数据库服务器上,服务器可以启动本地php脚本在该机器上执行某些操作. (7认同)
  • Downvote用于调用"坏"和"疯狂"的东西,没有任何解释. (7认同)
  • 一个用例 - 当触发事件必须做一些MYSQL中没有的处理时 - 就像json解析/真实世界一样凌乱:D (3认同)
  • @Johan"内部网不比互联网上的内容更安全""员工不能信任""大多数犯罪都在工作中"这些过度概括当然并不总是适用.所以正确的答案是"确保你采取预防措施并有充分的理由,如果你尝试这样的黑客",而不是"这总是一个坏主意". (3认同)
  • MySQL可以通过编程代码之外的其他东西进行更新.例如,Excel或Access或FileMaker等数据库应用程序可以更新通过ODBC访问的MySQL数据库; 至少可以说,这些应用程序的编程能力比PHP要有限得多.有一种方法让MySQL自己通知PHP或其他代码它已经改变了,这是一种让网站或其他代码通知其数据库外部变化的方法,例如,如果它需要做任何改变的结果(发送)一封电子邮件等). (2认同)
  • 不同意“非常糟糕的编程实践” 这对数据库比 cron/polling 技术友好得多,尤其是在设计为异步运行的情况下。 (2认同)

Lan*_*ing 6

我找到了这个:

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 ;
Run Code Online (Sandbox Code Playgroud)

  • \!命令:仅执行一次(在CREATE TRIGGER上).它不会在Insert上执行. (12认同)

pha*_*zei 6

我正在考虑一个长轮询案例的确切问题,我不希望php脚本不得不继续轮询数据库.轮询需要在某个地方完成,内存可能是最好的.因此,如果某种程度上触发器可以将信息放入像memcache这样的东西,那么php可以进行轮询,这将会大大减少整体密集度.只需要一个mysql的方法来使用memcache.也许进入具有特定用户ID的预定义变量.一旦数据被检索,php就可以重置var,直到db再次设置它为止.虽然不确定时间问题.也许第二个变量用于存储选定的上一个键.