Мы решили эту проблему следующим образом:
- Настройка обычного php-файла, запланированного cron. Ничего общего с кодигнитером пока нет
- Внутри него вы можете сделать запрос fsocket или curl для выполнения вашего обычного вызова CodeIgniter, как вы делаете это из Интернета.
Вот пример (скажем, 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-соединение закрыто, ваш скрипт все равно будет работать до конца.
На самом деле у нас есть куча этих fsockets по разным причинам. Если вам нужно убедиться, что вызов этого контроллера / метода поступил из скрипта cron, вам нужно передать некоторые дополнительные значения хеша, чтобы его знали только cron и скрипт. Как только скрипт вызван, он получает доступ к любым функциям codeigniter. Работает как шарм.