How to send data via using POST in Zend_Rest_Client - php

There is the next code:
$client = new Zend_Rest_Client('http://test.com/rest');
$client->sendData('data');
if i send via GET (echo $client->get()) it works correct
if via POST (echo $client->post()) i'm getting the next message "No Method Specified."
how to send post using Zend_Rest_Client?

Maybe this helps:
$base_url = 'http://www.example.com';
$endpoint = '/path/to/endpoint';
$data = array(
'param1' => 'value1',
'param2' => 'value2',
'param3' => 'value3'
);
$client = new Zend_Rest_Client($base_url);
$response = $client->restPost($endpoint, $data);
print_r($response);

Below is the link for the Zend_Rest_Client Class as it indicates we can use the public method restPost() to perform the post operation.
restPost ($path, $data=null)
Performs an HTTP POST request to $path.
http://www.sourcecodebrowser.com/zend-framework/1.10.3/class_zend_rest_client.html

Related

Laravel CURL - Passing a string to HTTP URL (Postfields)

I use Laravel 9 and the built-in method Http::withHeaders ($headers)->post($url, $data).
In the $data variable, I pass the string that resulted from http_build_request with the "&" separator. But Laravel tries to make an array out of it and send data.
The API service returns me an error. Please tell me how you can force Laravel to pass exactly a STRING(!), and not an array?
My code:
$array = [
'key1' => 'value1',
'key2' => 'value2',
// etc...
];
$headers = [
'Content-Type' => 'application/x-www-form-urlencoded',
'HMAC' => $hmac
];
$data = http_build_query($array, '', '&');
$response = Http::withHeaders($headers)->post($api_url, $data);
return json_decode($response->getBody()));
If you sending it as x-www-form-urlencoded i gues u should be able to pass the data inside request body.
$response = Http::withHeaders($headers)
->withBody($data)
->asForm()
->post($api_url);
however, i am not sure if this will work
Have you tried, asForm?
$response = Http::withHeaders($headers)->asForm()->post($api_url, $data);
If you would like to send data using the application/x-www-form-urlencoded content type, you should call the asForm method before making your request.

KernelBrowser adding params to body POST request

I'm trying to test an endpoint of my Api with phpunit and the symfony WebTestCase object. I have to send a POST request with the KernelBrowser but I can't figure it out how to add parameters to the body of the request. My request work fine on postman.
I've tried this
$client->request('POST', '/url', ['param1' =>'value1', 'param2' => 'value2']);
It's not working.
I've tried this
$client->request('POST', '/url', [], [], [], '{param1: value, param2: value}');
It doesn't work,
I can't use the $client->submitForm() method because the form is send by another app.
Maybe it came from my Api endpoint because I'm using $_POST variable ?:
$res = false;
if(count($_POST) === 2){
$user = $this->userrepo->findByName($_POST['value1']);
if($user){
if($this->passwordEncoder->isPasswordValid($user[0], $_POST['value2'])){
$res = true;
}
}
}
return new Response($this->serializer->serialize(['isChecked' => $res], 'json'));
My test method has never passed the first if statement,
here my test method:
$client = static::createClient();
$client->request('POST', '/url', ['value1' => 'value1', 'value2' => 'value2']);
$this->assertStringContainsString('{"isChecked":true}', $client->getResponse()->getContent());
Here the POST request I'm trying to send:
curl --location --request POST 'http://localhost:8000/url' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--form 'value1=value1' \
--form 'value2=value2'
Symfony's test client dispatches the request internally. The global $_POST variable will always be empty. You should use the Request object in the controller to access the parameters. The attribute request contains the post data.
public function myAction(Request $request): Response
{
$postParameters = $request->request;
$res = false;
if ($postParameters->count() === 2) {
$user = $this->userrepo->findByName($postParameters->get('value1'));
if ($user) {
if ($this->passwordEncoder->isPasswordValid($user[0], $postParameters->get('value2'))) {
$res = true;
}
}
}
return new Response($this->serializer->serialize(['isChecked' => $res], 'json'));
}
Regarding the different variations of your test call, this one should work with the action above.
$client->request('POST', '/url', ['value1' => 'value1', 'value2' => 'value2']);

Using Config for api token gives error 'URI must be a string or UriInterface' Laravel

I am trying to make an API call.
If I do this: $url = "url-code.com?param1=value1&param2=value2&_token=enter-key-here";
I don't get any error.
If I do this: $url = "url-code.com?param1=value1&param2=value2&_token="+Config::get('app.john_doe_key');
I get an error: 'URI must be a string or UriInterface'
mycode
$statusCode = 200;
$url = "url-code.com?param1=value1&param2=value2&_token="+Config::get('app.john_doe_key');
$client = new Client();
$res = $client->get($url);
//dd($res);
return $res->getBody();
.env
JOHN_DOE_APP_KEY=key
config/app.php
'john_doe_key' => env('JOHN_DOE_APP_KEY'),
All right, based on our discussion in the comments of original question, here's what I would try.
Since everything in it's own works correctly, I would put all of the parameters in their own array:
$parameters = [
'someParam' => 'value',
'someOtherParam' => 'value',
'_token' => Config::get('app.john_doe_key')
];
And use http_build_query() to correctly format them:
$formattedParameters = http_build_query($parameters);
And finally, build the URL with what I have:
$url = "http://url-code.com?{$formattedParameters}";
You should be having a correctly formatted URL to use with Guzzle at this point.

