使用 PHP 读取 JSON POST

Posted

技术标签:

【中文标题】使用 PHP 读取 JSON POST【英文标题】:Reading JSON POST using PHP 【发布时间】:2013-10-01 00:53:21 【问题描述】:

在发布这个问题之前我环顾四周,所以如果它在另一个帖子上,我很抱歉,这只是我在这里的第二个问题,所以如果我没有正确格式化这个问题,我很抱歉。

我创建了一个非常简单的 Web 服务,它需要获取 post 值并返回 JSON 编码的数组。这一切都很好,直到我被告知我需要使用 application/json 的内容类型发布表单数据。从那以后,我无法从 Web 服务返回任何值,这肯定与我如何过滤它们的帖子值有关。

基本上在我的本地设置中,我创建了一个执行以下操作的测试页面 -

$curl = curl_init();
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");                                                                     
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);                                                                  
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);                                                                      
curl_setopt($curl, CURLOPT_HTTPHEADER, array(                                                                          
    'Content-Type: application/json',                                                                                
    'Content-Length: ' . strlen($data))                                                                       
);
curl_setopt($curl, CURLOPT_URL, 'http://webservice.local/');  // Set the url path we want to call
$result = curl_exec($curl);

//see the results
$json=json_decode($result,true);
curl_close($curl);
print_r($json);

在网络服务上我有这个(我已经剥离了一些功能)-

<?php

header('Content-type: application/json');

/* connect to the db */
$link = mysql_connect('localhost','root','root') or die('Cannot connect to the DB');
mysql_select_db('webservice',$link) or die('Cannot select the DB');

if(isset($_POST['action']) && $_POST['action'] == 'login') 
    $statusCode = array('statusCode'=>1, 'statusDescription'=>'Login Process - Fail');
    $posts[] = array('status'=>$statusCode);
    header('Content-type: application/json');
    echo json_encode($posts);

    /* disconnect from the db */

@mysql_close($link);

?>

基本上我知道这是由于未设置 $_POST 值,但我找不到需要放置的内容来代替 $_POST。我试过了 json_decode($_POST)、file_get_contents("php://input") 和其他一些方法,但我有点摸不着头脑。

任何帮助将不胜感激。

谢谢,史蒂夫

感谢迈克尔的帮助,这是向前迈出的明确一步

更新 CURL -

  $curl = curl_init();
  curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); 
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); 
  curl_setopt($curl, CURLOPT_URL, 'http://webservice.local/');  
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));

更新了数据发布到的页面上的 php -

$inputJSON = file_get_contents('php://input');
$input= json_decode( $inputJSON, TRUE ); //convert JSON into array

print_r(json_encode($input));

正如我所说,至少我现在看到一个响应,而之前它返回一个空白页面

【问题讨论】:

不确定失败是什么,但恕我直言,第一步是打印出 $_POST 的内容以查看其中的内容。如果数据在那里,则很容易处理它们。如果 $_POST 为空,至少你知道问题出在哪里。 【参考方案1】:

您有空的$_POST。如果您的网络服务器想要查看 json 格式的数据,您需要读取原始输入,然后使用 JSON 解码对其进行解析。

你需要这样的东西:

$json = file_get_contents('php://input');
$obj = json_decode($json);

您还有错误的测试 JSON 通信的代码...

CURLOPT_POSTFIELDS 告诉curl 将您的参数编码为application/x-www-form-urlencoded。这里需要 JSON 字符串。

更新

你的测试页面的php代码应该是这样的:

$data_string = json_encode($data);

$ch = curl_init('http://webservice.local/');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
        'Content-Length: ' . strlen($data_string))
);

$result = curl_exec($ch);
$result = json_decode($result);
var_dump($result);

同样在您的网络服务页面上,您应该删除header('Content-type: application/json'); 中的一行。它只能被调用一次。

【讨论】:

谢谢迈克尔,帮了大忙,你能看看我的编辑,看看你是否能看到导致我问题的其他任何东西? 伙计,这太有帮助了!代码 $json = file_get_contents('php://input'); $obj = json_decode($json);完美运行 我害怕要花一整天的时间来完成这项任务......但是很酷,它在不到 2 分钟的时间内就成功了!非常感谢,现在我可以假装很辛苦,请假一天...... 对我有帮助 $json = file_get_contents('php://input'); $obj = json_decode($json, true);否则我有错误“不能使用 stdClass 类型的对象作为数组”。我发送的 $data 是 json 格式的对象。【参考方案2】:

你好,这是我的一个旧项目的 sn-p,它使用 curl 从一些免费的 ip 数据库服务中获取 ip 信息,这些服务以 json 格式回复。我想它可能会对你有所帮助。

$ip_srv = array("http://freegeoip.net/json/$this->ip","http://smart-ip.net/geoip-json/$this->ip");

getUserLocation($ip_srv);

功能:

function getUserLocation($services) 

        $ctx = stream_context_create(array('http' => array('timeout' => 15))); // 15 seconds timeout

        for ($i = 0; $i < count($services); $i++) 

            // Configuring curl options
            $options = array (
                CURLOPT_RETURNTRANSFER => true, // return web page
                //CURLOPT_HEADER => false, // don't return headers
                CURLOPT_HTTPHEADER => array('Content-type: application/json'),
                CURLOPT_FOLLOWLOCATION => true, // follow redirects
                CURLOPT_ENCODING => "", // handle compressed
                CURLOPT_USERAGENT => "test", // who am i
                CURLOPT_AUTOREFERER => true, // set referer on redirect
                CURLOPT_CONNECTTIMEOUT => 5, // timeout on connect
                CURLOPT_TIMEOUT => 5, // timeout on response
                CURLOPT_MAXREDIRS => 10 // stop after 10 redirects
            ); 

            // Initializing curl
            $ch = curl_init($services[$i]);
            curl_setopt_array ( $ch, $options );

            $content = curl_exec ( $ch );
            $err = curl_errno ( $ch );
            $errmsg = curl_error ( $ch );
            $header = curl_getinfo ( $ch );
            $httpCode = curl_getinfo ( $ch, CURLINFO_HTTP_CODE );

            curl_close ( $ch );

            //echo 'service: ' . $services[$i] . '</br>';
            //echo 'err: '.$err.'</br>';
            //echo 'errmsg: '.$errmsg.'</br>';
            //echo 'httpCode: '.$httpCode.'</br>';
            //print_r($header);
            //print_r(json_decode($content, true));

            if ($err == 0 && $httpCode == 200 && $header['download_content_length'] > 0) 

                return json_decode($content, true);

             

        
    

【讨论】:

感谢代码 sn-p 但我认为我的问题出在 webservice/PHP 方面,而不是 CURL 代码(尽管我不是 100% 的,请随时告诉我)。我认为这是我的 PHP $_POST 值以及它们是否需要 json_encoded 或其他。 hmm 尝试将此添加到您的 curl curl_setopt($curl, CURLOPT_UPLOAD, 1);【参考方案3】:

您可以将您的 json 放入参数中并发送它,而不是仅将您的 json 放入标头中:

$post_string= 'json_param=' . json_encode($data);

//open connection
$ch = curl_init();

//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS, $post_string);
curl_setopt($curl, CURLOPT_URL, 'http://webservice.local/');  // Set the url path we want to call

//execute post
$result = curl_exec($curl);

//see the results
$json=json_decode($result,true);
curl_close($curl);
print_r($json);

在服务端,您可以获取您的 json 字符串作为参数:

$json_string = $_POST['json_param'];
$obj = json_decode($json_string);

然后您可以将转换后的数据用作对象。

【讨论】:

以上是关于使用 PHP 读取 JSON POST的主要内容,如果未能解决你的问题,请参考以下文章

从 PHP 中的 JSON POST 读取 HTTP 请求正文的问题

在php中读取json输入

从 SimpleHTTPServer Post 数据中读取 JSON

如何使用 boost::socket 读取 POST (JSON RPC) 数据?

WinINET 和 PHP php://input POST 读取

在 PHP 中读取“分块”的 POST 数据