php停止包含fle而继续实际文件中的循环?

时间:2011-07-07 16:18:53

标签: php

我可以说2个文件可以说一个index.php而另一个included.php

的index.php

<?php
include 'included.php';
while(true)
{
     $i++;
     sleep(3);
     $o = new tester();
}
?>

included.php

<?php
class tester{
public function __construct() {
//execute something
//wait for lets say one minute without stoping the flow of main loop.
//Rest code
}

&GT;

我想要的是不要在index.php中停止循环 并且当测试者类被激怒时执行第一部分然后等待我说一分钟?

可能吗? 还是我需要别的东西?

7 个答案:

答案 0 :(得分:6)

你不能用PHP做到这一点。它不是一种多线程语言。您可以通过并行执行另一个PHP副本来模糊地模拟它,但这不是真正的线程 - 它是两个完全独立的进程,恰好执行相同的脚本。

在单个PHP实例中,您不能同时执行两个或多个不同的脚本部分。

答案 1 :(得分:4)

问题非常笼统,但我不认为这是使用php的正确方法... usuaily php尝试尽可能快地执行事情,例如渲染网页。如果你想添加时间和动态的东西,那么每次你想要执行脚本时都必须将各个请求发送到服务器。

或许CRONJOBS或AJAX更适合你想要做的事情。

答案 2 :(得分:2)

您可以编写一个新的脚本testerStart.php,您可以通过url访问该脚本。这样你就可以在服务器上调用另一个脚本,该脚本将独立于你的初始脚本运行。

所以index.php看起来像:

<?php
  while(true)
  {
     $i++;
     sleep(3);
     // call testerStart.php asynch
  }
?>

testerStart.php看起来像:

<?php
  include 'included.php';
  $o = new tester();
?>

答案 3 :(得分:1)

您可能希望在PHP中查看PCNTL functions。我自己也没有太多的经验,但不久前偶然发现了它。它无论如何都不是真正的线程,但可能会让你更接近你想要实现的目标。

此外,如果您有PHPClasses帐户,我找到的链接可能与您相关:PHP PCNTL wrapper class

答案 4 :(得分:1)

我不确定,但你可以试试像

这样的东西
<?php
include 'included.php';
$instances = array();
while(true)
{
    foreach ($instances as $key => $instance) {
        if ($result = stream_get_contents($instance)) {
            pclose($instance);
            unset($instances[$key]);
            $o = unserialize($result);
            // do something with the object
        }
    }
    $instances[] = popen('php /path/to/include.php', 'r');
}
?>


<!-- in include.php -->
<?php
include 'included.php';
echo serialize(new tester());
?>

或者您可以将所有逻辑移动到“include.php”,因此主脚本根本不关心结果,您需要返回任何内容,以便主脚本知道它可能会关闭进程句柄。 / p>

这里我们使用popen('php /path/to/include.php', 'r');在单独的进程中启动一个脚本,并获取一个可读的管道(这样我们就可以读取该进程输出的内容)。在该单独的进程中成功创建对象后,我们序列化并输出结果。回到每个迭代的主脚本中,我们检查已经打开的实例,如果其中一些返回了某些内容 - 我们将这些内容视为序列化对象,对其进行反序列化,然后根据需要随意执行;然后在完成我们想要的操作后,我们关闭该进程并将其从打开的实例列表中删除。实际上,如果代码中的while(true)没有真正运行,而是直到满足某些条件 - 在初始化之后将处理部分移动到单独的循环中是个好主意... LIke

while($condition)
{
    $instances[] = popen('php /path/to/include.php', 'r');
}
while ( !empty($instances) ) {
    foreach ($instances as $key => $instance) {
        if ($result = stream_get_contents($instance)) {
            pclose($instance);
            unset($instances[$key]);
            $o = unserialize($result);
            // do something with the object
        }
    }
}

答案 5 :(得分:0)

您确实需要更复杂的设置。

您可能确实想要查看已经提到的pcntl函数,但这些仅在使用cli时建议。当您在Apache上的Web应用程序中需要它时,您需要查看其他解决方案,因为分叉您的过程将无法正常工作。

上述popen等其他解决方案是另一个很好的解决方案,虽然它可能会使你的代码依赖于你的架构(unix上的路径与windows上的路径不同,你需要确定'php'是可调用的,。 ..)

如果上述两种可能性都没有选项,我建议使用fsockopen的curl和stream_set_blocking禁用来执行异步http请求。 然而,这将是相当多的工作,但异步调用将使后台脚本运行,您的父脚本可以继续。然后在父进程的循环中,偶尔检查你的后台脚本是否已经完成 - 使用fsockopen:stream_get_contents($ resource)直到feof($ resource)

答案 6 :(得分:0)

我研究了更多,并且使用了我的思想和finnaly我发现了一种方式我自己做了这个:

  

的index.php

<?php
$cmd = "php -q nah.php";
exec($cmd);
while (true)
{
sleep(1);
echo "lalal";
}
?>
  

included.php

<?php
echo "yaya";
sleep(3);
?>

这就像魅力一样