【问题标题】:Call JSON API from within PHP Cron Job从 PHP Cron Job 中调用 JSON API
【发布时间】:2022-09-27 10:38:14
【问题描述】:

我有一个带有 API 的大型系统。 在前端,JavaScript 使用 AJAX 与 API 对话。

我有一个 PHP 文件,它作为 CRON 作业每 5 分钟运行一次。 我希望这个 PHP 代码与 API 交互。 它必须提交的只是查询变量。 发回的只是一个数字。

例如: https://examplesite.com/api/create?id=1&data=2 这会回复一个简单的数字,即 SQL last-insert-id。

额外的: API 还需要两个 Session 变量(user-id 和 system-id) 我可以在调用我猜的 API 之前开始会话并设置它们吗? 我需要由 CRON 系统运行的 PHP 脚本来与这个 API 对话。

我试过使用 cURL 但还没有运气:

        //Need to add a user-id to session, does this work?
        session_start();
        $_SESSION[\'user-id\'] = 1;

        //HOW TO CALL API FROM CRON?
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        //curl_setopt($ch, CURLOPT_URL, \'https://example.com/api/create?id=1&gid=2\');
        //curl_setopt($ch, CURLOPT_URL, \'http://example.com/api/create?id=1&gid=2\');
        curl_setopt($ch, CURLOPT_URL, \'file://../framework/api/create.php?id=1&data=2\');

        $result = curl_exec($ch);
        curl_close($ch);
        
        $result = str_replace(\"\\n\", \'\', $result); // remove new lines
        $result = str_replace(\"\\r\", \'\', $result); // remove carriage returns
        
        //Expect Result to be a number only
        file_put_contents(\"curl.log\", \"[\".date(\'Y-m-d H:i:s\').\"] $result\\n\\n\", FILE_APPEND);

文件方法似乎不起作用......可能是../的路径问题 http 方法似乎不起作用...服务器环回问题?

任何关于如何最好地让我的 PHP CRON 机器人使用我的 API 的建议将不胜感激。 我只是将 API 代码复制到 CRON 中,但随后我在复制代码,并且不允许机器人测试真正的 API。

谢谢。

  • 会话变量使用 cookie。您需要使用保存和发送 cookie 的 curl 选项。
  • session_start() 仅适用于网页,不适用于 CLI 脚本。
  • 也许我可以只包含 PHP API 文件并捕获输出?我仍然需要为它设置 $_SESSION[\'user-id\'] ......我可以在没有启动 _session() 的情况下设置它吗?
  • 您发布的代码中的 URL 对我有用,没有任何 cookie。如果在curl_exec() 之后调用curl_error($ch),它的输出是什么?
  • 您不能将 file: URL 用作 API。 PHP 脚本只有在通过网络服务器调用时才会执行。如果您使用file:,您只需获取源代码。

标签: php api curl cron


【解决方案1】:

假设您仍然想使用会话。您的第一个 curl 应该是对将创建 SESSION 然后响应的脚本的请求。

我创建了这个 get_cookie.php 来测试这个概念:

<?php
session_start();
$_SESSION['time'] = time();
echo 'Time=' . $_SESSION['time'];
?>

我调用了这个脚本来从响应 cookie 中获取 PHPSESSID

$ch = curl_init('http://example.com/get_cookie.php');
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);

$skip = intval(curl_getinfo($ch, CURLINFO_HEADER_SIZE)); 
$head = substr($response,0,$skip);
$data = substr($response,$skip);
$end = 0;
$start = strpos($head,'Set-Cookie: ',$end);
$start += 12;
$end = strpos($head,';',$start );
$cookie = substr($head,$start ,$end-$start );
file_put_contents('cookie.txt',$cookie);
echo "\ncookie=$cookie";
echo "\n$data\n";

回复:

cookie=PHPSESSID=bc65c95468d08dd02cc5ab8ab87bbd39
Time=1664237484

CRON 作业 URL session.php:

<?php
session_start();
echo 'Time=' . $_SESSION['time'];
?>

这是 CRON 作业脚本。

$cookie = file_get_contents('cookie.txt');
$ch = curl_init('http://example.com/session.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIE, $cookie );
curl_setopt($ch, CURLOPT_HEADER, false);
$response = curl_exec($ch);
echo $response;

回复:

Time=1664237484

结果"Time" ($_SESSION['TIME']) 始终与get_cookie.php 中的时间相同。

【讨论】:

  • 谢谢,我可以试试这个。我需要的会话只是传递一个 ID,所以我真的只是想让 API 的 $_SESSION['user-id'] 返回 0(机器人的用户 ID)而不是错误。实际上,我还需要 $_SESSION['system-id'] 来返回 'TestSystem'。除此之外,我不需要真正的会话。
  • @RyanMcCormick 我的想法是您使用 curl 像实际用户一样登录。并为任何后续请求保存 PHPSESSID,它的行为应该与真实用户相同。
【解决方案2】:

感谢您的帮助,但最终我的替代方法将是最简单且效果最好的。这是其他有需要的人的答案...

要让外部 PHP(通过 CRON 运行)测试内部 PHP API(前端 JavaScript 通常通过 AJAX 与之对话),这是最简单的解决方案,包括传递查询变量和会话变量。

第 1 步:不要担心 start_session() 或传递任何查询变量,只需提前将所需内容添加到数组中即可。

第 2 步:捕获输出缓冲区并简单地包含 PHP API 文件:

        $_SESSION['user-id'] = ' works! ';
        $_REQUEST['var']     = ' too ';

        ob_start();
        include '/var/www/vhosts/customername.com/sitename.com/framework/api/create.php';
        $result = ob_get_contents();
        ob_end_clean();              

        file_put_contents("/var/www/vhosts/customername.com/sitename.com/cron/curl.log", "[".date('Y-m-d H:i:s')."] Result: $result\n\n", FILE_APPEND);

        /* OUTPUT in curl.log:
        [2022-09-26 22:30:01] Result:  works! / too 
        */

【讨论】:

    猜你喜欢
    • 2021-09-12
    • 2015-07-05
    • 2021-01-07
    • 2016-02-16
    • 2016-09-14
    • 2017-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多