¿Cómo PUBLICAR datos JSON con PHP cURL?

132

Aquí está mi 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);

Y en otra página, estoy recuperando datos de publicaciones.

    print_r ($_POST);

La salida es

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

Por lo tanto, no obtengo los datos adecuados ni siquiera en mi propio servidor, es una matriz vacía. Quiero implementar REST usando json como en http://docs.shopify.com/api/customer#create

usuario1463076
fuente
2
¿No te estás perdiendo la conversión $dataal $data_stringuso json_encode()? No veo esta línea de código ...
shadyyx
Lo siento, no escribí aquí, pero en mi código escribí code$ data_string = json_encode ($ data); code¿Y cómo escribir código en los comentarios?
user1463076

Respuestas:

193

Está PUBLICANDO el json de forma incorrecta, pero incluso si fuera correcto, no podría realizar la prueba usando print_r($_POST)( lea por qué aquí ). En cambio, en su segunda página, puede atrapar la solicitud entrante usando file_get_contents("php://input"), que contendrá el json POSTed . Para ver los datos recibidos en un formato más legible, intente esto:

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

En su código, está indicando Content-Type:application/json, pero no está codificando json todos los datos POST, solo el valor del campo POST "cliente". En cambio, haz algo como esto:

$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 al margen: puede beneficiarse al usar una biblioteca de terceros en lugar de interactuar directamente con la API de Shopify.

Stephen M. Harris
fuente
1
Ja! Estaba luchando por qué no recibía los datos a través de $ _POST. El problema era que tenía que usar php: // input como dijiste. Gracias.
YOMorales
para que no tenga que especificar explícitamente que es una solicitud POST? ¿Es conocido porque CURLOPT_POSTFIELDS está configurado?
Srneczek
¿Dónde estaba esta respuesta cuando la estaba buscando toda la semana la semana pasada? ¡Ahora lo encuentro mucho después de que tuve que darme cuenta!
pythonian29033
Nota al margen: si envía JSON y espera JSON como respuesta, entonces algunas API requieren establecer también el tipo de respuesta curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json', 'Accept:application/json'));(de lo contrario, puede enviar JSON, pero obtener XML como respuesta).
pixelbrackets
2
salvaste el día
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 me funcionó. Puedes probar...

roki estelar
fuente
13

Reemplazar

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

con:

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

No entiendo lo que quieres decir con "otra página", espero que sea la página en: 'url_to_post'. Si esa página está escrita en PHP, el JSON que acaba de publicar arriba se leerá de la siguiente manera:

$jsonStr = file_get_contents("php://input"); //read the HTTP body.
$json = json_decode($jsonStr);
Ultra instinto
fuente
¿Por qué asumes eso? Si está poniendo los datos en el campo 'cliente', debe hacerlo por alguna razón, ¿no?
Okonomiyaki3000
Sí, gracias, me perdí esa parte. Pero él, en mi opinión, lo está haciendo mal. Actualizaré mi respuesta con ella.
UltraInstinct
Ninguna de las soluciones anteriores funciona para obtener datos json en el archivo php :(
Gohel Kiran
7

Por favor, intente 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
fuente
3

Prueba este ejemplo.

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

Su código page2.php

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

?>
Prasad Rajapaksha
fuente
1

Intenta así:

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

La clave que olvidó fue json_encode sus datos. Pero también puede resultarle conveniente utilizar curl_setopt_array para configurar todas las opciones de curva a la vez pasando una matriz.

Okonomiyaki3000
fuente
-1. Consulte la API aquí: api.shopify.com/customer.html#create . El cuerpo que el servidor espera en JSON, no urlencoded-json. Comprueba mi respuesta, no es necesario usarlo array(..)en `CURLOPT_POSTFIELDS
UltraInstinct
Sí, como dije, lo está enviando mal. Pasar un array(..)mensaje a CURLOPT_POSTFIELDS` también codificará el JSON.
UltraInstinct
De todos modos, lo intenté muchas veces con un código diferente, pero no pude hacerlo en json ahora lo hice con éxito en xml.
user1463076