PHP - Posting JSON via file_get_contents - php

I am trying to POST JSON content to a remote REST endpoint, however the 'content' value appears to be empty on delivery. All other headers etc are being received correctly, and the web service tests successfully with a browser based test client.
Is there a problem with my syntax below where I specify the 'content' field?
$data = array("username" => "duser", "firstname" => "Demo", "surname" => "User", "email" => "example#example.com");
$data_string = json_encode($data);
$result = file_get_contents('http://test.com/api/user/create', null, stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => array('Content-Type: application/json'."\r\n"
. 'Authorization: username:key'."\r\n"
. 'Content-Length: ' . strlen($data_string) . "\r\n"),
'content' => $data_string)
)
));
echo $result;

This is the code I always use and it looks pretty similar (though this is of course for x-www-form-urlencoded).
Perhaps your username:key needs to be base64_encode'd.
function file_post_contents($url, $data, $username = null, $password = null)
{
$postdata = http_build_query($data);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
if($username && $password)
{
$opts['http']['header'] .= ("Authorization: Basic " . base64_encode("$username:$password"));
}
$context = stream_context_create($opts);
return file_get_contents($url, false, $context);
}

The question was about json, why the accepted answer is about x-www-form?
Json has many cool stuff to struggle about, like utf8_encode
function my_utf8_encode(array $in): array
{
foreach ($in as $key => $record) {
if (is_array($record)) {
$in[$key] = my_utf8_encode($record);
} else {
$in[$key] = utf8_encode($record);
}
}
return $in;
}
function file_post_contents(string $url, array $data, string $username = null, string $password = null)
{
$data = my_utf8_encode($data);
$postdata = json_encode($data);
if (is_null($postdata)) {
throw new \Exception('decoding params');
}
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/json',
'content' => $postdata
)
);
if (!is_null($username) && !is_null($password)) {
$opts['http']['header'] .= "Authorization: Basic " . base64_encode("$username:$password");
}
$context = stream_context_create($opts);
try {
$response = file_get_contents($url, false, $context);
} catch (\ErrorException $ex) {
throw new \Exception($ex->getMessage(), $ex->getCode(), $ex->getPrevious());
}
if ($response === false) {
throw new \Exception();
}
return $response;
}

