我想从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+45
和init
} value应设置为85。
但是,当我运行PHP脚本时,Python脚本中的每个x
实例都替换为x+45
。如何将其限制为仅#formula
函数内的g()
标记的部分?
答案 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的exec
或shell_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。