71

Is there any way how to invoke a PHP page / function when a record is inserted to a MySQL database table? We don't have control over the record insertion procedure. Is there a trigger mechanism which can call a PHP script back?

Mifeet
  • 12,949
  • 5
  • 60
  • 108
Shyju
  • 214,206
  • 104
  • 411
  • 497
  • Maybe this helps you : http://stackoverflow.com/questions/40025369/how-to-execute-external-script-app-command-from-mysql-server – Baurin Leza Oct 14 '16 at 16:15
  • It's nowadays trivial to do this, here's an example https://support.pubnub.com/hc/en-us/articles/360051973671-Can-I-publish-a-message-via-database-trigger- Of course, there are many dangers in such an architecture – Fattie Sep 02 '22 at 11:22
  • Another easy approach is, just tail the log file of mysql and do what you wish with each new item. – Fattie Sep 02 '22 at 11:27

10 Answers10

34

The trigger is executed on the MySQL server, not on the PHP one (even if those are both on the same machine).

So, I would say this is not quite possible -- at least not simply.


Still, considering this entry from the MySQL FAQ on Triggers :

23.5.11: Can triggers call an external application through a UDF?

Yes. For example, a trigger could invoke the sys_exec() UDF available here: https://github.com/mysqludf/lib_mysqludf_sys#readme

So, there might be a way via an UDF function that would launch the php executable/script. Not that easy, but seems possible. ;-)

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
27

A friend and I have figured out how to call Bernardo Damele's sys_eval UDF, but the solution isn't as elegant as I'd like. Here's what we did:

  1. Since we're using Windows, we had to compile the UDF library for Windows using Roland Bouman's instructions and install them on our MySQL server.
  2. We created a stored procedure that calls sys_eval.
  3. We created a trigger that calls the stored procedure.

Stored Procedure code:

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$$;

Trigger code:

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

I'm not thrilled about having the stored procedure, and I don't know if it creates extra overhead, but it does work. Each time a row is added to sometable, the trigger fires.

Mike E.
  • 451
  • 5
  • 6
17

That should be considered a very bad programming practice to call PHP code from a database trigger. If you will explain the task you are trying to solve using such "mad" tricks, we might provide a satisfying solution.

ADDED 19.03.2014:

I should have added some reasoning earlier, but only found time to do this now. Thanks to @cmc for an important remark. So, PHP triggers add the following complexities to your application:

  • Adds a certain degree of security problems to the application (external PHP script calls, permission setup, probably SELinux setup etc) as @Johan says.

  • Adds additional level of complexity to your application (to understand how database works you now need to know both SQL and PHP, not only SQL) and you will have to debug PHP also, not only SQL.

  • Adds additional point of failure to your application (PHP misconfiguration for example), which needs to be diagnosied also ( I think trigger needs to hold some debug code which will log somwewhere all insuccessful PHP interpreter calls and their reasons).

  • Adds additional point of performance analysis. Each PHP call is expensive, since you need to start interpreter, compile script to bytecode, execute it etc. So each query involving this trigger will execute slower. And sometimes it will be difficult to isolate query performance problems since EXPLAIN doesn't tell you anything about query being slower because of trigger routine performance. And I'm not sure how trigger time is dumped into slow query log.

  • Adds some problems to application testing. SQL can be tested pretty easily. But to test SQL + PHP triggers, you will have to apply some skill.

