我可以说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
中停止循环
并且当测试者类被激怒时执行第一部分然后等待我说一分钟?
可能吗? 还是我需要别的东西?
答案 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);
?>
这就像魅力一样