Visual Studio Code + Python
PythonコードをPHP上から実行する
(2019. 11. 27)
PythonスクリプトをVSCodeなどで作っていると、F5を押せば動いてしまうため、そのコードがVSCodeが無くても起動できる事を何となく忘れがちになります。Pythonで作った物を実用的に使う場合、データはPythonの外で用意して、python.exe等をコマンドライン上で走らせてPythonでそのデータを処理させて、出力をまた活用する…みたいなバッチ処理の一部に組み込むと考えると応用範囲が広がります。それと似たような発想で、ネット上でデータを入力して、それをサーバで処理し出力を返す、という事が出来たら何だか色々アイデアが膨らみそうですよね。
サーバ処理を行う言語も色々ありますが、多分最も多用されているのが「PHP」です。ネットからのリクエスト(****.phpよ動け、みたいな)を受けるとWebサーバは該当するPHPファイルを実行してくれます。ではリクエストにPythonファイルを直接指定できるかというと、リクエスト自体は出来ますが動作はしません。理由は普通のWebサーバはそのように動作するようにそもそも作られていないからです。なので、リクエストの結果そのpythonファイルのコードがそのままテキストとしてブラウザに出力されてしまいます。
PHPフォイルはリクエストに応えて動作する、でも処理自体はPythonにある。そういう状況を想定した場合「PHP上で自分が作ったPythonコードを動かす」仕組みが必要になります。
@ PHPのexec関数でpythonコマンド発行
PHPにはサーバ環境のコマンドライン(シェル)に命令を与えるexec関数が定義されています。使い方は至極簡単で:
<?php
exec( "ls -la", $outputs, $state );
print( "state: ".$state );
var_dump( $outputs );
?>
exec関数の第1引数には実行したいコマンドを文字列で指定します。上の例ではカレントディレクトリのリストを列挙させています。シェルへの出力文字列は第2引数に与えた変数に配列として行ごとに格納されます。第3引数には指定したコマンドを実行した結果(エラーコード)が出力されます。正常動作の場合は0で、何か問題が起きた場合は0以外の数値が返ります。127が返ってきた場合、指定のコマンドが見つかっていません(これ結構私嵌りました(-_-;)。
この関数にpythonを動かすコマンドを指定すればPHPの呼び出しでpythonコードが走ります:
<?php
exec( "python mycode.py", $output, $state );
?>
ただ細かく色々と罠があります。まずpythonの実行環境へのパスが通っている必要があります。そうでない場合、例えば複数のPythonバージョンを使い分けている場合などはフルパスでpythonを指定する必要があります(嵌りポイント)。特にレンタルサーバなどに独自のpythonを入れている時などは嵌りやすいと思います。実行したいpythonコードは呼び出されたPHPファイルからの相対位置で指定します。絶対パスでも勿論大丈夫です。
Python側からPHPへ値を直接返すにはPython側で文字列を出力します。python側のprint関数を使うなどすればOKです。ただ大量の結果を返す場合、文字列だと扱いが面倒だったりバッファへの書き込みが遅すぎる時もあります。その場合はPython側で出力用の一時ファイルをサーバ上に作って、PHPでそれをオープンして活用するなども可能かと思います。