即使编码格式似乎正确,JSON_DECODE也会从cURL响应返回NULL?

时间:2017-06-02 21:40:42

标签: php json curl post

编辑:对于解决方案,请查看下面Barmar的回复。希望这可以帮助任何有类似问题的人。

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

- 如果我回显$内容,则会显示:

 {"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,设置卷曲标题,以及我在其他帖子上推荐的所有内容。

任何帮助都将非常感谢。先谢谢你们。

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的回复。希望这可以帮助任何有类似问题的人。

3 个答案:

答案 0 :(得分:1)

你应该做

json_encode(get_object_vars($data));
logInfo函数中的

我会推荐几件事。在函数内定义类不是一个好习惯。你应该把你的班级放在一个单独的文件中。它有助于保持代码的有序性。

其次,很好地遵循蛇案例或驼峰案例来定义类/方法/函数等。

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

答案 1 :(得分:0)

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()的代码放入不同的脚本中。

答案 2 :(得分:-1)

尝试使用此库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', '{', '['