无法使用PHP中的curl从API获取json响应

时间:2019-03-25 14:21:32

标签: php ajax curl

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

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响应。我真的不明白我在这里缺少什么。谁能帮我理解这个问题?谢谢

2 个答案:

答案 0 :(得分:1)

也许以下内容可能会有所帮助-由于端点是https,因此您应该在curl request函数中设置其他选项来处理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
}

答案 1 :(得分:0)

先在您的Ajax调用中添加:

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

之后,您的PHP错误。您尝试回显数组。

$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