Mock Slim endpoint POST requests with PHPUnit

I want to test the endpoints of my Slim application with PHPUnit. I'm struggling to mock POST requests, as the request body is always empty.
I've tried the approach as described here: Slim Framework endpoint unit testing. (adding the environment variable slim-input)
I've tried writing to php://input directly, but I've found out php://input is read only (the hard way)
The emulation of the environment works correctly as for example the REQUEST_URI is always as expected. I've found out that the body of the request is read out in Slim\Http\RequestBody from php://input.
Notes:
I want to avoid calling the controller methods directly, so I can test everything, including endpoints.
I want to avoid guzzle because it sends an actual request. I do not want to have a server running while testing the application.
my test code so far:
//inherits from Slim/App
$this->app = new SyncApiApp();
// write json to //temp, does not work
$tmp_handle = fopen('php://temp', 'w+');
fwrite($tmp_handle, $json);
rewind($tmp_handle);
fclose($tmp_handle);
//override environment
$this->app->container["environment"] =
Environment::mock(
[
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/1.0/' . $relativeLink,
'slim.input' => $json,
'SERVER_NAME' => 'localhost',
'CONTENT_TYPE' => 'application/json;charset=utf8'
]
);
//run the application
$response = $this->app->run();
//result: the correct endpoint is reached, but $request->getBody() is empty
Whole project (be aware that I've simplified the code on stackoverflow):
https://github.com/famoser/SyncApi/blob/master/Famoser.SyncApi.Webpage/tests/Famoser/SyncApi/Tests/
Note 2:
I've asked at the slimframework forum, link:
http://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973. I'll keep both stackoverflow and discourse.slimframework up to date what is happening.
Note 3:
There is a currently open pull request of mine for this feature: https://github.com/slimphp/Slim/pull/2086
There was help over at http://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973/7, the solution was to create the Request from scratch, and write to the request body.
//setup environment vals to create request
$env = Environment::mock();
$uri = Uri::createFromString('/1.0/' . $relativeLink);
$headers = Headers::createFromEnvironment($env);
$cookies = [];
$serverParams = $env->all();
$body = new RequestBody();
$uploadedFiles = UploadedFile::createFromEnvironment($env);
$request = new Request('POST', $uri, $headers, $cookies, $serverParams, $body, $uploadedFiles);
//write request data
$request->write(json_encode([ 'key' => 'val' ]));
$request->getBody()->rewind();
//set method & content type
$request = $request->withHeader('Content-Type', 'application/json');
$request = $request->withMethod('POST');
//execute request
$app = new App();
$resOut = $app($request, new Response());
$resOut->getBody()->rewind();
$this->assertEquals('full response text', $resOut->getBody()->getContents());
The original blog post which helped to answer was at http://glenneggleton.com/page/slim-unit-testing

Laravel 5 - Returned json is a simple string

Scenario: REST api where a client requests data from server via GET method
I am returning an array from HomeController (Server side: Laravel 5)
return ['Status' => 'Success', 'SearchResponse' => $apiresponse, 'AuthToken' => $property];
The above response is generated from a URL http://example.com/flightSearch
On the client side (Laravel 4)
$input=Input::all();
$url = 'http://example.com/flightSearch';
$data = array(
'client_id' => 'XXX',
'api_secret' => 'YYY',
'method'=>'SearchFlight',
'adult'=>$input['adult'],
'children'=>$input['children'],
'infant'=>$input['infant'],
'departCity'=>$input['departCity'],
'arrivalCity'=>$input['arrivalCity'],
'departDate'=>$input['departDate'],
'returnDate'=>$input['returnDate'],
'journeyType'=>$input['journeyType']
);
$params = http_build_query($data);
$result = file_get_contents($url.'?'.$params);
$response = json_decode($result);
return $response->Status //Works
return $response->AuthToken //Works
return $response->SearchResponse //Throws following Error
Error:
The Response content must be a string or object implementing __toString()
Solution:
The variable $apiresponse was an object returned from a remote server. Adding the variable to an object solved the problem
return ['Status' => 'Success', 'SearchResponse' => array($apiresponse), 'AuthToken' => $property];
Update
Since you have a JSON string you can simply use json_decode():
$response = json_decode($result);
return $response->Status;
The Response content must be a string or object implementing __toString()
This is just because you're returning the $response->SearchResponse from your controller action. Using it like $response->SearchResponse->SomeProperty will just work fine. No need for array($apiresponse) If you want to see all the contents of that variable use var_dump():
var_dump($response->SearchResponse);
Assuming you created the $response with Laravels help this should be an instance of Illuminate\Http\JsonResponse.
You can get the data (already decoded) with getData():
$data = $response->getData();
echo $data->Name
$test1 = array('name'=>'gggg');
print_r($test1); //answer: Array ([name]=>gggg)
$test2 = json_encode($test1);
print_r($test2); //answer: {"name":"gggg"}
$test3 = json_decode($test2);
echo $test3->name; //answer: gggg

Categories