Como postar dados JSON com PHP cURL?

132

Aqui está o meu código,

$url = 'url_to_post';
$data = array(
    "first_name" => "First name",
    "last_name" => "last name",
    "email"=>"[email protected]",
    "addresses" => array (
        "address1" => "some address",
        "city" => "city",
        "country" => "CA",
        "first_name" =>  "Mother",
        "last_name" =>  "Lastnameson",
        "phone" => "555-1212",
        "province" => "ON",
        "zip" => "123 ABC"
    )
);
$data_string = json_encode($data);
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, array("customer"=>$data_string));
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,
    array(
        'Content-Type:application/json',
        'Content-Length: ' . strlen($data_string)
    )
);

$result = curl_exec($ch);
curl_close($ch);

E em outra página, estou recuperando dados de postagem.

    print_r ($_POST);

Saída é

HTTP/1.1 200 OK
Date: Mon, 18 Jun 2012 07:58:11 GMT
Server: Apache
X-Powered-By: PHP/5.3.6
Vary: Accept-Encoding
Connection: close
Content-Type: text/html

Array ( ) 

Portanto, não estou obtendo dados adequados, mesmo no meu próprio servidor, é uma matriz vazia. Quero implementar o REST usando json como em http://docs.shopify.com/api/customer#create

user1463076
fonte
2
Você não está perdendo a conversão $datapara $data_stringusar json_encode()??? Não ver esta linha de código ...
shadyyx
Desculpe, não escrevi aqui, mas no meu código escrevi code$ data_string = json_encode ($ data); codee como escrever código nos comentários? nos comentários não consigo escrever quebra de linha e como escrever código?
user1463076

Respostas:

193

Você está postando o json incorretamente - mas mesmo se estiver correto, não poderá testar usando print_r($_POST)( leia o porquê aqui ). Em vez disso, na sua segunda página, você pode capturar a solicitação de entrada usando file_get_contents("php://input"), que conterá o json POSTed . Para visualizar os dados recebidos em um formato mais legível, tente o seguinte:

echo '<pre>'.print_r(json_decode(file_get_contents("php://input")),1).'</pre>';

No seu código, você está indicando Content-Type:application/json, mas não está codificando json todos os dados do POST - apenas o valor do campo POST "customer". Em vez disso, faça algo como isto:

$ch = curl_init( $url );
# Setup request to send json via POST.
$payload = json_encode( array( "customer"=> $data ) );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
# Return response instead of printing.
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
# Send request.
$result = curl_exec($ch);
curl_close($ch);
# Print response.
echo "<pre>$result</pre>";

Nota: Você pode se beneficiar do uso de uma biblioteca de terceiros em vez de interagir diretamente com a API do Shopify.

Stephen M. Harris
fonte
1
Hah! Eu estava lutando porque não estava recebendo os dados via $ _POST. O problema foi que eu tive que usar a entrada php: // como você disse. Obrigado.
YOMorales #
então você não precisa especificar explicitamente que é uma solicitação POST? É conhecido porque CURLOPT_POSTFIELDS está definido?
Srneczek
onde estava essa resposta quando eu estava procurando a semana toda semana passada? Agora eu acho isso depois que eu tive que me descobrir!
Pythonian29033 de 01/09/19
Nota: Se você enviar JSON e esperar JSON como resposta, algumas APIs também exigirão definir o tipo de resposta curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json', 'Accept:application/json'));(caso contrário, você poderá enviar JSON, mas obter XML como resposta).
Pixelbrackets 9/0318
2
você salvou o dia
Nisal Edu
29
$url = 'url_to_post';
$data = array("first_name" => "First name","last_name" => "last name","email"=>"[email protected]","addresses" => array ("address1" => "some address" ,"city" => "city","country" => "CA", "first_name" =>  "Mother","last_name" =>  "Lastnameson","phone" => "555-1212", "province" => "ON", "zip" => "123 ABC" ) );

$postdata = json_encode($data);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$result = curl_exec($ch);
curl_close($ch);
print_r ($result);

Este código funcionou para mim. Podes tentar...

roki estelar
fonte
13

