【问题标题】:cURL request in PHP script works via browser but not CRONPHP 脚本中的 cURL 请求可通过浏览器工作,但不能通过 CRON
【发布时间】:2018-05-10 17:13:56
【问题描述】:

我知道对此有疑问,但到目前为止,没有人能帮助我解决我的问题。

我有一个 PHP 脚本,它的工作是发送预定的电子邮件。它通过 cURL 调用我控制的 Web 服务来实现这一点。

在浏览器中运行,一切正常。通过 CRON 运行,cURL 响应为空。它永远不会到达网络服务;我知道这一点是因为我让 WS 在联系时写入了一个文本文件。如果您通过浏览器访问,而不是通过 CRON 访问,则可以。

我知道 CRON 在不同的环境中运行,我不依赖任何环境变量,例如$_SERVERrequire() 的路径也不是问题,因为它成功地从该文件中获取数据以连接到数据库。

This question 建议添加以下 cURL 选项,我已经这样做了,但没有骰子:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);

这是我的 PHP 脚本:

//prep
define('WS_URL', 'http://mywebservicedomain.com/index.php/web_service');
require '../application/config/database.php';
$db = new mysqli($db['default']['hostname'], $db['default']['username'], $db['default']['password'], $db['default']['database']) or die('failed to connect to DB');

//get scheduled e-mails
$res = $db->query('SELECT * FROM _cron_emails WHERE send_when < NOW()');

//process each...
while ($email_arr = $res->fetch_assoc()) {

    //...get API connection info
    $api_accnt = $db->query($sql = 'SELECT id, secret FROM _api_accounts WHERE project = "'.$email_arr['project'].'"');
    $api_accnt = $api_accnt->fetch_assoc();

    //...recreate $_POST env
    $tmp = json_decode($email_arr['post_vars'], 1);
    $_POST = array();
    foreach($tmp as $key => $val) $_POST[$key] = !is_array($val) ? $val : implode(',', $val);

    //...call API to send e-mail
    $ch = curl_init($url = WS_URL.'/send_scheduled_email/'.$email_arr['email_id'].'/'.$email_arr['store_id'].'/'.$email_arr['item_id']);
    curl_setopt_array($ch, array(
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_SAFE_UPLOAD => true,
        CURLOPT_SSL_VERIFYHOST => 1, //<-- tried adding this
        CURLOPT_SSL_VERIFYPEER => 1, //<-- ditto
        CURLOPT_POSTFIELDS => array_merge($_POST, array(
            'api_key' => $api_accnt['id'],
            'api_secret' => $api_accnt['secret'],
        ))
    ));
    $resp = curl_exec($ch); //<-- empty when CRON

    //if e-mail was sent OK, or decider script said it was ineligible, delete it from the queue
    if (($resp == 'ok' || $resp == 'ineligible'))
        $db->query('DELETE FROM _cron_emails WHERE id = '.$email_arr['id'].' LIMIT 1');

}

有谁知道为什么只有在 CRON 中运行时它无法通过 cURL 连接到我的 Web 服务?

这是 CRON 作业:

/usr/bin/php /home/desyn/public_html/cron/send_scheduled_emails.php

【问题讨论】:

  • 检查路径和 SSL
  • 你能再具体一点吗? CRON 脚本的路径?它正在执行,就像我说的那样,require() 的路径也在执行。
  • 您的(错误)日志中有什么内容吗?您使用的实际 cron 语法是什么?
  • 有时 PHP 配置文件对于 CLI 和 web 是不同的;我建议你从 bash 运行你的 cron 命令并从那里开始工作。
  • 一种可能的解决方法是 wget/curl 您面向公众的 url 作为 cron 作业,以确保相同的环境。

标签: php web-services curl cron


【解决方案1】:

最后证明这是一个非常特殊的问题,我想这是不常见的问题。我怀疑它对其他人的帮助太大,但我把它留在这里以防万一。

基本上,我的服务器不喜欢通过域进行 cURL。

CRON 脚本中 cURL 调用的服务器与运行 CRON 任务的服务器相同(但不同的帐户和网站。)

通过浏览器证明这不是问题;只能通过 CRON。

将 cURL 请求更改为使用服务器的本地 IP,而不是使用域,解决了这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    • 2014-09-02
    • 1970-01-01
    • 2017-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多