- 締切済み
system() 関数でスクリプトの代わりに変数内のphpコードを実行させる
system() 関数でphpスクリプト(例えば、script.php)を実行するときは、 system("php script.php &"); でできますが、これを、script.php のデータの内容がそのまま入っている $phpcode を実行させることなどできますでしょうか? 例えば、 $phpcode = file_get_contents('script'); system("php $phpcode &"); などとしてもだめですよね。 いったい何をしたいのかと申しますと、データベース内にスクリプトを保存し、任意に呼び出して実行できるようにしたいのです。 もし方法をご存知の方おられましたらどうぞよろしくお願いいたします。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- NINJA104
- ベストアンサー率43% (133/306)
大変失礼しました。 いくつか説明間違いしていた様です。。。m(_"_;m 提案させて頂いた手法の中で、私の環境で実際に実現出来た記述のサンプルコードを以下に記載させて頂きます。 popen() を使った手法となります。 <?php $phpcode = '<?php echo "Hello World!\n"; ?>'; echo "実行するphpスクリプト:$phpcode\n"; $pipe = popen( "/usr/bin/php", "w" ); fwrite( $pipe, $phpcode ); pclose( $pipe ); ?> 実行すると、Hello World! が表示されると思います。 こんなやり方は如何でしょうか?
- NINJA104
- ベストアンサー率43% (133/306)
追伸です。 >または syetem() で「php」そのものを実行するのも手かと。 と記述しましたが、質問者様が最初に検討した手段と殆ど差はないと思います。 具体的には、 system( "php -l '$phpcode' &" ); となるのかな。 この場合、参考先にも有る様に、<? と ?> は記述禁止なので、preg_replace() 辺りを使って、前後の <? と ?> を削除した物を与えてあげる等の工夫が必要になるかと思います。 また、スクリプトを ' でくくっていますので、' をスクリプト内で使わない等の工夫も必要になるかな。 提案させて頂いたいくつかの方法でいけると思うんですけれどね。。。 f(^^;
お礼
ありがとうございます。こちらの方法を試してみたのですが、エラーが出ました。 まず、hello.php というスクリプトを <? $result ="Hello World!"; $path = './hello.html'; $fo = fopen($path, "w"); fwrite($fo, $result); fclose($fo); ?> で作成しました。次に実行ディレクトリCHMOD を777にして、同階層内の別ファイル、 <? $phpcode = file_get_contents('hello.php'); $del_pattern = array('<?php', '?>', '<?'); $phpcode = str_replace($del_pattern, '', $phpcode); system( "php -l '$phpcode' &" ); ?> を実行(ブラウザからアクセス)したところ、以下のようなエラーメッセージが出ました。 Could not open input file: $result ="Hello World!"; $path = ./hello.html; $fo = fopen($path, "w"); fwrite($fo, $result); fclose($fo); 仰られるように、以下のように'(シングルクオート)を取って実行してみました。 system( "php -l $phpcode &" ); すると、 Could not open input file: のみ表示されました。hello.php にブラウザから直接アクセスすると、フィルを作成してくれます。 どこが問題かお分かりになりますでしょうか?どうぞよろしくお願いいたします。
- NINJA104
- ベストアンサー率43% (133/306)
>その場合、eval() ですとどのようにしてsystem() に渡せばよいのでしょうか? system()で処理するのではなく、eval()でそのまま変数に保存されているphpスクリプトを実行させてしまいます。 バックグラウンドでとの事なので、pcntl_fork()と組み合わせると良いかと。 但し、OS依存なのでWinだと出来なさそう。。。 参考:pcntl_fork() の使い方 http://phpspot.net/php/man/php/function.pcntl-fork.html popen() を使って「php」そのものをパイプハンドラ付きで open し、そのopen時のハンドラに対し変数(phpスクリプト)を出力するというのはどうでしょうか? または syetem() で「php」そのものを実行するのも手かと。 どちらもphpをコマンドラインから起動する時の応用です。 http://search.net-newbie.com/php/features.commandline.html 未検証なのですが、実際に試してみる事をお薦めします。
お礼
ありがとうございます。現在検証しています。上手くいきましたら報告させていただきますので、よろしくお願いします。
- NINJA104
- ベストアンサー率43% (133/306)
うーん、、、 私ならば eval() を使うか、データベースから取得したスクリプトを一旦テンポラリファイル扱いとしてファイルに出力し、実行後に消すかな。。。
お礼
ありがとうございます。実はDB内に格納したスクリプトをバックグラウンドで実行しようと思っています。 その場合、eval() ですとどのようにしてsystem() に渡せばよいのでしょうか? >データベースから取得したスクリプトを一旦テンポラリファイル扱いとしてファイルに出力し、実行後に消す できましたらDB内から直接実行させるようなことはできないものでしょうか?
お礼
ありがとうございます。こちらの環境では、同様の結果が確認できませんでした。 phpの場所を usr/bin/php から /usr/local/bin/php に変更しています。出力をできるだけシンプルにするために echo "実行するphpスクリプト:$phpcode\n"; をはずして実行してみました。 <?php $phpcode = '<?php echo "Hello World!\n"; ?>'; $pipe = popen( "/usr/local/bin/php", "w" ); fwrite( $pipe, $phpcode ); pclose( $pipe ); ?> このコードで実行すると白紙画面が帰ってきます。HTMLソースコードは以下のようになっています。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML><HEAD> <META http-equiv=Content-Type content="text/html; charset=utf-8"></HEAD> <BODY></BODY></HTML> 環境: FreeBSD PHP Version 4.4.1 phpinfo の safe_modeの表示ですが、 safe_mode Off Off safe_mode_exec_dir no value no value safe_mode_gid Off Off safe_mode_include_dir no value となっています。どこが問題かわかりますでしょうか?よろしくお願いいたします。
補足
phpinfo に --enable-pcntl がないのですが関係ありますでしょうか? ためしにインストールしてみようと思ったのですが、 「インストール手順 PHPがサポートするプロセス制御機能は、デフォルトでは有効となってい ません。プロセス制御機能を有効にするには、 configure のオプションに --enable-pcntl を付け、CGI 版あるいは CLI 版の PHP をコンパイルする必要があります。」 と書いてあり、「CGI 版あるいは CLI 版の PHP をコンパイルする必要があります」 この部分の意味が良くわかりません。なにかファイルをダウンロードする必要があるのでしょうか?