web-dev-qa-db-ja.com

MySQLトリガーからPHPスクリプトを呼び出す

レコードがMySQLデータベーステーブルに挿入されたときにPHP page/functionを呼び出す方法はありますか?レコード挿入手順を制御できません。トリガーメカニズムはありますか? PHPスクリプトを返しますか?

58
Shyju

トリガーは、PHP oneではなく、両方が同じマシン上にある場合でも)MySQLサーバーで実行されます。

したがって、これはまったく不可能であると言えます-少なくとも単純ではありません。


それでも考慮します MySQLからのこのエントリFAQトリガーで)

23.5.11:トリガーはUDFを介して外部アプリケーションを呼び出すことができますか?

はい。たとえば、トリガーは、ここで利用可能なsys_exec() UDFを呼び出すことができます。 https://github.com/mysqludf/lib_mysqludf_sys#readme

そのため、UDF関数を介してphp実行可能ファイル/スクリプトを起動する方法があるかもしれません。それほど簡単ではありませんが、可能と思われます。 ;-)

31
Pascal MARTIN

友人と私は、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);

ストアドプロシージャを作成することに興奮しておらず、余分なオーバーヘッドが発生するかどうかはわかりませんが、機能します。行がsometableに追加されるたびに、トリガーが起動します。

25
Mike E.

それは非常に悪いプログラミング慣行と呼ばれるべきですPHPデータベーストリガーからのコード。トリック、私たちは満足のいくソリューションを提供するかもしれません。

2014年3月3日追加:

以前にいくつかの推論を追加する必要がありましたが、今これを行う時間を見つけました。重要な発言をしてくれた@cmcに感謝します。したがって、PHPトリガーは、アプリケーションに次の複雑さを追加します。

  • @Johanが言うように、ある程度のセキュリティ問題をアプリケーションに追加します(外部PHPスクリプト呼び出し、パーミッション設定、おそらくSELinux設定など)。

  • アプリケーションに複雑さを追加します(データベースの動作を理解するには、SQLだけでなくSQLとPHPの両方を知る必要があります)。デバッグする必要があるのは、PHPも、SQLだけではありません。

  • 追加の障害点をアプリケーションに追加します(たとえば、PHPの構成ミス)。これも診断する必要があります(トリガーは、すべての失敗したPHPインタープリター呼び出しとその理由)。

  • パフォーマンス分析のポイントを追加します。各PHP呼び出しは、インタープリターを起動し、スクリプトをバイトコードにコンパイルし、実行する必要があるため、コストがかかります。したがって、このトリガーを含む各クエリの実行は遅くなります。 EXPLAINはトリガールーチンのパフォーマンスのためにクエリが遅くなることについて何も伝えないため、パフォーマンスの問題が発生します。また、トリガー時間をスロークエリログにダンプする方法がわかりません。

  • アプリケーションのテストにいくつかの問題を追加します。 SQLは非常に簡単にテストできます。ただし、SQL + PHPトリガーをテストするには、何らかのスキルを適用する必要があります。

16

私はこれを見つけました:

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

私は、PHPスクリプトで継続的にdbをポーリングする必要がない、長いポーリングの場合にこの正確な問題について考えていました。ポーリングはどこかで行う必要がありますが、おそらくメモリが最適です。そのため、トリガーが何らかの方法で情報をmemcacheのようなものに入れることができる場合、phpは全体的にはるかに少ない集中度でポーリングできます。 mysqlがmemcacheを使用するためのメソッドが必要です。おそらく、特定のユーザーIDを持つ事前定義された変数に。データが取得されると、phpは、dbが再度設定するまでvarをリセットできます。ただし、タイミングの問題についてはわかりません。おそらく、選択した前のキーを保存するための2番目の変数。

6
phazei

MySQLにトランザクションログがある場合、ログインスタンスを作成するためのトリガーを作成できます。 cronjobはこのログを監視し、トリガーによって作成されたイベントに基づいてphpスクリプトを呼び出すことができます。これは、挿入をまったく制御できない場合です。

1
Mohammad

それが可能かどうかはわかりませんが、MySQLのCSVストレージエンジンを使用してこれを実行できることを常に想像していました。このエンジンの詳細はわかりません: http://dev.mysql.com/doc/refman/5.7/en/csv-storage-engine.html しかし、あなたはそれを調べて、オペレーティングシステムに、ファイルが変更された場合にPHP呼び出しをトリガーするFile Watcherがあります。

1
StackOverflowed

データベースから通知を取得するために、websocketを使用してコマンドラインスクリプトを作成し、最新の更新されたタイムスタンプを毎秒確認しました。これはサーバー上で無限ループとして実行されました。変更がある場合、接続されているすべてのクライアントに通知を送信できます。

1
Kaippally

Cronjobはこのログを監視し、トリガーによって作成されたイベントに基づいてphpスクリプトを呼び出すことができます。これは、挿入を完全に制御できない場合です。MySQLにトランザクションログがある場合は、ログインスタンスを作成する目的でトリガーを作成できます。

0
tutor