我试图从PHP脚本中执行PERL脚本。我已经使用了Exec,Popen和proc_open等各种方法进行此操作,但是我有几个问题可以解决,旧的Google并没有给我答案。

我需要从php文件中运行.pl脚本(将一个变量传递给脚本,这是一个数字),但是请停止PHP脚本等待直到.pl完成(.pl可能需要4-5个小时在服务器上运行)。我不会期望从Perl脚本(Perl脚本将其输出记录到MySQL db)中的任何回报输出),因此我只需要它在服务器上运行并让PHP脚本运行即可。

当它在Windows机器上运行Apache,PHP,MySQL时,有一些障碍可以超越它。

我认为我看到了Linux的解决方案,但需要留在Windows机器上。

IM当前尝试使用以下代码尝试proc_open方法(proc_open行上的35是我需要传递给perl脚本的测试ID):

$descriptorspec = array(
0 => array("pipe","r"),
1 => array("pipe","w"),
2 => array("file","./error.log","a")
) ;

proc_close(proc_open('perl perlscript.pl 35', $descriptorspec, $pipes));

$i = 0;
while ($i < 1000) {
   echo ++$i;  
}

现在,此代码确实执行了Perl脚本,但是在其之后放置的while循环(仅用于测试)永远不会执行(Ive不等待Perl脚本完成是否完成),因为它必须等待.pl完成。

有帮助吗?

解决方案 4

感谢所有回答这个问题的人。经过大量的研究并处理了不同的解决方案,我终于得到了一些工作并满足我们的需求。它远非完美,但嘿,它的工作原理,所以我不会抱怨太多。

由于这似乎是其他人想知道的ID ID ID共享我的解决方案。

  1. 我从这里下载了一个名为Hstart(40KB)的小程序: http://www.ntwind.com/software/utilities/hstart.html

  2. 我将文件提取到C: Windows System32。

HSTART程序可以在不打开命令窗口的情况下运行批处理文件。它不会直接调用.pl文件,因此我必须创建一个.bat以如下调用.pl。

  1. 创建了一个.bat文件与我的.pl文件相同的目录,该目录基本上使用本地安装的PERL并传递变量。如下所示:

    perl脚本.pl%1

  2. 在我的PHP脚本中,我使用以下命令调用我的Perl文件。

    $ cmd ='hstart /noconsole“ run.bat'。$ id。'”> log.log'; exec($ cmd);

  3. 运行PHP文件会导致HSTART由于标志集而使用Noconsole打开,并以$ id I传递为变量的Perl文件,并将隐藏控制台窗口的所有输出发送到我命令指定的log.log。我所能看到的是我的任务管理器中运行的perl.exe。

正如我所说的远非完美的,但它可以奏效。

其他提示

我可以看到3个选项:

  • 采用 fork 在您的perl脚本中,可以使用叉子后立即存在的父进程分叉实际工作。但是,这可能无法正常工作或在窗户上根本无法正常工作,但值得一试。

    请查看以下“”fork 在Windows上“参考:

  • 如果PHP可以启动URL请求(类似于Perl的LWP或WGET类似),则将您的Perl脚本转换为CGI脚本(Trivial),请粘在Apache的CGI目录中,并通过适当的URL称其为 http://localhost/.... 。然后在最坏的情况下通过一些ITERNAL PHP超时或常规HTTP超时时间来超时URL请求。在最坏的情况下,从perl代码中执行相同的技巧,因为Perl绝对可以支持通过LWP库以及通过超时的URL调用 alarm()

  • 让调度程序每X分钟启动您的Perl脚本。脚本应以以下逻辑开头: if (-e $flag_file) { unlink $flag_file; do_long_work() } else { exit 0; } 在哪里 $flag_file 是服务器上的特殊位置(说 C:\temp\myscript_start_perl.txt), 和 do_long_work() 包含需要完成的实际工作。

    然后,当PHP脚本需要启动Perl脚本时,它只会创建一个空的标志文件(相同 C:\temp\myscript_start_perl.txt),下次调度程序执行它时,Perl脚本将注意到。

有两种可能性

  1. 使用“开始”程序。您将无法使用管道,只有命令行参数。

  2. 创建一个始终运行的PERL程序(在启动或使用Win32 :: Daemon)。使用插座或HTTP连接到它。这很容易,因为CPAN上有很多现成的服务器

另外,可以使用win32 :: job或win32 ::流程或其他其他CPAN模块从另一个PERL程序中执行此操作。

我最近发布了一个用于此类任务的模块: win32 ::独立

将其添加到您的perl脚本中,它将自我避免,从而使您的PHP脚本继续前进。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top