GuzzleHttp disable UrlEncoding - php

I should send some JSON in my Get request and the server returns some data in application/json as response:
$url='http://example.com/var1=123&var2={'id':123,satrt:342,end:987,using:"abc"}';
and I use this code:
$client = new \GuzzleHttp\Client;
$response = $client->get($url);
$data = json_decode((string)$response->getBody(), true);
but it send a request to:
http://example.com/var1=123&var2=%7B'id':123,satrt:342,end:987,using:"abc"%7D
I see this answer about $response->getQuery()->useUrlEncoding(false) but it do nothing.
how can I tell GuzzleHttp not to url encode the { and }?

IMO you should not want to do that. The remote server must decode the query string, so it will receive the original string in the end. BTW, it's better to use query option to manage query string parameters.
If you want to do it anyway, try to construct an instance of Uri class manually.

Related

Pulling a base64 encoded string from http request in php

Background
I wrote a small test to make sure I could pull the data from a POST request made from my mobile application. It works fine,
$rawJsonObj = file_get_contents('php://input');
$json = json_decode( $rawJsonObj, true );
$decodedData = base64_decode($json['data']);
file_put_contents('student-data/'.$json['username'].'.txt', $decodedData);
Then in my Slim Framework app I try the same logic and the actual data that I use to create the file with is null. But I can still access the username and password that are sent in the request.
$app->post('/api/v1/endpoint', function ($request, $response, $args) {
$rawJsonObj = $request->getParams();
$json = json_decode( $rawJsonObj, true );
$decodedData = base64_decode($json['data']);
file_put_contents('test.txt', $decodedData);
return $response;
}
The username and password are showing in the request and I can see them when I write the data in the request to a file.
$data = $request->getParams();
file_put_contents('2.txt', $data);
Data that is wrote to file,
","username":"myuname","password":"myPword"}
But the base64encoded string is missing,
Example
In Swift I am creating the dict like this, then POST it as json,
let dict: [String: Any] = [
"username": named,
"password": password,
"data": data.base64EncodedString()
]
if let json = try? JSONSerialization.data(withJSONObject: dict, options: []) {
request.httpBody = json
}
Question
How do I access the actual "data": data.base64EncodedString() from the request body in Slim Framework 3?
I assume this has to do with the way $rawJsonObj = file_get_contents('php://input'); actually handles the data compared to Slim?
Request::getParams() is a custom method by Slim (not part of PSR-7) that collects all input data; in other words, it's a rough equivalent of PHP's $_REQUEST superglobal. Internally, it grabs the request body with Request::getParsedBody() (this one, part of PSR-7). Here's where major differences with $_REQUEST or $_POST arise:
If the request Content-Type is either
application/x-www-form-urlencoded or multipart/form-data, and the
request method is POST, this method MUST return the contents of
$_POST.
Otherwise, this method may return any results of deserializing the
request body content; as parsing returns structured content, the
potential types MUST be arrays or objects only. A null value
indicates the absence of body content.
While $_POST only decodes standard form encodings (thus in your test code you need to fetch and parse data manually) getParsedBody() tries to decode other encodings but, just like $_POST, it needs a proper Content-Type to do so. If you send one from your mobile app:
Content-Type: application/json
... it'll work as expected because Slim has a builtin JSON decoder.
If you can't send an encoding declaration, you need to decode stuff manually. In this case, the PSR-7 way to fetch the raw request body is Message::getBody(), that returns a stream (more specifically, a Stream object that that implements StreamInterface).

Get and Send file with PHP and RESTful API

One of my partners has an API service which should send an HTTP POST request whenever a new file is published. This requires me to have an api file which will get the POST this way:
http://myip:port/api/ReciveFile
and requesting that the JSON format request should be:
{
"FILE ":"filename.zip",
"FILE_ID":"123",
"FILE_DESC":"PRUPOUS_FILE",
"EXTRAVAR":"",
"EXTRAVAR2":"",
"USERID":" xxxxxxxxxxxx",
"PASSWORD":"yyyyyyyyyyy"
}
Meanwhile it should issue a response, in JSON format if it got the file or not
{"RESULT_CODE":0,"RESULT_DESCR":""}
{"RESULT_CODE":1001,"RESULT_DESCR":"Bad request"}
And after, when I am finished elaborating the file, I should send back the modified file same way.
The question is, now basically from what I understand he will send me the variables witch I have to read, download the file, and send a response back.
I am not really sure how to do this any sample code would be welcomed!
I'm not sure exactly what the question is, but if you mean creating a success response in JSON for if an action occurred while adding data to it which is what can be understood from the question, just create an array with the values you wish to send back to the provider and do json_encode on the array which should create json and just print it back as a response.
About receiving the information; all you have to do is use the integrated curl functions or use a wrapper (Guzzle, etc) to output the raw JSON or json_decode data into a variable and do whatever you please with it.
From what I read in the question, you wish to modify the contents of it. This can be achieved by just decoding the json and changing the variables in the array, then printing the modified JSON back as a response.
Example (this uses GuzzleHTTP as an example):
$res = $client->request('GET', 'url');
$json = $res->getBody();
$array = json_decode($json, 1); // decode the json
// Start modifying the values or adding
$array['value_to_modify'] = $whatever;
$filename = $array['filename']; // get filename
// make a new request
$res = $client->request('GET', 'url/'.$filename);
// get the body of specified filename
$body = $res->getBody();
// Return the array.
echo json_encode($body);
References:
http://docs.guzzlephp.org/en/latest/

Slim PUT request empty body

I am using slim php framework for developing REST API. I am successful in implementing POST and GET requests. I am using ContentTypes middleware as well to parse the JSON body in POST and PUT requests however my PUT request always gives empty string on the server. POST just works fine and I can get the parsed JSON as PHP associative array but cant get it in PUT request. I am using application/json in headers and I dont want to use application/x-www-form-urlencoded method.
$app->map('/example/:id', function ($id) use($app, $log) {
//$body = $app->request()->getBody();
//using the above in other POST calls & it works but does not in this case
$body = json_decode($app->request()->getBody()); //tried this. no success
var_dump($body);
} )->via ( 'PUT', 'PATCH' );
I am calling it via CURL like this
$headers = array(
'Content-Type'=>'application/json;charset=utf-8',
);
$id = 123;
$body = array("name"=>"myfirstname","email"=>"myemail");
$json_str = json_encode($body);
$response = Requests::put($base_url.'/api/v1/example/'.$id,$headers,$json_str);
When I try to return the same JSON from the API it returns empty array. I tried POSTMAN on chrome and above code but does not work. What is the issue.
Update: I have verified the same code works on localhost but does not work on remote dev server. What can be the reason? Do I need to alter any settings on server?
Slim reads php://input to get the contents of the request body, so whatever the problem is it has to do with the particulars of that stream.
Do you have some other code that tries to read php://input? If so, note that this is only possible starting from PHP 5.6 (which your local machine may have when your server does not).
Try using getInstance().
$body = json_decode($app->getInstance()->request()->getBody());

How to access a JSON request body of a POST request in Slim?

I'm just a newbie in the Slim framework. I've written one API using Slim framework.
A POST request is coming to this API from an iPhone app. This POST request is in JSON format.
But I'm not able to access the POST parameters that are sent in a request from iPhone. When I tried to print the POST parameters' values I got "null" for every parameter.
$allPostVars = $application->request->post(); //Always I get null
Then I tried to get the body of a coming request, convert the body into JSON format and sent it back as a response to the iPhone. Then I got the parameters' values but they are in very weird format as follows:
"{\"password\":\"admin123\",\"login\":\"admin#gmail.com\",\"device_type\":\"iphone\",\"device_token\":\"785903860i5y1243i5\"}"
So one thing for sure is POST request parameters are coming to this API file. Though they are not accessible in $application->request->post(), they are coming into request body.
My first issue is how should I access these POST parameters from request body and my second issue is why the request data is getting displayed into such a weird format as above after converting the request body into JSON format?
Following is the necessary code snippet:
<?php
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();
//Instantiate Slim class in order to get a reference for the object.
$application = new \Slim\Slim();
$body = $application->request->getBody();
header("Content-Type: application/json");//setting header before sending the JSON response back to the iPhone
echo json_encode($new_body);// Converting the request body into JSON format and sending it as a response back to the iPhone. After execution of this step I'm getting the above weird format data as a response on iPhone.
die;
?>
Generally speaking, you can access the POST parameters individually in one of two ways:
$paramValue = $application->request->params('paramName');
or
$paramValue = $application->request->post('paramName');
More info is available in the documentation: http://docs.slimframework.com/#Request-Variables
When JSON is sent in a POST, you have to access the information from the request body, for example:
$app->post('/some/path', function () use ($app) {
$json = $app->request->getBody();
$data = json_decode($json, true); // parse the JSON into an assoc. array
// do other tasks
});
"Slim can parse JSON, XML, and URL-encoded data out of the box" - http://www.slimframework.com/docs/objects/request.html under "The Request Body".
Easiest way to handle a request in any body form is via the "getParsedBody()". This will do guillermoandrae example but on 1 line instead of 2.
Example:
$allPostVars = $application->request->getParsedBody();
Then you can access any parameters by their key in the array given.
$someVariable = $allPostVars['someVariable'];
Slim will json_decode the post body for you using this middleware
https://www.slimframework.com/docs/v4/middleware/body-parsing.html

Calling ASP.NET Web Api method with PHP

I have the following web method in my web api controller
public HttpResponseMessage PostMakeBooking(FacilityBookingRequest bookingRequest)
{
var returnStatus = HttpStatusCode.OK;
var json = new JavaScriptSerializer().Serialize(bookingRequest);
var response = Request.CreateResponse<CardholderResponse>(returnStatus, cardholderResponse);
return response;
}
When I make this call from my .NET app, my json string appears correctly when I seralize it
{"correlationId":null,"RequestId":"7ec5092a-342a-4e32-9311-10e7df3e3683","BookingId":"BK-123102","CardholderId":"123456","BookingFrom":"\/Date(1370512706448)\/","BookingUntil":"\/Date(1370523506449)\/","DeviceId":"ACU-01-R2","Action":"Add","LoginId":"tester","Password":"tester"}
However, when I made to call from my php script
public function web_request(){
$guid =self::getGUID();
$replace = array("{","}");
$guid = str_replace($replace, "", $guid);
$client = new Zend_Rest_Client("http://203.92.72.221");
$request= new myZendCommon_FacilityBookingRequest();
$request->RequestId =$guid;
$request->BookingFrom ="27/03/2013 05:30";
$request->BookingUntil ="27/03/2013 06:30";
$request->CardholderId ="E0185963";
$request->DeviceId ="ACU-B2-01-R1";
$request->BookingId ="111";
$request->Action ="Add";
$request->LoginId ="tester";
$request->correlationId ="(null)";
$request->Password ="tester";
$request = json_encode($request);
$response = $client->restPost("/ibsswebapi/api/facilitybooking",$request);
print_r($response);
exit();
The call goes to my web method, but when I serialize it using JavaScriptSerializer().Serialize(bookingRequest)
{"correlationId":null,"RequestId":null,"BookingId":null,"CardholderId":null,"BookingFrom":"\/Date(-62135596800000)\/","BookingUntil":"\/Date(-62135596800000)\/","DeviceId":null,"Action":null,"LoginId":null,"Password":null}
All the values are null.
Is something wrong with the script?
I believe Kiran is right. Not sure why some one has felt his answer is not useful. Anyways, my understanding is that you are creating a JSON string and doing a form post of the same. I guess in this case the content type is sent as application/www-form-urlencoded but request body is a JSON string. You can use Fiddler to see how the request is being sent by the PHP script. I don't have the PHP knowledge to tell you how you can post JSON but my guess is that if you just remove the JSON encoding line $request = json_encode($request);, it should be okay.
From ASP.NET Web API point of view, if the request has Content-Type: application/json header and the body has the right JSON or if the request has Content-Type:application/www-form-urlencoded header and the body has the form url encoded content like RequestId=7ec5092a-342a-4e32-9311-10e7df3e3683&BookingId=BK-123102 and so on, web API will absolutely have no problem in binding. Currently, the request is not being sent in the right format for web API to bind.
Are you sending the header Content-Type:application/json in your request?
Also add the following piece of code to catch any model state validation errors:
.
if (!ModelState.IsValid)
{
throw new HttpResponseException(
Request.CreateErrorResponse(HttpStatusCode.BadRequest, this.ModelState));
}

Categories