PHP exec()函数只运行极短的Python脚本

时间:2017-01-10 03:45:54

标签: php python python-3.x php-7

我在使用PHP exec()函数时遇到了一些麻烦。每当我试图运行的脚本很短时,exec()就可以了。但是如果脚本花费的时间超过一秒钟,它就会失败。注意,我尝试在命令行上手动运行长脚本,它运行正常。似乎PHP解释器正在杀死我的外部脚本,如果运行时间超过一秒左右。有什么想法或建议吗?这是我的代码:

<?php
    $fileName = "foobar.docx";
    $argVar = $fileName;
    exec("python3 /var/www/html/jan8/alexandrina.py /var/www/html/jan8/$argVar");
    echo "$output";
?>

这是我的剧本:

#!/usr/bin/env python3

import docx
import sys

docxFile = "".join(sys.argv[1:])

# The Three Lines Below Create a New Variable "htmlFile"
# "htmlFile" is the same as "docxFile", except ".docx" is cut off
# and replaced with ".html"
myNumber = len(docxFile) - 5
htmlFile = docxFile[0:myNumber]
htmlFile = htmlFile + '.html'

def generateHTML(filename):
    doc = docx.Document(filename)
    fullText = []
    for para in doc.paragraphs:
        fullText.append('<p>')
        fullText.append(para.text)
        fullText.append('</p>')
        fullText.append('\n')
    return '\n'.join(fullText)

file = open(htmlFile, "w")
file.write(generateHTML(docxFile))
file.close()

print("end python script")

附加说明:我已经增加了php.ini中的最长执行时间限制,但我认为这不应该重要,因为&#34;长脚本&#34;应该只需几秒钟就可以运行。另外,当我参考&#34;短脚本&#34;和&#34;长脚本&#34;时,我实际上指的是同一个脚本。 &#34;长脚本&#34;之间的区别和#34;短脚本&#34;只是执行的时间,因为它可能会有所不同,具体取决于我要求脚本处理的文件的大小。无论如何......真的很感激任何建议!

2 个答案:

答案 0 :(得分:1)

通常,php exec函数应该阻塞,直到您运行的命令完成。即,PHP脚本将暂停,等待命令完成,直到继续执行其余脚本。我有一半认为你的服务器正在经历max_execution_time超时,但是你已经明确表示即使只是几秒钟也太长了,即使这些相当短的脚本也有问题。

我想到了几个解决方案。最简单的方法是更改​​python命令,以便a)将任何输出路由到文件或输出流,以及b)进程在后台运行。根据{{​​3}}:

  

如果使用此功能启动程序,为了使其在后台继续运行,必须将程序的输出重定向到文件或其他输出流。如果不这样做将导致PHP挂起,直到程序执行结束。

我还希望您使用exec函数的两个附加可选参数。

$fileName = "foobar.docx";
$argVar = $fileName;
$cmd = "python3 /var/www/html/jan8/alexandrina.py /var/www/html/jan8/$argVar";
// modify your command to toss output, background the process, and output the process id
$cmd_modified = $cmd . " >/dev/null & echo \$!";
$cmd_output = NULL; // this will be an array of output
$cmd_return_value = NULL; // this will be the return value of the script
exec($cmd_modified, $cmd_output, $cmd_return_value);
echo "exec has completed</br>";
echo "output:<br>" . print_r($cmd_output, TRUE) . "<br>";
echo "return value: " . print_r($cmd_return_value, TRUE);

这可能会有所帮助,也可能不会。如果没有,我们仍然可以使用posix命令解决问题。

编辑:根据crispytx,长脚本导致$ cmd_return_val为1,这意味着发生了错误。尝试更改这一行:

$cmd_modified = $cmd . " >/dev/null & echo \$!";

到这个

$cmd_modified = $cmd . " & echo \$!";

让我们知道$ cmd_output的输出是什么 - 它至少应该具有新生成的进程的进程ID。

答案 1 :(得分:0)

感谢所有帮助S. Imp。调试使用你的建议我有点麻烦,因为我碰巧使用AJAX来调用脚本。但是,我使用您的建议编写了更简单的脚本来尝试调试问题,这就是我发现的:

数组([0] =&gt;回溯(最近一次呼叫最后):[1] =&gt;文件&#34; /var/www/html/jan8/alexandrina.py",第28行,在[2] =&gt; file.write(generateHTML(docxFile))[3] =&gt; UnicodeEncodeError:&#39; ascii&#39;编解码器无法编码字符&#39; \ u2026&#39;就位25:序数不在范围内(128))

所以看起来这个问题与ascii编码有关!即使较大的文件只是一个docx文件,其文本与较短的docx文件相同,一遍又一遍地重复300页。似乎如果docx文件超过1页,则插入的ascii字符不会出现在单页docx文件中。我不知道这篇文章是否会最终帮助任何人,但谁知道呢!

[已解决]