【问题标题】:Cron job outputting the default controller输出默认控制器的 Cron 作业
【发布时间】:2015-01-26 18:31:51
【问题描述】:

问题

我正在为我的网站使用 CodeIgniter v2.1.4。我已经使用以下命令 php -q /home/user_name/www/index.php controller my_method 设置了一个 cronjob 每 2 小时运行一次。但是,这会输出我的默认控制器页面 html 内容(这是我主页的 html 内容)。

尝试过

我用一个简单的回显在我的 www 目录中添加了另一个名为 test.php 的文件,它运行正确,因此我确信问题存在于 CI 中。此外,当我使用浏览器访问我试图通过 cron 作业执行的控制器/方法时,它会输出正确的消息。

所需的解决方案

我按照另一个线程的建议使用了wget -q http://mywebsite.com/controller/my_method,它工作正常,但我想使用php -q 方式,因为这样我就可以拒绝从浏览器直接访问我的脚本。

【问题讨论】:

  • PHP 之后-q 是干什么用的?我似乎无法找到它的参考。
  • 我也找了,但没找到。我的托管服务提供商告诉我以这种方式使用它。
  • 我认为这是在 Linux 机器上?
  • 是的,它的 Linux。 @RossWilson 你知道解决办法吗?
  • 您是否安装了php5-cli?你能用sudo apt-get install php5-cli安装它吗?

标签: php codeigniter cron


【解决方案1】:

CodeIgniter 使用 CLI 请求。所以你需要使用 PHP CLI。

/usr/bin/php-cli  /home/user_directory/public_html/index.php controller method

如果您的服务器上没有 PHP CLI,还有另一种选择;

您可以在 CodeIgniter 上启用查询字符串并尝试像这样运行。

php -q /home/user_directory/public_html/index.php?c=controller&m=method

有关启用查询字符串的更多信息:CodeIgniter URLS

【讨论】:

  • 在 CodeIgniter 3.10 上,我的 cron 回退到默认控制器,因为我使用的是 /usr/bin/php 而不是 /usr/bin/php-cli。这篇文章也为我解决了这个问题。
【解决方案2】:

应该只是(来自 cPanel):

php /home/user_name/www/index.php controller method

但是,如果您使用命令行并且输入了crontab -e

30 2 * * * php /home/username/index.php welcome show

上面的示例将在每天凌晨 2:30 运行。

希望这会有所帮助!

【讨论】:

  • 是的,我是从 cPanel 设置的,您在第一行中提到的命令与我使用的命令几乎相同。但它仍然无法正常工作。
  • 你能 ssh 到你的服务器吗?
  • 我试过了,它说你的服务器上没有启用 shell 访问。所以不..我在服务器上也有一个 .htaccess 文件,你认为它也可以路由 php cron 作业请求吗?
  • 不,因为(除非我弄错了).htaccess 文件纯粹用于 apache,而 cronjobs 不是特定于 php 的。最后,我假设您在路径中使用实际的user_name 而不仅仅是字符串“user_name”?
  • 是的,我使用的是正确的用户名,而不是我在问题中提出的 user_name 字符串。我使用另一个 cronjob 只是为了回显一个简单的字符串,它工作得很好。所以当我尝试调用codeigniter index.php时,问题就真的来了。有什么方法可以调试这个问题吗?
【解决方案3】:

我很抱歉没有更好地了解 CodeIgnitre,但我想提一下命令行 PHP 和通过 Web 服务器的 PHP 使用不同的环境变量(特别是可以使用不同的 php.ini 文件)以及诸如重写和其他处理之类的东西Web 服务器可能会(特别是通过 .htaccess,但有时也在主配置中)可能会导致此处出现问题。

如果您在 PHP 脚本中运行 phpinfo() 函数,它会告诉您应该使用它正在使用的 php.ini 文件。

我假设您已经检查了您的控制器和方法,并确保它们的拼写准确无误(我不知道这是否需要大写)。

您可以做一个简单的测试,使用您的 CodeIgniter 脚本来回显它认为您要求的控制器和方法。我猜你的命令行/cron 没有正确传递变量,它默认为主主页作为后备。

