【问题标题】:Spawning a PHP script from inside another. Non-blockning从另一个内部生成一个 PHP 脚本。非阻塞
【发布时间】:2013-08-11 17:24:22
【问题描述】:

我有一个 PHP 脚本,需要从另一个 PHP 网页中执行。但是,要使第二个正常运行,第一个需要完全完成。本质上,我需要第一页为第二个脚本生成一个新进程/线程,该脚本将在开始前等待 1 秒。

执行包含会导致阻塞,从而阻止它工作,我无法让它开始使用 exec

编辑:

应该澄清一下。这些页面没有输出,也没有通过 Web 界面进行交互。所有页面都由来自另一台服务器的 POST 请求调用。


编辑2:

解决方案:让请求页面的服务器在第一个返回后1秒直接向第二个页面发送请求。

【问题讨论】:

标签: php multithreading


【解决方案1】:

proc_open 是正确的选择,正如@ChristopherMorrissey 指出的那样。我想在这里详细说明一下,因为使用 proc_open 有一些注意事项并不完全清楚。

在第一个代码示例@http://php.net/manual/en/function.proc-open.php 中,它显示了整体用法,我将参考它。

第一个警告是管道。管道是 PHP 中的文件流,链接到子进程的 STDIN、STDOUT 和 STDERR。在示例中,管道索引 0 表示从父 PHP 进程角度看的文件流。如果父进程写入此流,它将显示为子进程的 STDIN 输入。

在 POSIX 兼容的操作系统上,进程的 STDIN 需要在进程终止之前关闭。从父级调用管道上的 fclose 非常重要,否则您的子进程将被卡住。示例中的这一行就是这样做的:

fclose($pipes[0]);

另一个警告是检查子进程的退出代码。检查退出代码是确定子进程是否正确退出或是否出错的最佳方法。至少,您只需要知道子进程何时完成。检查这个和退出代码都是用http://www.php.net/manual/en/function.proc-get-status.php

如果要确保进程正确退出,则需要查看 proc_get_status 数组中返回的 exitcode 字段。请记住,此退出代码只会返回一次有效值。所有其他时间它将返回-1。因此,一旦它返回 > -1,这就是您的实际退出代码。所以,第一次running == false,检查exitcode

我希望这会有所帮助。

【讨论】:

  • 如问题中所述,任一页面都涉及 0 个 IO。在第一个页面完全完成并发送 HTTP 响应之前,第二个页面无法正常运行。
  • @sam 即使没有 IO,您仍然需要关闭子进程的 STDIN 管道。即使您作为程序员知道不会从父级向子级发送 IO,反之亦然,但操作系统并不知道。在 STDIN 关闭之前,操作系统不会让子进程终止。现在,在父代码中没有显式关闭管道的情况下,当父进程退出时,PHP 会自动在管道上调用 close。正是在这一点上,子进程最终将执行完成。
  • 这是为了一个概念验证系统而做的,真的不值得我花时间去尝试让它工作。它甚至可能不会在生产环境中使用 PHP。
  • 好奇,制作使用的是什么语言?
  • 它可能是 JSP,所以其他子系统的代码不需要更改。
【解决方案2】:

一个选项是在第一个脚本完成后重定向页面。

你可以这样做:

//first script here
sleep(1); //wait one second
echo "<meta http-equiv=\"refresh\" content=\"0;URL='yoursecondscript.php'\" />"; //redirect

甚至:

//first script here
//redirect after one sec 
echo "<meta http-equiv=\"refresh\" content=\"1;URL='http://thetudors.example.com/'\" />";

【讨论】:

  • 假设您在脚本 1 中有一些变量,重定向后它们会在脚本 2 上工作吗?。
  • 因为请求第一页的服务器除了确保存在 HTTP:200 之外不解析响应。
  • @YouKnowNothingJonSnow 不,您首先必须启动会话,然后从下一页调用会话变量。
【解决方案3】:

您可以在需要时将页眉写入第二页,然后将页眉放回第二页末尾的原始页。尽管此修复不起作用的原因有很多,例如 PHP 代码需要在 HTML 中。

Headers reference 比如:header(Location: seconddocument.php)

或者也许你可以把 PHP 放在一个函数中执行,然后从原始 PHP 文档中调用它。我不能完全确定您的要求,但这是我最好的两个答案。

【讨论】:

    猜你喜欢
    • 2010-10-25
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多