Php 如何使用RabbitMQ在CodeIgniter中重新加载代码更改?

Php 如何使用RabbitMQ在CodeIgniter中重新加载代码更改?,php,codeigniter,rabbitmq,Php,Codeigniter,Rabbitmq,我使用带有RabbitMQ的CodeIgniter框架来执行耗时的活动,例如发送电子邮件、生成PDF 每当我在PHP文件(比如库或控制器)中更改代码,直到我重新启动Apache,旧代码都会由RabbitMQ执行。如何解决这个问题 控制器中的函数 public function receive() { $this->db->reconnect(); $connection = new AMQPStreamConnection('localhost', 5672, 'gu

我使用带有RabbitMQ的CodeIgniter框架来执行耗时的活动,例如发送电子邮件、生成PDF

每当我在PHP文件(比如库或控制器)中更改代码,直到我重新启动Apache,旧代码都会由RabbitMQ执行。如何解决这个问题

控制器中的函数

public function receive()
{
    $this->db->reconnect();
    $connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
    $channel = $connection->channel();
    $channel->queue_declare('generate_pdf', false, false, false, false);
    echo "[*] Started listening to connections... To exit press CTRL+C\n";
    $generate_pdf = function ($data)
    {
        $this->generatepdf->generate($data); // Generatepdf.php library -> generate() function
    };
    $channel->basic_qos(null, 1, null);
    $channel->basic_consume('generate_pdf', '', false, true, false, false, $generate_pdf)

    while ($channel->is_consuming())
    {
        $channel->wait();
    }
}
从termimal开始

php index.php Controllerfile.php接收

这工作正常。因此,当作业被推送到队列时,将调用库文件Generatepdf.php中的generate函数并完成执行

但是,如果我通过编辑器修改generate函数,或者重新上传带有更改的文件,这些更改在我重新启动Apache服务器之前不会反映出来

更改前的功能定义:

public function generate()
{
    echo "Hello the data is 250";
}
输出:你好,数据是250

更改后的函数定义:

public function generate()
{
    echo "Hello the data is 251";
}
重启Apache之前的输出:您好,数据是250

重启Apache后的输出:您好,数据是251


为什么会发生这种情况?如何执行以刷新文件中的更改?

显示的代码包含以下循环:

while ($channel->is_consuming())
{
    $channel->wait();
}
这意味着除非与RabbitMQ的连接中断,否则请等待新消息,处理它,然后再次等待,直到永远。换句话说,它是一个无限循环,运行它的PHP进程不会退出,除非您杀死它

与我看到的一些描述相反,PHP是一种编译语言,而不是解释语言:当一个PHP进程被要求加载一个PHP代码文件时,它会查看一次,将其编译成一个称为op代码的机器友好表示形式,然后不需要再次查看它来执行其中的代码。因此,当您编辑文件时,已经运行的进程不会注意到,也不会编译新代码

如果希望加载新代码,则需要退出无限循环,因此流程结束,然后启动一个新的流程,该流程将编译新代码。例如,您可以在循环中检查某个特定文件,测量它运行的时间,或者侦听告诉它退出的特殊消息。然后,您可以使用类似supervisord的工具来确保脚本在退出时重新运行,或者只需要执行cron任务来定期启动新副本


另外一点:PHP有一个名为OpCache的特性,它甚至在进程之间重用文件的编译版本,以获得更好的性能。默认情况下,它会查看文件的时间戳以决定是否重新编译它,因此会注意到是否编辑了文件,但为了获得最佳性能,可以关闭该检查。如果这就是问题所在,那么您将在所有PHP代码中看到这一点,而不仅仅是RabbitMQ循环。

您显示的代码包含以下循环:

while ($channel->is_consuming())
{
    $channel->wait();
}
这意味着除非与RabbitMQ的连接中断,否则请等待新消息,处理它,然后再次等待,直到永远。换句话说,它是一个无限循环,运行它的PHP进程不会退出,除非您杀死它

与我看到的一些描述相反,PHP是一种编译语言,而不是解释语言:当一个PHP进程被要求加载一个PHP代码文件时,它会查看一次,将其编译成一个称为op代码的机器友好表示形式,然后不需要再次查看它来执行其中的代码。因此,当您编辑文件时,已经运行的进程不会注意到,也不会编译新代码

如果希望加载新代码,则需要退出无限循环,因此流程结束,然后启动一个新的流程,该流程将编译新代码。例如,您可以在循环中检查某个特定文件,测量它运行的时间,或者侦听告诉它退出的特殊消息。然后,您可以使用类似supervisord的工具来确保脚本在退出时重新运行,或者只需要执行cron任务来定期启动新副本


另外一点:PHP有一个名为OpCache的特性,它甚至在进程之间重用文件的编译版本,以获得更好的性能。默认情况下,它会查看文件的时间戳以决定是否重新编译它,因此会注意到是否编辑了文件,但为了获得最佳性能,可以关闭该检查。如果这就是问题所在,那么您将在所有PHP代码中看到这一点,而不仅仅是RabbitMQ循环。

好的,非常感谢您的详细解释。现在我明白了:非常感谢你的详细解释。现在我明白了这个问题: