5
votes

I have the following php code

curl_setopt($ch, CURLOPT_URL, $URL);
curl_setopt($ch, CURLOPT_USERAGENT, $this->_agent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->_headers);
curl_setopt($ch, CURLOPT_ENCODING , "gzip");
curl_setopt($ch, CURLOPT_VERBOSE, false); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_TIMEOUT,  120);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_COOKIEFILE, $this->_cookie_file_path);
curl_setopt($ch, CURLOPT_COOKIEJAR, $this->_cookie_file_path);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"folderId":"1","parameters":{"amount":3,"ascending":false,"offset":0,"sort":"date"}}');
curl_setopt($ch, CURLOPT_POST, 1); 

But I don't understand why is not working . The API that I'm posting the JSON to says that the parameters were not received . Is there anything wrong in my code ? I think the whole trick is on the JSON parameters... I'm not sure how to send them as I couldn't see any "nave->value" pair with the http analyzer as it usually appears in simple forms ... just that JSON code without any "name".

10
What's the sent Content-Type? And why don't you use json_encode?mario
@mario I tried with curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json')); and is not working either . By default I head the header set as $headers = array( "Expect:", ); I don't see how it would work with json_encodeAmeli
You will have to consult the API maintainer. We can only guess.mario
@mario I added the debug info (firebug) on this link due the fact I couldn't post it on SO. It says that it was not formatted well(though I tried several times to "format it) pastebin.com/Ujdim8t8Ameli
If you have something that use this interface and actually works, then use a proxy and record it :p then find out what your script does different, and luke out all the differences ( fiddler proxy is great for this, it even support fake certificates/MITM attacks for spying on HTTPS encrypted connections, decoding of gzip/deflate, etc)hanshenrik

10 Answers

5
votes

You can try as follows. Basically if we have a array of data then it should be json encoded using php json_encode. And you should also add content-type in header which can be defined in curl as curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));

$data = array("country"=>"US","states"=>array("MHASASAS"=>"MH","XYZABABA"=>"XYZ"));
$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);
3
votes

you can use this and replace with

curl_setopt($ch, CURLOPT_POSTFIELDS, '{"folderId":"1","parameters":{"amount":3,"ascending":false,"offset":0,"sort":"date"}}');

use this

$Parameters = array(
    'MerchantCode'        => $MerchantCode,
    'PriceValue'          => $amount,
    'ReturnUrl'           => $callback,
    'InvoiceNumber'       => $resnum,
);

    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($Parameters));
2
votes

If:you use post method,you should know that:

CURLOPT_POST TRUE to do a regular HTTP POST. This POST is the normal application/x-www-form-urlencoded kind, most commonly used by HTML forms.

@see http://php.net/manual/en/function.curl-setopt.php

So:you can do like this:

$ar_form = array('name'=>'PHPJungle','age'=>66,'gender'=>'male');
$poststr = http_build_query($ar_form ); # important

$options[CURLOPT_HTTPGET] = false;
$options[CURLOPT_POST] = true;
$options[CURLOPT_POSTFIELDS] = $poststr ; //default type:application/x-www-from-urlencoded

curl_setopt_array ( $ch, $options );
# @todo your other codes

This is my class I have used for a long time.The class is based on PHP cURL. It supports GET/POST,HTTP/HTTPS.

@see https://github.com/phpjungle/iHttp/

2
votes

You can post a json data with curl like so:

Using Command Prompt:

    curl -X POST -H "Content-Type: application/json" -d '{"folderId":"1","parameters":{"amount":3,"ascending":false,"offset":0,"sort":"date"}}' $url

Using PHP:

    $data = array("folderId"=>"1","parameters"=>array("amount"=>3,"ascending"=>false,"offset"=>0,"sort"=>"date"));
    $postdata = json_encode($data);
    OR
    $postdata = '{"folderId":"1","parameters":{"amount":3,"ascending":false,"offset":0,"sort":"date"}}';
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
    $result = curl_exec($ch);
    curl_close($ch);

    print_r($result);
1
votes

You haven't set the content type, so the post data is being sent as form data. Try setting the content type to application/json.

If that doesn't work, try wrapping the json string with an array.

1
votes
$link = "http://test.domain/myquery";
   $json = '{"folderId":"1","parameters":{"amount":3,"ascending":false,"offset":0,"sort":"date"}}';
   $postdata = json_decode($json);
 echo openurl($link, $postdata);

This works as json decode converts a json string into array.

function openurl($url, $postvars = "") {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, '3');
        $content = trim(curl_exec($ch));
        curl_close($ch);
        return $content;
    }
1
votes

if your API endpoint using body for send request using json data may be you can use Guzzle the doc is here doc.

use GuzzleHttp\Client;
$client = new Client();
$request = $this->client->post($url,array(
            'content-type' => 'application/json'
    ),array());
$request->setBody($json_data);
$response = $request->send();
return $response;

hope this work.

0
votes

I'm not sure, that this is the solution but this works for me when posting json, change the json from

'{"folderId":"1","parameters":{"amount":3,"ascending":false,"offset":0,"sort":"date"}}'

to

"{'folderId':'1','parameters':{'amount':3,'ascending':false,'offset':0,'sort':'date'}}"

The only change i made was the double quotes are now on the outside, that works for me but I'm obviously posting to a different server

Only other help I could offer is to download a network debugging tool such as Fiddler or Charles proxy and monitor the requests sent/received, it could be a case that something else is wrong in your code.

Hope i helped :)

0
votes

first of all please check the curl http status code

$http_code= curl_get_info($exec_res,CURL_HTTP_CODE);

then modify this request header set with post header API server add a recorder to log those request info.

0
votes

You can do it make by steps:

$data = array(
    'folderId'=>"1","parameters"=>array(
        "amount"=>"3","ascending"=>false,"offset"=>0,"sort"=>"date"
    )
);

$data_string = http_build_query($data);

$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($data));
curl_setopt($ch,CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);

$result = json_decode($result,true);

I don't know if you need the header. I think that by default it is already application/x-www-form-urlencode

If it doesn't work, try changing the $data values in array. Think it helps. :)