【问题标题】:Unable to get the json response from API using curl in PHP无法在 PHP 中使用 curl 从 API 获取 json 响应
【发布时间】:2019-08-15 19:44:00
【问题描述】:

我正在开发一个网页,用户将在其中输入数字,该数字将用作 API 调用的查询参数,并且需要在网页中显示响应。我正在使用以下命令在同一 mac 上运行这个本地 mac 和 php 服务器

php -S localhost:8080 -t /Users/demouser/my_website

我已使用 phpinfo() 验证了 curl 已启用。

我在 HTML 文件中有以下函数,将使用 javascript 点击按钮调用。

function performRequest(todoid) {
        $.ajax({
            url:"api_call.php", 
            type: "GET", 
            data: { todoid: todoid },
            success:function(result){
                console.log("JS result"+result);
           }
        });
    }

我的 PHP 文件如下所示

    <?php
    if (isset($_GET['todoid'])) 
    {
        callExternalAPI($_GET['todoid']);
    }

    function callExternalAPI($todoid) 
    {
        $result = callAPI("https://jsonplaceholder.typicode.com/todos/".$todoid);
        print_r("Result from URL".$result);
        $info = json_decode($result, true);
        echo("Info from API".$info);
    }

    function callAPI($url)
    {
        $curlObj = curl_init();
        curl_setopt($curlObj, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curlObj, CURLOPT_ENCODING, "identity");
        curl_setopt($curlObj, CURLOPT_URL, $url);
        if (!$result = curl_exec($curlObj))
        {
            echo "Failed to perform request".curl_error($curlObj);
        }
        curl_close($curlObj);
        return $result;
    }
?>

但在 Ajax 成功回调中,我得到了

JS resultResult from URLhttps://jsonplaceholder.typicode.com/todos/1Info from API

当我在浏览器或邮递员中点击相同的 API 时,我得到了正确的 json 响应。我真的不明白我在这里缺少什么。谁能帮我理解这个问题?谢谢

【问题讨论】:

    标签: php ajax curl


    【解决方案1】:

    也许以下可能会有所帮助 - 由于端点是 https,您应该在 curl 请求函数中设置其他选项来处理 SSL。下面的 curl 函数是我经常使用的东西的简化版

    <?php
    
        /* https://stackoverflow.com/questions/55339967/unable-to-get-the-json-response-from-api-using-curl-in-php */
        /* jsonplaceholder.typicode.com api experiments */
    
    
        if( isset( $_GET['todoid'] ) ){
    
            $id=filter_input( INPUT_GET, 'todoid', FILTER_SANITIZE_NUMBER_INT  );
    
            /* utility to quickly display data in readable fashion */
            function pre( $data=false, $header=false, $tag='h1' ){
                if( $data ){
                    $title = $header ? sprintf('<'.$tag.'>%s</'.$tag.'>',$header) : '';
                    printf('%s<pre>%s</pre>',$title,print_r($data,1));
                }
            }
    
            /* basic curl request helper */
            function curl( $url ){
                /* set an appropriate path to YOUR cacert.pem file */
                $cacert='c:/wwwroot/cacert.pem';
    
                $curl=curl_init();
                if( parse_url( $url,PHP_URL_SCHEME )=='https' ){
                    curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, true );
                    curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, 2 );
                    curl_setopt( $curl, CURLOPT_CAINFO, $cacert );
                }
                curl_setopt( $curl, CURLOPT_URL,trim( $url ) );
                curl_setopt( $curl, CURLOPT_AUTOREFERER, true );
                curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
                curl_setopt( $curl, CURLOPT_FAILONERROR, true );
                curl_setopt( $curl, CURLOPT_HEADER, false );
                curl_setopt( $curl, CURLINFO_HEADER_OUT, false );
                curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
                curl_setopt( $curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36' );
                curl_setopt( $curl, CURLOPT_MAXREDIRS, 10 );
                curl_setopt( $curl, CURLOPT_ENCODING, '' );
    
                $res=(object)array(
                    'response'  =>  curl_exec( $curl ),
                    'info'      =>  (object)curl_getinfo( $curl ),
                    'errors'    =>  curl_error( $curl )
                );
                curl_close( $curl );
                return $res;
            }
    
            function callapi( $id ){
                $url=sprintf( 'https://jsonplaceholder.typicode.com/todos/%s',$id );
                return curl( $url );
            }
    
    
    
    
            /* call the api */
            $res = callapi( $id );
    
    
            /* process response data */
            if( $res && $res->info->http_code==200 ) {
                /* to debug */
                pre( $res->response, 'Response data' );
    
                /* live */
                #exit( $res->response );
            }
        }
    ?>
    

    示例输出:

    响应数据

    {
      "userId": 2,
      "id": 23,
      "title": "et itaque necessitatibus maxime molestiae qui quas velit",
      "completed": false
    }
    

    【讨论】:

    • 感谢您提供详细的 cmets 和代码。它按预期工作。
    【解决方案2】:

    好的,首先在你的 ajax 调用中添加:

     url:"api_call.php", 
                type: "GET", 
                data: { todoid: todoid },
                dataType : "json",
    

    之后,您的 php.ini 文件中出现错误。你尝试回显一个数组。

    $info = json_decode($result, true);   // this line will get you an array
    print_r($info);   // this is the way to print the array. Echo is used for strings
    

    只是一个小建议,我看不出有任何理由在 ajax 成功中返回 json 和具有 相同数据 的数组。仅返回您的 json 并使用 javascript 处理数据。

    你可以做的是简单地使用你已经拥有的这行代码:

    echo("Result from URL".$result); // you can echo that one since it's just a json string
    

    【讨论】:

    • OP正在回显一个字符串,所以设置$info = json_decode($result, true);会导致ajax请求失败。
    • 是的,他正在回显一个 json 字符串,但随后他对其进行解码并尝试回显该字符串。这就是它失败的地方,因为他得到一个字符串到数组的转换错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    • 1970-01-01
    • 2015-05-21
    • 2017-12-20
    • 1970-01-01
    • 2015-06-02
    • 1970-01-01
    相关资源
    最近更新 更多