Substituir

curl_setopt($ch, CURLOPT_POSTFIELDS, array("customer"=>$data_string));

com:

$data_string = json_encode(array("customer"=>$data));
//Send blindly the json-encoded string.
//The server, IMO, expects the body of the HTTP request to be in JSON
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);

Não entendo o que você quis dizer com "outra página", espero que seja a página em: 'url_to_post'. Se essa página for escrita em PHP, o JSON que você acabou de postar acima será lido da seguinte maneira:

$jsonStr = file_get_contents("php://input"); //read the HTTP body.
$json = json_decode($jsonStr);
UltraInstinct
fonte
Por que você assumiria isso? Se ele está colocando os dados no campo "cliente", deve fazê-lo por um motivo, não?
usar o seguinte
Sim, obrigado, eu perdi essa parte. Mas ele, IMO, está fazendo errado. Vou atualizar minha resposta com ele.
UltraInstinct
Nenhuma das soluções acima funciona para obter dados json no arquivo php :(
Gohel Kiran
7

Por favor, tente este código: -

$url = 'url_to_post';

$data = array("first_name" => "First name","last_name" => "last name","email"=>"[email protected]","addresses" => array ("address1" => "some address" ,"city" => "city","country" => "CA", "first_name" =>  "Mother","last_name" =>  "Lastnameson","phone" => "555-1212", "province" => "ON", "zip" => "123 ABC" ) );

$data_string = json_encode(array("customer" =>$data));

$ch = curl_init($url);

curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);

curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$result = curl_exec($ch);

curl_close($ch);

echo "$result";
Damini Mahawer
fonte
3

Tente este exemplo.

<?php 
 $url = 'http://localhost/test/page2.php';
    $data = array("first_name" => "First name","last_name" => "last name","email"=>"[email protected]","addresses" => array ("address1" => "some address" ,"city" => "city","country" => "CA", "first_name" =>  "Mother","last_name" =>  "Lastnameson","phone" => "555-1212", "province" => "ON", "zip" => "123 ABC" ) );
    $ch=curl_init($url);
    $data_string = urlencode(json_encode($data));
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_POSTFIELDS, array("customer"=>$data_string));


    $result = curl_exec($ch);
    curl_close($ch);

    echo $result;
?>

O seu código page2.php

<?php
$datastring = $_POST['customer'];
$data = json_decode( urldecode( $datastring));

?>
Prasad Rajapaksha
fonte
1

Tente assim:

$url = 'url_to_post';
// this is only part of the data you need to sen
$customer_data = array("first_name" => "First name","last_name" => "last name","email"=>"[email protected]","addresses" => array ("address1" => "some address" ,"city" => "city","country" => "CA", "first_name" =>  "Mother","last_name" =>  "Lastnameson","phone" => "555-1212", "province" => "ON", "zip" => "123 ABC" ) );
// As per your API, the customer data should be structured this way
$data = array("customer" => $customer_data);
// And then encoded as a json string
$data_string = json_encode($data);
$ch=curl_init($url);

curl_setopt_array($ch, array(
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $data_string,
    CURLOPT_HEADER => true,
    CURLOPT_HTTPHEADER => array('Content-Type:application/json', 'Content-Length: ' . strlen($data_string)))
));

$result = curl_exec($ch);
curl_close($ch);

A principal coisa que você esqueceu foi json_encode seus dados. Mas você também pode achar conveniente usar curl_setopt_array para definir todas as opções de curvatura de uma só vez, passando uma matriz.

Okonomiyaki3000
fonte
-1. Verifique a API aqui: api.shopify.com/customer.html#create . O corpo que o servidor espera em JSON, não urlencoded-json. Verifique minha resposta, não há necessidade de usar o array(..)`CURLOPT_POSTFIELDS
UltraInstinct
Sim, como eu disse, ele está enviando errado. Passar array(..)para CURLOPT_POSTFIELDS` também irá codificar o JSON.
UltraInstinct
Enfim, eu tentei muitas vezes com código diferente, mas eu não era capaz de fazer em json agora eu fiz com sucesso em xml.
user1463076