The earlier response of
function file_post_contents($url, $data, $username = null, $password = null) {
$postdata = http_build_query($data);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
if($username && $password)
{
$opts['http']['header'] = ("Authorization: Basic " . base64_encode("$username:$password"));
}
$context = stream_context_create($opts);
return file_get_contents($url, false, $context);}
is incorrect. This function works sometimes, but it is inaccurate and will fail if you're not using the Content-type of application/x-www-form-urlencoded and you pass in a username and password.
It's working for the writer because application/x-www-form-urlencoded is the default Content-type, but his handling of the username and password is overwriting the earlier declaration of content type.
Here is the corrected function:
function file_post_contents($url, $data, $username = null, $password = null){
$postdata = http_build_query($data);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'content' => $postdata
)
);
if($username && $password)
{
$opts['http']['header'] .= ("Authorization: Basic " . base64_encode("$username:$password")); // .= to append to the header array element
}
$context = stream_context_create($opts);
return file_get_contents($url, false, $context);}
Note the line:
$opts['http']['header' .= (dot equals to append to the array element.)

Related

How do I get the result from response of this php api?

I've been working with this api and can't get anything response. Apparently the response should be true or false.
It returns Array;
I've tried things like:
return $obj[0][0];
But the page is blank
Here's the code:
function checkGuest ( $intEvent, $strBarcode, $ourSubscriptionKey, $sessionTokenClient )
{
$body = '';
$opts = array('http' =>
array(
'method' => 'GET',
'header' =>
"Content-Type: application/json\r\n".
"Authorization: Bearer " . $sessionTokenClient ."\r\n".
"Ocp-Apim-Subscription-Key: " . $ourSubscriptionKey,
'content' => $body,
'timeout' => 60
) );
$context = stream_context_create($opts);
$url = 'https://api.qflowhub.io/v1/api/guests/'.$intEvent.'/bybarcode?barcode='.$strBarcode;
try
{
$result = file_get_contents($url, false, $context);
$obj = json_decode( $result );
return $obj;
}
catch (Exception $ex)
{
$result = $ex;
}
}
$userCheck = checkGuest ( $intEvent, $strBarcode, $ourSubscriptionKey, $sessionTokenClient ) ;
echo $userCheck;

Post request with file_get_content not working

I am trying to use file_get_contents to "post" to a url and get auth token. The problem I am having is that it returns a error.
Message: file_get_contents(something): failed to open stream: HTTP request failed! HTTP/1.1 411 Length Required.
I am not sure what is causing this but need help. Here is the function.
public function ForToken(){
$username = 'gettoken';
$password = 'something';
$url = 'https://something.com';
$context = stream_context_create(array (
'http' => array (
'header' => 'Authorization: Basic ' . base64_encode("$username:$password"),
'method' => 'POST'
)
));
$token = file_get_contents($url, false, $context);
if(token){
var_dump($token);
}else{
return $resultArray['result'] = 'getting token failed';
}
}
I tried it with POSTMAN, and it works, so only problem I am having is that why isnt it working with file_get_contents.
Cannot command so i will do it this way. If you use Postman why don't you let Postman generate the code for you. In postman you can click code at a request and you can even select in what coding language you wanne have it. Like PHP with cURL:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "http://somthing.com/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => array(
"password: somthing",
"username: gettoken"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Hope this will help!
I can not comment because of my reputation;
In some servers file_get_content is not available...
You may try with CURL like this
Your request havent any data and content length is missing.
You can try this:
public function ForToken(){
$username = 'gettoken';
$password = 'something';
$url = 'https://something.com';
$data = array('foo' => 'some data');
$data = http_build_query($data);
$context_options = array (
'http' => array (
'method' => 'POST',
'header'=> "Content-type: application/x-www-form-urlencoded\r\n"
. "Authorization: Basic " . base64_encode("$username:$password") . "\r\n"
. "Content-Length: " . strlen($data) . "\r\n",
'content' => $data
)
);
$context = context_create_stream($context_options);
$token = file_get_contents($url, false, $context);
if(token){
var_dump($token);
}else{
return $resultArray['result'] = 'getting token failed';
}
}
Here is similar problem:
How to fix 411 Length Required error with file_get_contents and the expedia XML API?
RFC2616 10.4.12
https://www.rfc-editor.org/rfc/rfc2616#section-10.4.12
Code: (Doesn't work, see below)
public function ForToken(){
$username = 'gettoken';
$password = 'something';
$url = 'https://something.com';
$context = stream_context_create(array (
'http' => array (
'header' => 'Authorization: Basic ' . base64_encode("$username:$password") . 'Content-Length: ' . strlen($url) . '\r\n',
'method' => 'POST'
)
));
$token = file_get_contents($url, false, $context);
if(token){
var_dump($token);
}else{
return $resultArray['result'] = 'getting token failed';
}
}
2nd Try:
public function ForToken(){
$username = 'gettoken';
$password = 'something';
$url = 'https://something.com';
$context_options = array (
'http' => array (
'method' => 'POST',
'header'=> "Content-type: application/x-www-form-urlencoded\r\n" . "Authorization: Basic " . base64_encode("$username:$password") . "Content-Length: " . strlen($url) . "\r\n",
'content' => $url
)
);
$context = stream_context_create($context_options);
$token = file_get_contents($url, false, $context);
if(token){
var_dump($token);
}else{
return $resultArray['result'] = 'getting token failed';
}
}
This is from patryk-uszynski's answer formatted with the OP's code.

PHP URL encoding with HTTP GET request

I've set up a PHP script to send a text message using the Nexmo API, however there's a problem with how I'm encoding the HTTP GET request. The script pulls some variables from stored data, and then fires. I'm not experienced with PHP and have spent so much time on this already, this is my last resort, is anyone able to see where I've gone wrong in the following code?
The intended format for the request:
https://rest.nexmo.com/sms/json?api_key=XXX&api_secret=XXX&to=XXX&from=XXX&text=XXX
The code:
function sendText () {
$api_key = $settings['consumer_key'];
$api_secret = $settings['consumer_secret'];
$recipient = $settings['recipient'];
$from = $settings['from'];
$text = $settings['sms_contents'];
$url = 'https://rest.nexmo.com/sms/json';
$data = array_merge($data, array('api_key' => $api_key, 'api_secret' => $api_secret, 'to' => $recipient, 'from' => $from, 'text' => $text));
$post = '';
foreach($data as $k => $v) {
$post .= "&$k=$v";
}
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $post
)
);
$context = stream_context_create($opts);
$from_nexmo = file_get_contents($url, false, $context);
}
sendText();
I don’t think you are doing any encoding. Here is what I would do:
foreach($data as $k => $v){
$post .= "&$k=" . urlencode($v);
}
Try to use urlencode() for transferred values:
$post = array();
foreach($data as $k => $v){
$post[] = $k . '=' . urlencode($v);
}
$post = implode('&', $post);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $post
)
);
Please try executing the following code snippet:
function sendText () {
$api_key = $settings['consumer_key'];
$api_secret = $settings['consumer_secret'];
$recipient = $settings['recipient'];
$from = $settings['from'];
$text = $settings['sms_contents'];
$url = 'https://rest.nexmo.com/sms/json';
$data = array_merge($data, array('api_key' => $api_key, 'api_secret' => $api_secret, 'to' => $recipient, 'from' => $from, 'text' => $text));
$post = http_build_query($data);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $post
)
);
$context = stream_context_create($opts);
$from_nexmo = file_get_contents($url, false, $context);
}
sendText();

