PHPでPythonを呼び出す


82

最近書いたPythonスクリプトがあり、いくつかのオプションを指定してコマンドラインを使用して呼び出します。Macでこのスクリプトをローカルに呼び出すための非常に薄いWebインターフェイスが必要です。

Macにmod_pythonまたはmod_wsgiをインストールするという小さな問題を経験したくないので、PHPからsystem()またはpopen()を実行してPythonスクリプトを呼び出すだけでした。

より良いアイデアはありますか?前もって感謝します!

回答:


106

何をしているかによって、system()またはpopen()が最適な場合があります。Pythonスクリプトに出力がない場合、またはPythonスクリプトの出力をブラウザーに直接送信する場合は、system()を使用します。Pythonスクリプトの標準入力にデータを書き込む場合、またはphpのPythonスクリプトの標準出力からデータを読み取る場合は、popen()を使用します。popen()は、読み取りまたは書き込みのみを許可し、両方は許可しません。両方が必要な場合は、proc_open()を確認してください。ただし、プログラム間の双方向通信では、各プログラムが他のプログラムが何かを実行するのを待っているデッドロックを回避するように注意する必要があります。

ユーザーが指定したデータをPythonスクリプトに渡したい場合、注意すべき重要なことはコマンドの挿入です。注意しないと、ユーザーから「; evilcommand;」のようなデータが送信される可能性があります。そしてあなたのプログラムにあなたの意志に反して任意のコマンドを実行させます。

escapeshellarg()escapeshellcmd()はこれに役立ちますが、個人的には、次のようなものを使用して、既知の適切な文字ではないものをすべて削除するのが好きです。

preg_replace('/[^a-zA-Z0-9]/', '', $str)

1
サブプロセスモジュールは、os.Popen [n]を直接使用して置き換えられました。代わりにそれを使用する必要があります。
Nick Stinemates 2008年

6
@Nick Stinemates:PHP関数について話しています;)
Glaslos 2011

Cのexecve()のように、最初にfork()を実行する代わりに別のプロセスで実行することを除いて、シェルを含まないソリューションはありません。
嘘ライアン

解決策は常にありますが、何かを引き出すにはどこかでpythonを実行する必要があります。入力を待つだけの単純なPythonサービスを作成するか、何らかの方法でプログラムをトリガーすることができます(たとえば、linux inotify)。次に、それらのPHP拡張機能があり、Linuxサーバー用のローカルソケットがあります。PHPのPythonは、他の(プラグイン以外の)Pythonの周りに常に何らかのシェルがあるため、最良のNoShellソリューションのように見えます。
サンポサララ-codidact.org 2014年

27

backquote演算子を使用すると、上記と同様の構文を使用してPythonスクリプトを実行することもできます。

python.pyというPythonファイルの場合:

hello = "hello"
world = "world"
print hello + " " + world

python.phpというphpファイルの場合:

$python = `python python.py`;
echo $python;

15

PHP拡張機能もあります:Pip-PHPのPython、私は試したことがありませんが、そのような機会のためにブックマークしました


11
「pip」という名前は、非常に人気があり、かなり標準的なPythonパッケージ管理ツールを表すためにも使用されているため、このPHPツールの名前は非常に悪く、混乱し、運命にあることに注意してください。多分それはそれがそれほど長い間更新されていない理由です。
gregD 2013

2
まだ進行中のようです(名前の選択が不十分です)github.com/jparise/php-python
benekastah

11

phpを介してPythonスクリプトを実行し、ブラウザに出力できます。

基本的に、Pythonスクリプトを次のように呼び出す必要があります。

$command = "python /path/to/python_script.py 2>&1";
$pid = popen( $command,"r");
while( !feof( $pid ) )
{
 echo fread($pid, 256);
 flush();
 ob_flush();
 usleep(100000);
}
pclose($pid);

注:Pythonコードでtime.sleep()を実行すると、ブラウザーに結果が出力されません。

完全なコードが機能するようにするには、PHPからPythonスクリプトを実行し、ブラウザーに出力を表示する方法にアクセスしてください。


ここで相対パスと絶対パスを指定する方法。基本的に、たとえばフォルダの下にPythonスクリプトがtempmonあり、同じフォルダにPythonスクリプトが含まれています。アプリケーションを移植可能にしたいので、のtempmon下のフォルダをコピーするだけhtdocsです。そして、同じことが異なるマシンでも機能するはずです。
クリシュナオザ2015年

完璧に機能しました。初心者の理解を深めるために、開始と終了のphpタグ<?php?>を追加できます
Zaheer

7

私はいつもこの種のことを、手っ取り早いスクリプトのために行っています。system / popenを使用して外部プログラムを呼び出すだけのCGIまたはPHPスクリプトを使用することは非常に一般的です。

Webサーバーがインターネット全体に公開されている場合は、特に注意してください。この場合、攻撃者がマシン上で任意のコマンドを実行できないように、必ずGET / POST入力をサニタイズしてください。


3

call_python_file.phpは次のようになります。

<?php
    $item='Everything is awesome!!';
    $tmp = exec("py.py $item");
    echo $tmp;
?>

これにより、Pythonスクリプトが実行され、結果がブラウザに出力されます。Pythonスクリプトでは、(sys.argv [1:])変数がすべての引数を取り込みます。phpがプルしている場所の文字列としてargvを表示するには、テキスト領域を実行する場合は次のようにします。

import sys

list1 = ' '.join(sys.argv[1:])

def main():
  print list1

if __name__ == '__main__':
    main()

0

(共有ホスティングのように)仮想環境を使用している場合は、Pythonへのパスを調整する必要があることに注意してください。例: /home/user/mypython/bin/python ./cgi-bin/test.py


0

上記の方法は複雑なようです。私の方法を参考にしてください。

私はこの2つのファイルを持っています

run.php

mkdir.py

ここでは、GOボタンを含むhtmlページを作成しました。このボタンを押すたびに、パスを指定したディレクトリに新しいフォルダが作成されます。

run.php

<html>
 <body>
  <head>
   <title>
     run
   </title>
  </head>

   <form method="post">

    <input type="submit" value="GO" name="GO">
   </form>
 </body>
</html>

<?php
    if(isset($_POST['GO']))
    {
        shell_exec("python /var/www/html/lab/mkdir.py");
        echo"success";
    }
?>

mkdir.py

#!/usr/bin/env python    
import os    
os.makedirs("thisfolder");

-2

PythonスクリプトをPHPで実行する場合は、phpスクリプトで次のコマンドを実行する必要があります。

exec('your script python.py')

a)個別のパラメータにスペースを入れます。つまり、これyourはパラメータscriptとを使用してプログラムを呼び出そうとしますpython.py。b)Pythonスクリプトに適切なシバンがない限り、Pythonインタープリターを呼び出して、スクリプト名を渡す必要があります(python script.py)。適切なシバンがあっても./script.py、インタプリタ名を使用する代わりに呼び出すので、これは間違っています。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.