Vladislav Rastrusny
  • 29,378
  • 23
  • 95
  • 156
  • 8
    why? It seems like it could be very functional. For instance, a php script inserts onto a remote db server, the server could start a local php script to do something on that machine. – phazei Aug 19 '10 at 06:32
  • At least because this cannot be made fast enough. Triggers should execute as fast as possible. PHP code is a bad candidate for this task. Also the connection between DB and PHP is weak and this weakens database integrity. – Vladislav Rastrusny Aug 19 '10 at 13:18
  • 35
    I don't think its a "very bad programming practice"... it is just a non-conventional way. In my case I need a "Real Time" response all the way from MySQL->PHP->Javascript (Using HTML5 web sockets). As the ws server and the web server are running in different ports, I have no other "simple" way to achieve it. (and...) Querying the Database each second seems impractical to me as data won't change each second (it may not change in hours). – lepe Aug 05 '11 at 09:01
  • 3
    One Use case - when trigger events have to do some processing not available in MYSQL - like json parsing/ Real world is messy :D – rjha94 Mar 28 '12 at 09:35
  • 9
    Downvote for calling something "bad" and "mad" with no explanation. – cmc Nov 20 '13 at 15:08
  • @Johan not inherently. It could be implemented in an intranet. – cmc Nov 20 '13 at 15:10
  • 1
    @cmc, intranets are no more secure than stuff on the internet. Just because only employees have supposed to have access, does not mean that everyone else does not have access. And employees cannot be trusted either. Most crimes are inside jobs. So still a very bad idea. – Johan Nov 20 '13 at 15:28
  • 3
    @Johan "intranets are no more secure than stuff on the internet" "employees cannot be trusted" "Most crimes are inside jobs" these are overgeneralizations that certainly do not always apply. So the correct answer is "make sure you take precautions and have a good reason if you attempt a hack like this", not "this is always a bad idea". – cmc Nov 20 '13 at 19:26
  • 1
    "very bad programming practice", **says who?** – Rolf Jan 04 '14 at 00:12
  • 2
    MySQL can be updated by something other than programming code. For example, Excel or a database app like Access or FileMaker could update a MySQL database accessed over ODBC; and these apps have much more limited programming abilities than PHP, to say the least. Having a way for MySQL itself to notify PHP or other code that it has changed is a way to keep a website or other code notified of external changes to its database, for example if it needs to do anything as a result of the change (send an email, etc.). – Geoffrey Booth Feb 28 '14 at 17:40
  • 2
    Disagree with "very bad programming practice" This is much friendlier to a database than a cron/polling technique, especially if designed to run asynchronous. – efreed Aug 18 '14 at 23:05
  • @efreed It will not be asynchronous for sure. If you have jobs, that need to be run periodically, it's much better to utilize cron. If you have queues, use something like RabbitMQ. Anyway, I provided my reasoning in the post. – Vladislav Rastrusny Aug 20 '14 at 04:16
  • 1
    I think generally we (SO users) get into trouble if we try to judge a question rather than simply answer the question. Mike E. gave a great example of how he was able to implement the call. That's really what we are after here. The negative points you highlighted are true of all custom programming. – ChronoFish Dec 18 '14 at 03:22
  • 1
    @Johan you cant overgeneralize, even a bad configured Web server is a risk, but is not a bad practice to have a Web server. Please dont say something is "very bad", just say "there should be better ways". – Frederic Yesid Peña Sánchez Feb 19 '15 at 20:49
  • 1
    @ChronoFish Well, have it your way ;) But to me StackOverflow is all about education. And I will do my best to educate users even by saying not-so-nice things about their questions, design decisions or code. I will also be glad if someone will do the same to me. I do not want to blindly answer the question and provide solutions leading to code that smells. Primarily because I might end up being a developer debugging such code. – Vladislav Rastrusny Mar 12 '15 at 08:09
  • I must add, that I should have answered that question though. Of course, providing a reason why my answer should never get implemented ;) – Vladislav Rastrusny Mar 12 '15 at 08:16
  • 1
    On your 2nd point, my reason for contemplating this is to avoid splitting complex processing up between the scripts that do the majority of the work (importing data from external sources) and some hidden triggers that most programmers will not be aware of (to perform pricing calculations for denormalised final prices when cost prices change), and even fewer will have the skills to maintain. – Kickstart May 06 '15 at 10:35
  • 1
    +1 In addition to your reasons, another reason not to run application code from a trigger is that it breaks transaction isolation. The trigger fires when the SQL action happens. There's no guarantee that the action will be committed, and it definitely is not committed at the time the trigger executes. You could end up running app code for "phantom updates" that are not visible to the app. – Bill Karwin Aug 16 '16 at 15:08
7

I was thinking about this exact issue for a case with long polling where I didn't want the php script to have to continually poll the db. Polling would need to be done somewhere, memory would probably be best. So if somehow the trigger could put the info into something like memcache, then php could poll that would would be much less intensive overall. Just need a method for mysql to use memcache. Perhaps into a predefined variable with a specific user id. Once the data is retrieved php could reset the var until the db sets it again. Not sure about timing issues though. Perhaps a second variable to store the previous key selected.

phazei
  • 5,323
  • 5
  • 42
  • 46
5

I found this:

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 ;
Lance Rushing
  • 7,540
  • 4
  • 29
  • 34
  • 13
    \! command : is only executed once (on CREATE TRIGGER). It does not execute on Insert. – lepe Aug 05 '11 at 08:54
1

If you have transaction logs in you MySQL, you can create a trigger for purpose of a log instance creation. A cronjob could monitor this log and based on events created by your trigger it could invoke a php script. That is if you absolutely have no control over you insertion.

Mohammad
  • 714
  • 4
  • 13
1

In order to get a notification from the database I wrote a command line script using websocket to check for the latest updated timestamp every second. This ran as an infinite loop on the server. If there is a change all connected clients will can be sent a notification.

Kaippally
  • 96
  • 10
1

I don't know if it's possible but I always pictured myself being able to do this with the CSV storage engine in MySQL. I don't know the details of this engine: http://dev.mysql.com/doc/refman/5.7/en/csv-storage-engine.html but you can look into it and have a file watcher in your operating system that triggers a PHP call if the file is modified.

StackOverflowed
  • 5,854
  • 9
  • 55
  • 119
-1

A cronjob could monitor this log and based on events created by your trigger it could invoke a php script. That is if you absolutely have no control over you insertion.. If you have transaction logs in you MySQL, you can create a trigger for purpose of a log instance creation.

tutor
  • 1
-5

Run away from store procedures as much as possible (some few times it is NOT possible). They are pretty hard to maintain and are VERY OLD STUFF ;)

Mário de Sá Vera
  • 380
  • 1
  • 4
  • 12
  • 2
    If you know what you are doing than they are not hard to maintain :P They can save you a ton of time also – DaAmidza Jan 15 '18 at 13:07
  • 4
    This really is rubbish. SPs do have issues and in unskilled hands can indeed be bad, but used properly they are highly efficient and indeed optimal for logical consistency – Cruachan Aug 16 '18 at 12:53
  • 1
    Stored Procedures are the only known way to react to database events on the database server, how can anyone run away from it? – Koushik Shom Choudhury Jun 05 '20 at 02:52
  • 4
    Java Developer: Should I use stored procedure on Oracle??? Answer: You MUST! || .NET Developer: Should I use stored procedures on M. SQL Server??? Answer: You MUST!!! || PHP Developers: Don't use stored procedures, they are useless, old and not OOP || PHP Developers: Why doesn't anybody want to use PHP for full size corporate solutions any more??? || Me... banging my head on a freaking wall :-( – Yuriy Semenikhin Aug 09 '20 at 15:23
  • 1
    this makes zero sense – Fattie Sep 02 '22 at 11:22
  • I love you all ! :) – Mário de Sá Vera Nov 26 '22 at 11:40