How do I send json data using Zend 2 http?

2019-07-20 08:16发布

问题:

I've been struggling with this for a few days now - I need to send a set of data encoded in json to an api. I'm trying to use Zend 2 http to achieve this but I've had no luck so far. Here is what the manual for the api says :

Bulk Create Contacts
This command can be used to insert new numbers into your Textlocal contact groups 
and  will allow you to insert extra fields such as the contact's name.

Parameter   Description
group_id    ID of the group you’d like to store the numbers in. This
contacts    A JSON object containing all the details for each contact.

Note: It is recommended to send this request via POST.

Sample Request
(POST Variables): 
username: testing@Textlocal.co.uk 
hash: 4c0d2b951ffabd6f9a10489dc40fc356ec1d26d5 
group_id: 5 
contacts: [{"number":"447123456789","first_name":"Bob","last_name":"Smith","custom1":"","custom2":"","custom3":""},{"number":"447987654321","first_name":"Sally","last_name":"McKenzie","custom1":"","custom2":"","custom3":""},{"number":"447000000000","first_name":"Ramesh","last_name":"Dewani","custom1":"","custom2":"","custom3":""}]

Ok so that's what it expects and this is my code so far :-

include 'Zend/Loader/StandardAutoloader.php';
$loader = new Zend\Loader\StandardAutoloader(array('autoregister_zf' => true));
$loader->register();

use Zend\Http\Client;
use Zend\Http\Request;

$data = array(
'username'      => 'myUsername',
'hash'    => 'myHash',
'group_id'       => 123456,
'contacts' => json_encode(array('number'=>447123456789,'first_name'=>'Bob','last_name'=>'Smith','custom1'=>"",'custom2'=>"","custom3"=>""))
);


$uri = 'https://api.txtlocal.com/create_contacts_bulk';
$request = new Request();
$request->setUri($uri);
$request->setMethod('POST');
$request->getPost()->set($data);

    $config = array(
                'adapter' => 'Zend\Http\Client\Adapter\Socket',
                'ssltransport' => 'ssl',
                'sslcert' => '/etc/pki/tls/cert.pem',
                'sslcapath' => '/etc/pki/tls/certs'
                );

$client = new Client(null, $config);
$client->setEncType(Client::ENC_FORMDATA);
$response = $client->dispatch($request);

if ($response->isSuccess()) {
echo "the post worked!";
}else{
echo "the post failed";
}

That's not working and I'm sure there's I'm missing - here are the errors I get when I fire that script : -

[Thu Oct 24 09:29:47 2013] [error] [client] PHP Warning: Missing argument 2 for Zend\\Stdlib\\Parameters::set(), called in zend_test.php on line 24 and defined in Zend/Stdlib/Parameters.php on line 110
[Thu Oct 24 09:29:47 2013] [error] [client] PHP Notice: Undefined variable: value in Zend/Stdlib/Parameters.php on line 112
[Thu Oct 24 09:29:47 2013] [error] [client] PHP Fatal error: Uncaught exception 'Zend\\Http\\Client\\Exception\\RuntimeException' with message 'Cannot handle content type '' automatically' in Zend/Http/Client.php:1218\nStack trace:\n#0 Zend/Http/Client.php(858): Zend\\Http\\Client->prepareBody()\n#1 Zend/Http/Client.php(798): Zend\\Http\\Client->send(Object(Zend\\Http\\Request))\n#2 zend_test.php(30): Zend\\Http\\Client->dispatch(Object(Zend\\Http\\Request))\n#3 {main}\n thrown in Zend/Http/Client.php on line 1218 

Any light you can shed or help you can give me would be greatly appreciated :)

Thanks in advance

Joe

回答1:

You need to set the enc type when adding post data to the request object (this isn't very clear in the docs). Also, the example from the API manual implies that it's only the contacts that need to be JSON, you've encoded the whole array.

Try this:

$data = array(
    'username' => 'myUsername',
    'hash' => 'myHash',
    'group_id' => 123456,
    'contacts' => json_encode(array('number'=>447123456789,'first_name'=>'Bob','last_name'=>'Smith','custom1'=>"",'custom2'=>"","custom3"=>""))
);

$request = new Request();
$request->setUri('https://api.txtlocal.com/create_contacts_bulk');
$request->setMethod('POST');
$request->getPost()->fromArray($data);

$client = new Client();
$client->setEncType(Client::ENC_FORMDATA);
$response = $client->dispatch($request);

if ($response->isSuccess()) {
    echo "the post worked!";
}else{
    echo "the post failed";
}

Edit: In order to verify that the SSL certificate is valid, the HTTP client needs the path to the CA certificates on your web server.

You pass this in as a config option to the Http client instance:

$client = new Client(null, array(
    'sslcapath' => '/etc/ssl/certs'
));

That's the path on Ubuntu, you'll need to find out what it is for your server.



回答2:

By the way, instead of long constructions of Request, Response and Client classes please conider static Client usage:

http://framework.zend.com/manual/2.0/en/modules/zend.http.client-static.html

use Zend\Http\ClientStatic;

// Simple GET request
$response = ClientStatic::get('http://example.org');

// More complex GET request, specifying query string 'foo=bar' and adding a
// custom header to request JSON data be returned (Accept: application/json)
$response = ClientStatic::get(
    'http://example.org',
    array( 'foo' => 'bar' ),
    array( 'Accept' => 'application/json')
);

// We can also do a POST request using the same format.  Here we POST
// login credentials (username/password) to a login page:
$response = ClientStatic::post('https://example.org/login.php', array(
    'username' => 'foo',
    'password' => 'bar',
));