web-dev-qa-db-fra.com

Lecture JSON POST en utilisant PHP

J'ai jeté un coup d'œil autour de moi avant de poster cette question. Je vous prie de m'excuser si elle figure dans un autre message et ce n'est que ma deuxième question ici.

J'ai créé un service Web très simple qui doit prendre des valeurs de publication et renvoyer un tableau codé JSON. Tout cela a bien fonctionné jusqu'à ce que l'on me dise que je devrais publier les données de formulaire avec un type de contenu application/json. Depuis lors, je ne peux renvoyer aucune valeur du service Web et cela a certainement un rapport avec la façon dont je filtre leurs valeurs de publication.

En gros, dans ma configuration locale, j'ai créé une page de test qui effectue les opérations suivantes:

$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);

Sur le service Web, j'ai ceci (j'ai supprimé certaines fonctions) -

<?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);

?>

En gros, je sais que cela est dû au fait que les valeurs de $ _POST ne sont pas définies, mais je ne trouve pas ce que je dois mettre à la place de $ _POST. J'ai essayé Json_decode ($ _ POST), file_get_contents ("php: // input") et un certain nombre d'autres moyens, mais je tournais un peu dans le noir.

Toute aide serait grandement appréciée.

Merci Steve

Merci Michael pour l’aide, c’était un grand pas en avant. Maintenant, j’ai au moins eu une réponse lorsque je me fais l'écho de la publication .... même si elle est nulle 

cURL mis à jour -

  $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 mis à jour sur la page sur laquelle les données sont publiées -

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

print_r(json_encode($input));

Comme je le dis au moins, je vois maintenant une réponse indiquant qu’avant il renvoyait une page vierge

53
Steve Matthews

Vous avez $_POST vide. Si votre serveur Web souhaite voir les données au format JSON, vous devez lire l'entrée brute, puis l'analyser avec le décodage JSON.

Vous avez besoin de quelque chose comme ça:

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

Aussi, vous avez un code erroné pour tester la communication JSON ...

CURLOPT_POSTFIELDS indique à curl de coder vos paramètres en tant que application/x-www-form-urlencoded. Vous avez besoin de la chaîne JSON ici.

METTRE &AGRAVE; JOUR

Votre code php pour la page de test devrait être comme ça:

$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);

Sur votre page de service Web, vous devez également supprimer l’une des lignes header('Content-type: application/json');. Il ne doit être appelé qu'une fois.

120
Michael Sivolobov

Bonjour, voici un extrait d’un ancien projet mien qui utilise curl pour obtenir des informations sur l’ip de certains services de bases de données ip gratuits qui répondent au format json. Je pense que cela pourrait vous aider.

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

getUserLocation($ip_srv);

Une fonction:

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);

            } 

        }
    }
1
Syd

vous pouvez mettre votre json dans un paramètre et l'envoyer au lieu de ne mettre que votre json dans l'en-tête:

$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);

côté service, vous pouvez obtenir votre chaîne json en tant que paramètre:

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

alors vous pouvez utiliser vos données converties en tant qu'objet.

0
morteza kavakebi