【讨论】:

    【解决方案4】:

    我昨天学到的是,您需要将控制器的功能限制为仅用于控制台,在控制器构造函数中阻止其 Web 调用

    class Hello extends CI_Controller {
        function __construct() {
            if (isset($_SERVER['REMOTE_ADDR'])) {
                die('Command Line Only!');
            }
            parent::__construct();
        }
        public function message($to = 'World'){
            echo "Hello {$to}!".PHP_EOL;
        }
    }
    

    然后,您需要在 ci 文件的根目录下创建一个cli.php 命令行文件

    if (isset($_SERVER['REMOTE_ADDR'])) {
        die('Command Line Only!');
    }
    
    set_time_limit(0);
    
    $_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'] = $argv[1];
    
    require dirname(__FILE__) . '/index.php';
    

    最后,为了运行命令,您在控制台中输入以下内容:

    php cli.php Hello message
    

    或者

    php cli.php Hello message "parameter" 
    

    输出将是 "Hello World!""Hello parameter!",您可能需要对控制器和函数名称进行一些调整,更多信息请参见 link 以及 codeigniter 的 cli 文档。

    【讨论】:

      【解决方案5】:

      在项目的根目录下创建一个 executeCron.php 文件,内容如下:

      #!/usr/local/bin/php
      <?php
      
      /*
      |--------------------------------------------------------------
      | CRON JOB BOOTSTRAPPER
      |--------------------------------------------------------------
      
      | PURPOSE
      | -------------------------------------------------------------
      | This script is designed to enable CodeIgniter controllers and functions to be easily called from the command line on UNIX/Linux systems.
      |
      |
      | SETUP
      | -------------------------------------------------------------
      | 1) Place this file somewhere outside your web server's document root
      | 2) Set the CRON_CI_INDEX constant to the location of your CodeIgniter index.php file
      | 3) Make this file executable (chmod a+x cron.php)
      | 4) You can then use this file to call any controller function:
      |    ./cron.php --run=/controller/method [--show-output] [--log-file=logfile] [--time-limit=N] [--server=http_server_name]
      |
      |
      | OPTIONS
      | -------------------------------------------------------------
      |   /controller/method   Required   The controller and method you want to run.
      
      |
      | NOTE: Do not load any authentication or session libraries in controllers you want to run via cron. If you do, they probably won't run right.
      
      */
      
          define('CRON_CI_INDEX', dirname(__FILE__)."/index.php");   // Your CodeIgniter main index.php file
          define('CRON', TRUE);   // Test for this in your controllers if you only want them accessible via cron
      
      
      # Parse the command line
      
          $script = array_shift($argv);
          $cmdline = implode(' ', $argv);
          $usage = "Usage: executeCron.php /login/index \n\n";
          $required = array('--run' => FALSE);
          foreach($argv as $arg)
          {
             /*switch($arg)
              {
                 case 'cronRemoveStories/index':*/
                      // Simulate an HTTP request
                      //$_SERVER['PATH_INFO'] = $arg;
                      $_SERVER['REQUEST_URI'] = $arg;
                      $_SERVER['REMOTE_ADDR'] = '';
                      $required['--run'] = TRUE;
                      break;
      
                 /* default:
                      die($usage);
              }*/
          }
      
          if(!defined('CRON_LOG')) define('CRON_LOG', 'cron.log');
          if(!defined('CRON_TIME_LIMIT')) define('CRON_TIME_LIMIT', 0);
      
          foreach($required as $arg => $present)
          {
              if(!$present) die($usage);
          }
      
      
      
      # Set run time limit
          set_time_limit(CRON_TIME_LIMIT);
      
      
      # Run CI and capture the output
          ob_start();
      
         if(file_exists(CRON_CI_INDEX)){
              require(CRON_CI_INDEX);           // Main CI index.php file
         }else{
              die(CRON_CI_INDEX." not found.");
         }
         $output = ob_get_contents();
         ob_end_clean();
      
      # Log the results of this run
          error_log("### ".date('Y-m-d H:i:s')." cron.php $cmdline\n", 3, CRON_LOG);
      ?>
      

      现在编写您的控制器并按如下方式配置 Crontab(如果需要,请更正您的文件路径):

      0 */2 * * * php /home/user_name/www/executeCron.php --run=/controllername/methodname

      【讨论】:

        【解决方案6】:

        在 crontab 中你也可以使用 curl 来更好的运行 URL

        所以你可以这样做

        */10 *  *  *  *     curl 'http://www.example.com/controller/action'
        

        希望对你有帮助

        【讨论】:

        • 是的。但是我将无法区分浏览器请求和直接 url 访问。
        【解决方案7】:

        我遇到了同样的问题。我尝试了很多东西。最后,显示 index.php 的原因是因为我的 config.php 中的以下行设置为“QUERY_STRING”

        当我把它改成下面的时候

        $config['uri_protocol']= "AUTO";

        它按预期工作。

        希望对你有帮助

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-01-06
          • 2012-08-02
          • 1970-01-01
          • 1970-01-01
          • 2016-04-03
          • 1970-01-01
          • 2013-02-05
          相关资源
          最近更新 更多