web-dev-qa-db-fra.com

Appel d'un script PHP à partir d'un déclencheur MySQL

Existe-t-il un moyen d'invoquer une page/fonction PHP lorsqu'un enregistrement est inséré dans une table de base de données MySQL? Nous n'avons aucun contrôle sur la procédure d'insertion d'enregistrement. Existe-t-il un mécanisme de déclenchement qui peut appeler un script PHP back?

58
Shyju

Le déclencheur est exécuté sur le serveur MySQL, pas sur le PHP celui (même si ceux-ci sont tous les deux sur la même machine).

Donc, je dirais que ce n'est pas tout à fait possible - du moins pas simplement.


Pourtant, considérant cette entrée de MySQL FAQ on Triggers :

23.5.11: Les déclencheurs peuvent-ils appeler une application externe via un UDF?

Oui. Par exemple, un déclencheur pourrait invoquer l'UDF sys_exec() disponible ici: https://github.com/mysqludf/lib_mysqludf_sys#readme

Donc, il pourrait y avoir un moyen via une fonction UDF qui lancerait l'exécutable/script php. Pas si simple, mais cela semble possible. ;-)

31
Pascal MARTIN

Un ami et moi avons trouvé comment appeler l'UDF sys_eval de Bernardo Damele, mais la solution n'est pas aussi élégante que je le souhaiterais. Voici ce que nous avons fait:

  1. Puisque nous utilisons Windows, nous avons dû compiler la bibliothèque UDF pour Windows en utilisant instructions de Roland Bouman et les installer sur notre serveur MySQL.
  2. Nous avons créé une procédure stockée qui appelle sys_eval.
  3. Nous avons créé un déclencheur qui appelle la procédure stockée.

Code de procédure stockée:

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

Code de déclenchement:

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

Je ne suis pas ravi d'avoir la procédure stockée, et je ne sais pas si cela crée une surcharge supplémentaire, mais cela fonctionne. Chaque fois qu'une ligne est ajoutée à quelque chose, le déclencheur se déclenche.

25
Mike E.

Cela devrait être considéré comme une très mauvaise pratique de programmation pour appeler PHP à partir d'un déclencheur de base de données. Si vous expliquez la tâche que vous essayez de résoudre en utilisant une telle "folle" astuces, nous pourrions fournir une solution satisfaisante.

AJOUTÉ 19.03.2014:

J'aurais dû ajouter un peu de raisonnement plus tôt, mais je n'ai trouvé que le temps de le faire maintenant. Merci à @cmc pour une remarque importante. Ainsi, les déclencheurs PHP ajoutent les complexités suivantes à votre application:

  • Ajoute un certain degré de problèmes de sécurité à l'application (externe PHP, configuration des autorisations, probablement configuration SELinux, etc.) comme le dit @Johan.

  • Ajoute un niveau de complexité supplémentaire à votre application (pour comprendre comment fonctionne la base de données, vous devez maintenant connaître SQL et PHP, pas seulement SQL) et vous devrez déboguer PHP également, pas seulement SQL.

  • Ajoute un point de défaillance supplémentaire à votre application (configuration incorrecte de PHP par exemple), qui doit également être diagnostiquée (je pense que le déclencheur doit contenir un code de débogage qui enregistrera quelque part où tous les échecs PHP appels d'interpréteur et leurs raisons).

  • Ajoute un point supplémentaire d'analyse des performances. Chaque appel PHP est cher, car vous devez démarrer l'interpréteur, compiler le script pour le bytecode, l'exécuter etc. Donc, chaque requête impliquant ce déclencheur s'exécutera plus lentement. Et parfois, il sera difficile d'isoler la requête problèmes de performances car EXPLAIN ne vous dit rien sur le ralentissement des requêtes en raison des performances de la routine de déclenchement. Et je ne sais pas comment le temps de déclenchement est vidé dans le journal des requêtes lent.

  • Ajoute quelques problèmes aux tests d'application. SQL peut être testé assez facilement. Mais pour tester SQL + PHP, vous devrez appliquer certaines compétences.

16
Vladislav Rastrusny

J'ai trouvé ça:

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 ;
6
Lance Rushing

Je pensais à ce problème exact pour un cas de longue interrogation où je ne voulais pas que le script php doive interroger continuellement la base de données. Le sondage devrait être fait quelque part, la mémoire serait probablement la meilleure. Donc, si le déclencheur pouvait mettre les informations dans quelque chose comme memcache, alors php pourrait interroger ce qui serait beaucoup moins intensif dans l'ensemble. Juste besoin d'une méthode pour que mysql utilise memcache. Peut-être dans une variable prédéfinie avec un ID utilisateur spécifique. Une fois les données récupérées, le php pourrait réinitialiser le var jusqu'à ce que le db le redéfinisse. Je ne suis pas sûr des problèmes de timing. Peut-être une deuxième variable pour stocker la clé précédente sélectionnée.

6
phazei

Si vous avez des journaux de transactions dans MySQL, vous pouvez créer un déclencheur pour la création d'une instance de journal. Un cronjob pourrait surveiller ce journal et en fonction des événements créés par votre déclencheur, il pourrait invoquer un script php. C'est si vous n'avez absolument aucun contrôle sur votre insertion.

1
Mohammad

Je ne sais pas si c'est possible mais je me suis toujours imaginé pouvoir le faire avec le moteur de stockage CSV dans MySQL. Je ne connais pas les détails de ce moteur: http://dev.mysql.com/doc/refman/5.7/en/csv-storage-engine.html mais vous pouvez le consulter et avoir un observateur de fichiers dans votre système d'exploitation qui déclenche un appel PHP si le fichier est modifié.

1
StackOverflowed

Afin d'obtenir une notification de la base de données, j'ai écrit un script de ligne de commande en utilisant websocket pour vérifier le dernier horodatage mis à jour chaque seconde. Cela a fonctionné comme une boucle infinie sur le serveur. En cas de changement, tous les clients connectés peuvent recevoir une notification.

1
Kaippally

Un cronjob pourrait surveiller ce journal et en fonction des événements créés par votre déclencheur, il pourrait invoquer un script php. C'est-à-dire si vous n'avez absolument aucun contrôle sur votre insertion. Si vous avez des journaux de transactions dans MySQL, vous pouvez créer un déclencheur dans le but de créer une instance de journal.

0
tutor