Empty POST data in first query - php

I have a strange problem with PHP script and sending data by POST.
Script source where I receive POST data:
<?php
print_r($GLOBALS);
?>
Script where I send POST data:
<?php
$url = 'http://server.com/script.php';
$data = array(
"request" => '
{
"variable": "some data"
}'
);
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data),
),
);
$context = stream_context_create($options);
echo $result = file_get_contents($url, false, $context);
?>
When I call this script first time it return:
Array ( [GLOBALS] => Array *RECURSION* [_POST] => Array ( ) [_GET] => Array ( ) [_COOKIE] => Array ( ) [_FILES] => Array ( ) )
When I repeat query it's OK - Array show POST data. After a few minutes it is again empty.
I tried set different settings in .htaccess file, but it does not help.
PS. Same script on other server works great.
Do you have any ideas?

Related

Using an array as request headers in PHP

I'm trying to send a GET request to an API using PHP stream_context_create and file_get_contents.
I need to add API keys to the headers of my request, I'm storing these in an array so I easily edit them later and use them in multiple functions. What is a good way to include these arrays as headers?
In this case the key of the array would be the header keys and the value of the array the value of the header.
Some code to explain the problem
<?php
$api = array(
"X-Api-Id" => "id",
"X-Api-Key" => "key",
"X-Api-Secret" => "secret"
);
$options = array(
"http" => array(
"header" => "Content-type: application/x-www-form-urlencoded\r\n", // here I need to add the $api array
"method" => "GET"
)
);
return file_get_contents("example.com", FALSE, stream_context_create($options));
?>
Simply add the info to the header.
<?php
$api = [
'X-Api-Id' => 'id',
'X-Api-Key' => 'key',
'X-Api-Secret' => 'secret',
];
$headerData['Content-type'] = 'application/x-www-form-urlencoded';
$headerData = array_merge($headerData, $api);
array_walk($headerData, static function(&$v, $k) { $v = $k.': '.$v; });
$options = array(
'http' => [
'header' => implode("\n", $headerData),
'method' => 'GET'
]
);
return file_get_contents('example.com', FALSE, stream_context_create($options));
?>
To encode the data you can use http_build_query().
To add it to the header options you should be able to do something like:
$options = array(
"http" =>array(
'method' => 'POST', // GET in your case(?)
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($api)
)
);

Dropbox API - Error: expected list got dict

I am currently building a routine that needs to download files from one specific Dropbox folder , send them to another server and then move them to another folder on Dropbox.
I am using the /files/move_batch API endpoint for Dropbox to do so.
Here are the params sent to the API to move multiples files (well I'm only trying to move one file right now as it's still not working) :
$params = array(
'headers' => array(
'method' => 'POST',
'content-type' => 'application/json; charset=utf-8',
),
'body' => json_encode(array(
'entries' => array(
'from_path' => self::$files[0],
'to_path' => '/Applications/Archives/' . substr(self::$files[0], strrpos(self::$files[0], '/') + 1),
),
'autorename' => true,
)),
);
But I keep getting the same error message :
Error in call to API function "files/move_batch": request body: entries: expected list, got dict
I don't know what the API means by a list or how it should be formated.
The entries value should be a list of dict, one per file you want to move, each one containing both a from_path and a to_path. Your code is supplying the entries value to be a single dict though. (In PHP you can make both lists and dicts using the array keyword.)
It's easier to see and work with when you break it into pieces. Here's a working sample that does that.
<?php
$fileop1 = array(
'from_path' => "/test_39995261/a/1.txt",
'to_path' => "/test_39995261/b/1.txt"
);
$fileop2 = array(
'from_path' => "/test_39995261/a/2.txt",
'to_path' => "/test_39995261/b/2.txt"
);
$parameters = array(
'entries' => array($fileop1, $fileop2),
'autorename' => true,
);
$headers = array('Authorization: Bearer <ACCESS_TOKEN>',
'Content-Type: application/json');
$curlOptions = array(
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($parameters),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_VERBOSE => true
);
$ch = curl_init('https://api.dropboxapi.com/2/files/move_batch');
curl_setopt_array($ch, $curlOptions);
$response = curl_exec($ch);
echo $response;
curl_close($ch);
?>
To move just one file using this batch endpoint, you would change that line to something like:
'entries' => array($fileop1),

POST call doesn't work correctly?

