web-dev-qa-db-fra.com

Curl et PHP - comment puis-je passer un json à travers curl par PUT, POST, GET

J'ai travaillé sur la construction d'une API Rest pour l'enfer et je l'ai testée au fur et à mesure en utilisant curl depuis la ligne de commande, ce qui est très facile pour CRUD.

Je peux passer ces appels avec succès depuis la ligne de commande

curl -u username:pass -X GET http://api.mysite.com/pet/1
curl -d '{"dog":"tall"}' -u username:pass -X GET http://api.mysite.com/pet
curl -d '{"dog":"short"}' -u username:pass -X POST http://api.mysite.com/pet
curl -d '{"dog":"tall"}' -u username:pass -X PUT http://api.mysite.com/pet/1

Les appels ci-dessus sont faciles à effectuer à partir de la ligne de commande et fonctionnent correctement avec mon API, mais je souhaite maintenant utiliser PHP pour créer le curl. Comme vous pouvez le constater, je transmets des données sous forme de chaîne json. J'ai lu autour et je pense que je peux probablement faire le POST et inclure les champs POST, mais je n'ai pas été en mesure de savoir comment passer des données de corps http avec GET. Tout ce que je vois indique que vous devez l'attacher à l'URL, mais cela ne se présente pas de la sorte sur le formulaire en ligne de commande. Quoi qu'il en soit, j'aimerais beaucoup que quelqu'un puisse écrire la bonne façon de faire ces quatre opérations dans PHP ici sur une seule page. Je voudrais voir le moyen le plus simple de le faire avec curl et php. Je pense que je dois tout passer à travers le corps http parce que mon api php attrape tout avec php: // input

47
Gilberg

PUT

$data = array('username'=>'dog','password'=>'tall');
$data_json = json_encode($data);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($data_json)));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS,$data_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response  = curl_exec($ch);
curl_close($ch);

POST

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$data_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response  = curl_exec($ch);
curl_close($ch);

OBTENEZ Voir la réponse de @Dan H

EFFACER

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_POSTFIELDS,$data_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response  = curl_exec($ch);
curl_close($ch);
136
voodoo417

Vous pouvez utiliser cette petite bibliothèque: https://github.com/jmoraleda/php-rest-curl

Passer un appel est aussi simple que:

// GET
$result = RestCurl::get($URL, array('id' => 12345678));

// POST
$result = RestCurl::post($URL, array('name' => 'John'));

// PUT
$result = RestCurl::put($URL, array('$set' => array('lastName' => "Smith")));

// DELETE
$result = RestCurl::delete($URL); 

Et pour la variable $ result:

  • $ result ['status'] est le code de réponse HTTP
  • $ result ['data'] un tableau avec la réponse JSON analysée
  • $ result ['header'] une chaîne avec les en-têtes de réponse

J'espère que ça aide

10
ledfusion

Pour ma part, je viens de l'encoder dans l'URL et d'utiliser $ _GET sur la page de destination. Voici une ligne à titre d'exemple.

$ch = curl_init();
$this->json->p->method = "whatever";
curl_setopt($ch, CURLOPT_URL, "http://" . $_SERVER['SERVER_NAME'] . $this->json->path . '?json=' . urlencode(json_encode($this->json->p)));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);

EDIT: Ajout de l'extrait de destination ... (EDIT 2 ajouté plus ci-dessus à la demande OPs)

<?php
if(!isset($_GET['json']))
    die("FAILURE");
$json = json_decode($_GET['json']);
$method = $json->method;
...
?>
7
Dan H

Je travaillais avec plugin Elastic SQL . La requête est effectuée avec la méthode GET en utilisant cURL comme ci-dessous:

curl -XGET http://localhost:9200/_sql/_explain -H 'Content-Type: application/json' \
-d 'SELECT city.keyword as city FROM routes group by city.keyword order by city'

J'ai exposé un port personnalisé sur un serveur public, faisant un proxy inverse avec le jeu d'authentification de base.

Ce code fonctionne très bien, plus l'en-tête d'authentification de base:

$Host = 'http://myhost.com:9200';
$uri = "/_sql/_explain";
$auth = "john:doe";
$data = "SELECT city.keyword as city FROM routes group by city.keyword order by city";

function restCurl($Host, $uri, $data = null, $auth = null, $method = 'DELETE'){
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $Host.$uri);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    if ($method == 'POST')
        curl_setopt($ch, CURLOPT_POST, 1);
    if ($auth)
        curl_setopt($ch, CURLOPT_USERPWD, $auth);
    if (strlen($data) > 0)
        curl_setopt($ch, CURLOPT_POSTFIELDS,$data);

    $resp  = curl_exec($ch);
    if(!$resp){
        $resp = (json_encode(array(array("error" => curl_error($ch), "code" => curl_errno($ch)))));
    }   
    curl_close($ch);
    return $resp;
}

$resp = restCurl($Host, $uri); //DELETE
$resp = restCurl($Host, $uri, $data, $auth, 'GET'); //GET
$resp = restCurl($Host, $uri, $data, $auth, 'POST'); //POST
$resp = restCurl($Host, $uri, $data, $auth, 'PUT'); //PUT
0
Luiz Vaz