Post login with file_get_contents - not curl

One site requires login for three variables: username, password and token. This data is sent via POST.
token is also sent through a section.
I have all three variables, and I want to log in via file_get_contents.
How can that data be sent and the authentication is successful?
function file_post_contents()
{
$url = 'http://site.com/auth.php?' . session_name() . '=' . session_id();
$login = 'jhon';
$senha = 'doe';
$token = '123456';
$_SESSION["token"] = $token;
$postdata = http_build_query(
array(
'login' => $login,
'senha' => $senha,
'token' => $token,
$_SESSION["token"] => $token
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
if($login && $senha)
{
$opts['http']['header'] = ("Authorization: Basic " . base64_encode("$login:$senha"));
}
$context = stream_context_create($opts);
return file_get_contents($url, false, $context);
}
Modified code. It does not work.
function file_post_contents()
{
$url = 'http://site.com/auth.php?' . session_name() . '=' . session_id();
$login = 'jhon';
$senha = 'doe';
$token = '123456';
$_SESSION["token"] = $token;
$postdata = http_build_query(
array(
'login' => $login,
'senha' => $senha,
'token' => $token
//, $_SESSION["token"] => $token
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded'
. "\r\n" . "Authorization: Basic " . base64_encode("$login:$senha"). "\r\n",
'content' => $postdata
)
);
$context = stream_context_create($opts);
return file_get_contents($url, false, $context);
}
Your headers might be set wrong, try adding \r\n like so
$opts = array('http' =>
array(
'method' => 'POST',
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'content' => $postdata
)
);
and later down the code
$opts['http']['header'] = $opts['http']['header'] . "Authorization: Basic " . base64_encode("$login:$senha") . "\r\n";
You're overriding $opts['http']['header'] with the Basic auth. You're not adding it to the Content-type, you're replacing Content-type with it.

Send HTTP Post with Array - PHP

I'm trying to use this nice function:
function do_post_request($url, $data, $optional_headers = null) {
$params = array('http' => array(
'method' => 'POST',
'content' => $data
));
if ($optional_headers !== null) {
$params['http']['header'] = $optional_headers;
}
$ctx = stream_context_create($params);
$fp = #fopen($url, 'rb', false, $ctx);
if (!$fp) {
throw new Exception("Problem with $url, $php_errormsg");
}
$response = #stream_get_contents($fp);
if ($response === false) {
throw new Exception("Problem reading data from $url, $php_errormsg");
}
return $response;
}
to send a POST command to a specific url, my problem is i'm trying to send the post paramters in a form of an array, something like this
login[username]: myusername
login[password]: mypassword,
however i'm not able to do that, calling the function with :
$login_post = array('login[username]' => $email,
'login[password]' => '');
do_post_request(getHost($website['code']), $login_post);
always send the data to the post in the form:
username: myusername
password: mypassword
How can I avoid this (without using curl)? Thanks a lot.
Thanks
Yehia
Maybe with that ?
<?php
// Define POST data
$donnees = array(
'login' => 'test',
'password' => '******' );
function http_build_headers( $headers ) {
$headers_brut = '';
foreach( $headers as $name => $value ) {
$headers_brut .= $name . ': ' . $value . "\r\n";
}
return $headers_brut;
}
$content = http_build_query( $donnees );
// define headers
$headers = http_build_headers( array(
'Content-Type' => 'application/x-www-form-urlencoded',
'Content-Length' => strlen( $content) ) );
// Define context
$options = array( 'http' => array( 'user_agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1) Gecko/20061010 Firefox/2.0',
'method' => 'POST',
'content' => $content,
'header' => $headers ) );
// Create context
$contexte = stream_context_create( $options );
// Send request
$return = file_get_contents( 'http://www.exemple.com', false, $contexte );
?>
$login_post = array(
'login' => array(
'username' => $email,
'password' => ''))
Try using stream_context_create
$url = 'http://your_url.com/path';
$data = array('login' => 'usrnname', 'password' => '**');
$opt = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
)
);
$context = stream_context_create($opt);
$result = file_get_contents($url, false, $context);
var_dump($result);
This method doesnt use curl.

Categories