I need to do a POST call to save data on a server. The server requires for some items a JSON-Encoded List. However when I do the post call and I look at $result, the data of the "JSON-Encoded List" is not saved and the items are null. The POST call is however successful.
$items = json_encode((array(
"name" => $_GET['title'],
"sub_type" => $subtype_fd,
"calories" => intval($_GET['calories']),
"carbohydrate" => floatval($_GET['carbohydrate']),
"cholesterol" => floatval($_GET['cholesterol']),
"fiber" => floatval($_GET['fiber']),
"protein" => floatval($_GET['protein']),
"saturated_fat" => floatval($_GET['saturated_fat']),
"unsaturated_fat" => floatval($_GET['unsaturated_fat']),
"sodium" => floatval($_GET['sodium']),
"sugar" => floatval($_GET['sugar'])
)));
var_dump($items);
$data = array('note' => $_GET['title'], 'sub_type' => $subtype_bld, 'items' => $items);
$options = array(
'http' => array(
"header" => "Content-Type: application/x-www-form-urlencoded\r\nAuthorization: Bearer {$_COOKIE['access_token']}\r\n",
'method' => 'POST',
'content' => $data
),
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
The Info from API
Host: jawbone.com
Accept: application/json
Content-Type: multipart/form-data
The content context option should be a string, you're providing an array. It's supposed to be a string in URL-encoded format. The http_build_str function will convert an associative array into this format. So use:
'content' => http_build_str($data)

Linkedin Invitation API Internal server error

Yo!
I'm trying to use the linkedin invitation api to allow users to conncect on linkedin from my application using email-addresses. I am able to find people, access the api and so on. I can't get the invites to work though. I am using php (Laravel).
I based myself on the example from the linkedin documentation ( Linkedin Invite API ). I send my data in a post using JSON (that contains the same info as their example).
I ask permission to use w_messages, the post works and my variables contain the correct information. I get a Internal Server error as a result.
$data = array(
"recipients" => array(
"values" => array(
"person" => array(
"_path" => "/people/email=".$email,
"first-name" => $firstname,
"last-name" => $lastname
)
)
),
"subject" => "Bla",
"body"=> "BlaBLa",
"item-content" => array(
"invitation-request" => array(
"connect-type" => "friend"
)
)
);
$dataString = json_encode($data);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => "Content-type: application/json\r\n".
"Connection: close\r\n" .
"Content-length: " . strlen($dataString) . "\r\n",
'content' => $dataString
)
);
$params = array('oauth2_access_token' => Session::get('access_token'),
'format' => 'json'
);
$url = "https://api.linkedin.com/v1/people/~/mailbox".'?' . http_build_query($params);
$context = stream_context_create($opts);
$result = file_get_contents($url, false, $context);
Log::info($result);
return Response::json(array("invite" => "sent"));
I assume I'm doing something wrong but don't really know where to look.
Looks like you doing this manually, have you tried using a tried & tested third party library like simple-linkedinphp - A PHP-based wrapper for the LinkedIn API.
https://code.google.com/p/simple-linkedinphp/wiki/Reference
Usage:
// Connect
$API_CONFIG = array(
'appKey' => '<your application key here>',
'appSecret' => '<your application secret here>',
'callbackUrl' => NULL
);
$linkedin = new LinkedIn($API_CONFIG);
// Send Invite
$linkedin->invite($method, $recipient, $subject, $body, $type = 'friend');
Doc: https://code.google.com/p/simple-linkedinphp/wiki/Reference

How to construct an AJAX JSON string with PHP to send with POST

I have a simple xmlhttprequest with AJAX and want to rebuild this with PHP.
var data = {};
var payload = {
"flags" : true,
"codes" : true,
"units" : true
};
data.payload = JSON.stringify(payload);
$.ajax({
type : 'POST',
url : 'http://httpbin.org/post',
data : data,
success : function(response) {
var arr = JSON.stringify(response);
document.getElementById('placeholder').innerHTML = arr;
}
});
This works fine!
Now my Version with PHP:
$data = array(
'payload' => array(
'flags' => true,
'codes' => true,
'units' => true
)
);
$options = array(
"http" => array(
"method" => "POST",
"header" => "Content-Type: application/json\r\n",
"content" => json_encode($data)
)
);
$url = "http://httpbin.org/post";
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
var_dump($response);
When I compare the results there is a difference in the structure.
Ajax looks like this:
{"form":{"payload":"{\"flags\":\"true\",
and PHP looks like this:
{"form": {},..."data": "{\"payload\":{\"flags\":\"true\",
Why is in PHP the "form" empty?
I've tried it an extra Array "form", but when I look at the result there is a second "form" in the string.
You use improper way of building POST data.
Try this:
$payload = array(
'flags' => true,
'codes' => true,
'units' => true
);
$data = array(
'payload' => json_encode($payload)
);
$options = array(
"http" => array(
"method" => "POST",
"header" => "Content-Type: application/x-www-form-urlencoded\r\n",
"content" => http_build_query($data)
)
);
Explanation
In your JS code POST data is an object containing one key-value pair {"payload": json} where json is json-encoded string representing payload object. This POST data object finally results (in $.ajax implementation) in a url-encoded string which look like this: payload=%7B%22flags%22%3Atrue%2C%22codes%22%3Atrue%2C%22units%22%3Atrue%7D.
Described process is exactly reproduced by my php code.
Have you tried to trigger json_last_error() right after encoding your array ?
$options = array(
"http" => array(
"method" => "POST",
"header" => "Content-Type: application/json\r\n",
"content" => json_encode($data)
)
);
$error = json_last_error();
echo $error;
In case of a silent json error, maybe it could give you a clue.
Let us know :)

Categories