从PHP编辑Python脚本

时间:2015-08-17 13:34:00

标签: php python

我想从PHP编辑Python脚本的代码,以更改其中一个项目的公式和初始值。

Python脚本:

import numpy as np
import scipy as sp
import math
from scipy.integrate import odeint
import matplotlib.pyplot as plt

def g(y, x):
    y0 = y[0]
    y1 = x #formula

    return y1
init = 90#formula2

x= np.linspace(0,1,100)
sol=odeint(g, init, x)

plt.legend()
plt.plot(x, sol[:,0], color='b')
plt.show()    

PHP:

 <?php
if (isset($_POST['equation1'])&&isset($_POST['constant'])) {
    $eqn1 = $_POST['equation1'];
    //$equation = $_POST['equation'];
    $eqn2 = $_POST['constant'];
    //str_replace("^", "**", $equation);
    $filename ='ode3.py';
    $pgm = "C:\\wamp\\www\\working\\".$filename;
    function get_string_between($string, $start, $end) {
        $string = " ".$string;
        $ini = strpos($string,$start);
        if ($ini == 0) return "";
        $ini += strlen($start);
        $len = strpos($string,$end,$ini) - $ini;
        return substr($string,$ini,$len);
    }

    //write the equation in python code
    $pgm_file = $pgm; 
    $myfile = fopen($pgm_file, "r") or die("Unable to open file!");
    $data = fread($myfile,filesize($pgm_file));
    $parsed = get_string_between($data, "y1 = ", " #formula");     
    $parsed2 = get_string_between($data,  "init = ", "#formula2");
    $datanew1 = str_replace($parsed, $eqn1, $data);
    $datanew2 = str_replace($parsed2,$eqn2, $datanew1);

    fclose($myfile);

    $myfile = fopen($pgm_file, "w") or die("Unable to open file!");
    $datacode = fwrite($myfile,$datanew2);

    $pgmfile = fopen($pgm_file, "r") or die("Unable to open file!");
    $pgmdata = fread($pgmfile,filesize($pgm_file));

    fclose($pgmfile);

    /*$demo = fopen($pgm, "r") or die("Unable to open file!");
    $xxx = fread($demo,filesize($pgm));
    echo  $xxx;*/

    $pyscript = "C:\\wamp\\www\\working\\".$filename;
    $python = 'C:\\Python34\\python.exe';
    $cmd = "$python $pyscript";

    exec("$cmd", $output);
    /* if (count($output) == 0) {
             echo "error%";
       } else {
           echo $output[0]."%";*/
       }
     var_dump($output);
    }           
?>    

我希望它只替换标记为#formula#formula2的Python脚本部分,其中x应替换为x+45init } value应设置为85。

但是,当我运行PHP脚本时,Python脚本中的每个x实例都替换为x+45。如何将其限制为仅#formula函数内的g()标记的部分?

1 个答案:

答案 0 :(得分:3)

我认为这是解决这个问题的一种不好的方法。您应该重新设计它,而不是编辑Python脚本的源代码,以便在调用脚本时可以将变量部分作为参数传入。然后,您可以使用sys.argv访问这些执行参数。

#!/usr/bin/env python
import sys
# ... import numpy etc.

def g(y,x, expr):
    y0 = y[0]
    # use the Python interpreter to evaluate the expression.
    # It should be of the form 'x**2 + 3' or something - a valid Python/math
    # expression otherwise it will crash with a syntax error.
    y1 = eval(expr)
    return y1

if __name__=='__main__':
    init = int(sys.argv[1]) # the first argument passed to the script
    expr = sys.argv[2].strip('"') # the second argument - if it includes 
                                  # whitespace, wrap it in "" so it works.

    # ... do stuff

然后,您可以使用PHP的execshell_exec函数将其称为标准脚本。将函数表达式作为参数传递,如下所示: python /path/to/ode3.py 85 "x+45"

非常小心使用Python的eval - 它会评估您放在那里的任何内容。由于您是从接受POST参数的面向Web的PHP脚本调用此函数,因此必须小心清理输入。从您发布的脚本看,它看起来并不像您验证它,因此如果它是公共可访问的,它将允许使用与PHP脚本相同的权限执行任意代码。无论您是使用eval还是编辑Python文件,都是如此。

更新:此外,运营商在不同语言中有不同的含义。例如,在Python中,^运算符表示指数,它实际上表示按位异或。如果你想获得x ^ 2(x平方),Python语法是x**2。如果您希望能够编写x^2,则需要编写解析器。有关详细信息,请参阅here