Php 用其他函数中断一个函数

Php 用其他函数中断一个函数,php,function,symfony,loops,for-loop,Php,Function,Symfony,Loops,For Loop,我有一份symfony工作,有两个功能: 发射和停止。 我的启动功能将从数据库中导入联系人,例如4乘4,并向所有联系人发送消息 public function launchAction() { $offset = 0; $limit = 4; $sizeData /= $limit; for( $i = 0; $i < $sizeData; $i++) { $contacts = $repository->getListByL

我有一份symfony工作,有两个功能: 发射和停止。 我的启动功能将从数据库中导入联系人,例如4乘4,并向所有联系人发送消息

public function launchAction()
{
    $offset = 0;
    $limit = 4;
    $sizeData /= $limit;

    for( $i = 0; $i < $sizeData; $i++)
    {
        $contacts = $repository->getListByLimit($offset, $limit);
        $sender->setContacts($contacts);
        $sender->send();
        $offset += $limit;
    }
}

我不会完全回答,但给你两个提示,它是如何工作的

1:

在启动时保存进程id为的文件()

在stop()上,您可以检查进程是否存在并按id终止进程

2:

在launch()上,您可以在循环中检查特定的db项,以便在值存在时中断


在停止时设置此db条目

如果的唯一目的是能够停止脚本,我认为您不需要完整的事件循环实现。您可以侦听本地套接字,并在接收数据时中断

例如,您可以在
launchAction

public function launchAction()
{
    $offset = 0;
    $limit = 4;
    $sizeData /= $limit;

    // Init IPC connection
    $server = stream_socket_server("tcp://127.0.0.1:1337", $errno, $errorMessage);
    if ($server === false) {
        throw new UnexpectedValueException("Could not bind to socket: $errorMessage");
    }

    for( $i = 0; $i < $sizeData; $i++)
    {
        // Check our socket for data
        $client = @stream_socket_accept($server);
        if ($client) {
            // Read sent data
            $data = fread($client, 1024);

            // Probably break
            if ($data === 'whatever') {
                break;
            }
        }

        $contacts = $repository->getListByLimit($offset, $limit);
        $sender->setContacts($contacts);
        $sender->send();
        $offset += $limit;
    }

    // Close socket after sending all messages
    fclose($client);
}
如果您在同一台机器上运行这两个函数,则应该可以执行此操作。还要注意,PHP只能侦听尚未占用的套接字。因此,您可能需要更改端口号。如果启动第二个进程并行发送消息,新进程将无法绑定到同一套接字

一篇解释一些细节的博文是

但是,如果您希望启动一个长时间运行的流程,我建议您看看,这是一个在多个不同设置上运行的优秀事件循环实现。它还包括计时器和其他有用的lib


你可能想看看这一系列博客文章,想知道它不可能。。。。。尤其是当每个请求都在自己的独立线程中运行,因此无法与其他请求交互时threads@Alaeddine-但如果launchAction循环为空,则stopAction无法运行running@MarkBaker我可以在launchAction循环中执行类似Evloop类的操作来停止循环吗?选项3,打开unix套接字并侦听终止循环的连接。但一般来说,持久性的一种形式,例如文件或数据库条目更容易保存implement@johnSmith我可以在launchAction中执行一些操作,例如Evloop类来停止循环吗?抱歉,我没有Evloop的经验。请提问,我可以稍后拒绝:)如果我想再次重新启动发送,如何使启动功能能够知道最后一个联系人id并再次运行。您可以将其保存在某个位置,例如包含作业运行时信息的数据库/表。这是一个简单的解决方案,但任何其他方法都会导致您进入一个长期运行的流程。这意味着您的脚本将永远循环,并定期检查是否要处理任何新数据。这是乏味的设置,你需要学习更多的东西。即使这样,您也必须采取措施防止在崩溃后重新发送。
public function launchAction()
{
    $offset = 0;
    $limit = 4;
    $sizeData /= $limit;

    // Init IPC connection
    $server = stream_socket_server("tcp://127.0.0.1:1337", $errno, $errorMessage);
    if ($server === false) {
        throw new UnexpectedValueException("Could not bind to socket: $errorMessage");
    }

    for( $i = 0; $i < $sizeData; $i++)
    {
        // Check our socket for data
        $client = @stream_socket_accept($server);
        if ($client) {
            // Read sent data
            $data = fread($client, 1024);

            // Probably break
            if ($data === 'whatever') {
                break;
            }
        }

        $contacts = $repository->getListByLimit($offset, $limit);
        $sender->setContacts($contacts);
        $sender->send();
        $offset += $limit;
    }

    // Close socket after sending all messages
    fclose($client);
}
public function stopAction()
{
    $socket = stream_socket_client('tcp://127.0.0.1:1337');

    fwrite($socket, 'whatever');

    fclose($socket);
}