共享主机上的 CodeIgniter Cron 作业?

Posted

技术标签:

【中文标题】共享主机上的 CodeIgniter Cron 作业?【英文标题】:CodeIgniter Cron Job on Shared Hosting? 【发布时间】:2012-01-10 01:30:26 【问题描述】:

我正在尝试学习如何使用 CodeIgniter 完成我的第一份 cron 工作。过去,使用 CI 执行此操作的唯一方法似乎是使用 wget 命令而不是 php

不过,CodeIgniter User Guide 表示现在您可以从命令行执行此操作,例如通过运行:

$ cd /path/to/project;
$ php index.php controller method

在我的本地设置中使用终端非常有用。但是当我在共享主机上的 cPanel 的 cron 部分中使用类似的命令时,该任务只会返回 index.php 的内容。

我不完全确定 cPanel 对这个命令做了什么,所以不确定它是否在使用命令行。

谁能解释一下我如何能够使用 CodeIgniter 在共享主机上设置 cron 作业?

以下是 CodeIgniter 用户指南中的示例代码:

tools.php

public function message($to = 'World')

    echo "Hello $to!".PHP_EOL;

?>

【问题讨论】:

你的控制器方法是做什么的? 现在我只是在尝试 CodeIgniter 用户指南中的 Hello World 示例。为什么,这会如何影响答案? 【参考方案1】:

这将取决于您的主机。如果您不小心,Cron 作业可能真的搞砸了,所以很多共享主机都不允许这样做。您可能需要在某个虚拟容器(如 VPS、virtuozo 等)上执行此操作。这不是 CodeIgniter 问题,而是托管服务提供商问题。先给他们打电话。

【讨论】:

虽然我确定你是对的,但我可以使用普通的 PHP 运行一个 cron 作业,并将文件放在 CodeIgniter 根目录中。但我觉得使用 CodeIgniter 比单独使用 PHP 要舒服得多。 好的,很高兴知道。在您的 cron 定义中,您使用的是 php 二进制文件的完整路径吗?此外,请确保您没有引用 $_SERVER 或任何未在 CLI 中定义的全局变量。我要检查的最后一件事是 gzip 是否搞砸了你的输出。我敢肯定还有更多,但这些是我脑海中的第一个......【参考方案2】:

我们解决了这个确切的问题如下:

    设置一个由 cron 调度的普通 php 文件。与 codeigniter 无关 在其中,您可以发出 fsocket 或 curl 请求来执行常规 CodeIgniter 调用,就像您从 Web 执行的操作一样。

这是一个例子(比如 cron.php)

#!/usr/local/bin/php.cli
<?php
DEFINE('CRON_CALL_URL','https://my_server/'); // 

DEFINE('CRON_HTTPS_PORT', 443); // port to use during fsocket connetion
DEFINE('CRON_SSL_PREFIX', 'ssl://'); // prefix to be used on the url when using ssl
$current_time = now();
$md5_hash = md5('somevalue'.$current_time);
        $url = CRON_CALL_URL.'MYCTRL/MYMETHOD'; 
        $parts=parse_url($url);
        // 
        $parts['query']='md5_hash='.$md5_hash.'&time='.$current_time;    
        $fp = fsockopen(CRON_SSL_PREFIX.$parts['host'],
            isset($parts['port'])?$parts['port']:CRON_HTTPS_PORT,
            $errno, $errstr, 30);

        if (!$fp) 
         else 

            if (!array_key_exists('query', $parts)) $parts['query'] = null;
            $out = "POST ".$parts['path']." HTTP/1.1\r\n";
            $out.= "Host: ".$parts['host']."\r\n";
            $out.= "Content-Type: application/x-www-form-urlencoded\r\n";
            $out.= "Content-Length: ".strlen($parts['query'])."\r\n";
            $out.= "Connection: Close\r\n\r\n";
            if (isset($parts['query'])) $out.= $parts['query'];

            fwrite($fp, $out);
            fclose($fp);
        

?>

注意:确保在您的 MYCTRL/MYMETHOD 函数中有

ignore_user_abort(true);

这样,当您关闭 fsocket 连接时,您的脚本仍将运行到最后。

出于各种原因,我们实际上有一堆这样的 fsocket。如果您需要确保对该控制器/方法的调用来自 cron 脚本,则需要传递一些额外的哈希值,以便只有 cron 和脚本知道它。一旦脚本被调用,它就可以访问任何 codeigniter 函数。像魅力一样工作。

【讨论】:

【参考方案3】:

我在共享主机上设置了 100 多个 CI cronjob,如下所示:创建一个简短的 php 脚本,它调用 CI 控制器,就好像它是一个网络浏览器一样。

所以,script.php 包含以下内容:

      script #! /usr/local/bin/php -f /home/example/public_html/script.php 

  <?php
     get_get_contents('http:example.com/cronjob/');     
  ?>

然后在 cPanel 中设置你的 cronjob 来调用 script.php 当它运行时 Script.php 将调用 Codeigniter Cronjob 控制器。您可以使用整个 CI 框架。

【讨论】:

【参考方案4】:

如果你要像网络浏览器一样调用它,为什么不替换 cronjob 命令:

wget http://example.com/cronjob/

而不是创造新的东西或简单地

curl --suppress http://example.com/cronjob/`

【讨论】:

以上是关于共享主机上的 CodeIgniter Cron 作业?的主要内容,如果未能解决你的问题,请参考以下文章

如何为服务器上的 codeigniter 脚本设置 cron 作业

cron 命令在共享主机中无法与 DirectAdmin 一起使用

如何在共享主机中为 Lumen 应用程序设置 cron 作业(使用 CPanel)?

在不同主机上的 Docker 中运行 cron 的问题

使用 cron 作业“访问页面”

Codeigniter 中的 Cron 作业