【问题标题】:JSON_DECODE returning NULL from cURL response even though encode format seems correct?即使编码格式似乎正确,JSON_DECODE 从 cURL 响应返回 NULL?
【发布时间】:2017-06-02 21:40:42
【问题描述】:

编辑:有关解决方案,请查看下方 Barmar 的回复。希望这对遇到类似问题的人有所帮助。

我正在尝试从我的 test.php 文件中获取登录信息并将其 cURL 到一个站点,该站点使用数据来模拟另一个页面上的登录(我知道这很乏味,但这并不是我作为一个整体在做什么,就在我遇到问题的地方)。因此,我将编码的 json 发布到 index.php url,解码它没有问题。然后使用传递的信息并编辑解码的 json 以显示成功或不成功的登录。然后再次对 json 进行编码并回显到页面上并保存在 test.php 上的 $contents 中。当我尝试在这个文件上解码它时,我每次都得到 NULL。我已经尝试了很多东西,并且刚刚开始认为我在某个地方犯了一个愚蠢的错误,所以我拼命地在这里寻求任何帮助。

-如果我回显 $contents 它会显示:

 {"user":"user","pass":"password","success":true}

-如果我 var_dump(trim($contents)) 它显示(格式完全如图所示):

 string(364) "
 {"user":"user","pass":"password","success":true} "

-last_json_error_msg 显示:

 SYNTAX ERROR

-我尝试过修剪、utfencoding、iconv、设置 curl 标题以及我在此处其他帖子中看到的所有推荐内容。

任何帮助都将不胜感激。在此先感谢各位。

test.php:

<html>
<head>
    <meta charset="UTF-8">
    <title>TITLE</title>
</head>
<body>
    <form action="test.php" method=POST>
        <input type="text" name="user">
        <input type="password" name="pass">
        <input type="submit" value="Submit">
    </form>

    <?php
    function logInfo(){
        class data{
          public $user = "";
          public $pass = "";
          public $success = false;
        }

        $data = new data();
        $data->user = $_POST['user'];
        $data->pass = $_POST['pass'];
        $ch = curl_init();
        $json = json_encode($data);

        curl_setopt($ch, CURLOPT_URL, [URL TO INDEX.PHP]);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, array("data"=>$json));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        $contents = curl_exec($ch);
        curl_close($ch);

        $array = json_decode($contents, true);
        var_dump($array);
        //VAR_DUMP SHOWS NULL
    }

    if(isset($_POST['user']) && isset($_POST['pass'])){
        logInfo();
    }
    ?>

</body>
</html>

index.php:

<html>
    <head>
            <meta charset="UTF-8">
            <title></title>
    </head>
    <body>
            <form action="test.php" method=POST>
                <input type="hidden" name="data">
            </form>
            <?php
            header('Context-type: application/json');
            function logInfo(){
                    $datastring = $_POST['data'];
                    $data = json_decode($datastring);

                    $ch = curl_init();

                    curl_setopt($ch, CURLOPT_URL, [URL TO SIMULATE LOGIN]);
                    curl_setopt($ch, CURLOPT_POST, 1);
                    curl_setopt($ch, CURLOPT_POSTFIELDS, [LOGIN POST]);
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
                    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
                    curl_exec($ch);
                    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);


                    if($code == [SUCCESSFUL LOGIN HTTP CODE]){
                            $data->success = true;
                    } else {
                            $data->success = false;
                    }

                    echo json_encode($data);
                    curl_close ($ch);
            }
            if(isset($_POST['data'])){
                logInfo();
            }
            ?>
    </body>
</html>

编辑:有关解决方案,请查看下方 Barmar 的回复。希望这对遇到类似问题的人有所帮助。

【问题讨论】:

    标签: php json curl post


    【解决方案1】:

    index.php 在 JSON 之前打印 HTML(当var_dump() 说字符串长度为 365 个字符,但您只能看到大约 50 个字符时,您没有怀疑吗?)。当脚本用于返回 JSON 时,它不能产生任何其他输出。

    所以在打印任何输出之前检查data 参数。如果找到,则在发送 JSON 后退出脚本,这样就不会打印 HTML。

    <?php
    if(isset($_POST['data'])){
        logInfo();
        exit();
    }
    ?>
    <html>
        <head>
                <meta charset="UTF-8">
                <title></title>
        </head>
        <body>
                <form action="test.php" method=POST>
                    <input type="hidden" name="data">
                </form>
                <?php
        </body>
    </html>
    <?php
    function logInfo(){
        header('Context-type: application/json');
        $datastring = $_POST['data'];
        $data = json_decode($datastring);
    
        $ch = curl_init();
    
        curl_setopt($ch, CURLOPT_URL, [URL TO SIMULATE LOGIN]);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, [LOGIN POST]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_exec($ch);
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
    
        if($code == [SUCCESSFUL LOGIN HTTP CODE]){
            $data->success = true;
        } else {
            $data->success = false;
        }
    
        echo json_encode($data);
        curl_close ($ch);
    }
    

    一个更简单的解决方案可能是将返回 logInfo() 的代码放入不同的脚本中。

    【讨论】:

    • 感谢您的帮助。不幸的是,仍然返回 NULL。
    • 您应该查看var_dump()View Source 的输出,以防有其他HTML 元素。
    • 编辑:在测试中使用了不同的登录信息和编辑过的代码,var_dump($contents) 显示相同。
    • 查看源代码时,您仍然可以看到所有的 HTML 吗?
    • 我从页面中完全删除了所有 HTML。在那之后能够让它工作。如果您没有引起我对 cURL 中返回 HTML 的注意,就永远不会得到它。万分感谢。我从来没有使用过 PHP,所以试图弄清楚这一点是一个严肃的问题。
    【解决方案2】:

    你应该这样做

    json_encode(get_object_vars($data));
    

    在logInfo函数中

    我会推荐几件事。在函数中定义类不是一个好习惯。您应该将您的课程放在一个单独的文件中。它有助于使您的代码井井有条。

    其次,在定义类/方法/函数等时,最好遵循蛇案例或骆驼案例。

    Snake 案例 例如:my_function_name_to_execute 骆驼案例 例如:MyFunctionNameToExecute

    【讨论】:

    • 似乎根本没有任何理由来定义这个类。他可以只使用一个简单的关联数组。它们都产生相同的 JSON。
    • 改变了你所说的一切。谢谢您的帮助。不幸的是,解码时仍然为 NULL。
    • 他的问题在于json_decode(),而不是json_encode()。为什么您认为更改正在编码的对象会产生影响?
    • @Barmar 它是在我尝试不同方法时创建的,但我无缘无故离开了它。
    【解决方案3】:

    尝试使用这个库https://github.com/Seldaek/jsonlint检查生成的 JSON 语法

    更新

    它正确地检测到来自index.php 的额外 HTML 和其他可能的问题。

    下面的例子

    use Seld\JsonLint\JsonParser;
    $parser = new JsonParser();
    $exception = $parser->lint('<html>{"user":"user","pass":"password","success":true}');
    echo $exception->getMessage();
    

    将输出:

    Parse error on line 1:
    <html>{"user":"user"
    ^
    Expected one of: 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-03
      • 1970-01-01
      • 2015-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多