Currently, I'm using Laravel HTTP client to make a request to an external URL. Mostly, the package working fine until I try to implement on_stats option from Guzzle.
From the doc, it says we can use Guzzle options using withMethod() method.
Here is my sample code to implement on_stats option using HTTP client.
$response = Http::withOptions([
'debug' => true,
'on_stats' => function(\GuzzleHttp\TransferStats $stats) {
Log::debug($stats->getTransferTime());
}
])
->get('https://laravel.com');
dd($response->status());
The code above will produce an error with the message:
Second array member is not a valid method
However, when I'm using the option within the Guzzle package directly, it works fine.
$client = new \GuzzleHttp\Client;
$response = $client->get('https://laravel.com', [
'on_stats' => function(\GuzzleHttp\TransferStats $stats) {
Log::debug($stats->getTransferTime());
}
]);
dd((string) $response->getStatusCode());
Any idea why this is happening? Is it a bug from the HTTP client wrapper from Laravel?
FYI, I'm using Laravel 8.x.
Thanks.
withOptions uses this code:
return tap($this, function ($request) use ($options) {
return $this->options = array_merge_recursive($this->options, $options);
});
So I'm guessing passing a closure in may not work, since it's not actually an array. From https://laracasts.com/discuss/channels/requests/httpwithtoken-get-total-time-of-request , you can get it from the response instead, so try this:
$client = new \GuzzleHttp\Client;
$response = $client->get('https://laravel.com');
Log::debug($response->transferStats->getTransferTime());
I try to make a RESTful api using slim framework.
I do not know details about the slim framework, because i'm beginner of this framework.
So, I followed all steps of how to get data in slimframework. But i can't get POST data.
Follow is my code to get POST data.
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
$app->post('/registration/user', function (Request $request, Response $response) use ($app) {
$data = $request->getParsedBody();
$name = $_POST['name'];
echo '1 : '.$data['name'];
echo '2 : '.$name;
});
That is result of when i send name data.
what i have to do for get post data??
Do you have any idea?
I use \Slim\Http\Request $request->getParsedBody() in my routes. The method contains all the $_POST data.
Example:
$postArr = $request->getParsedBody();
$name = $postArr["name"];
The following can be used:
$body= file_get_contents("php://input");
// $body = $request->getBody();
$data = json_decode($body, true);
I asked a similar question earlier, in a nutshell I have an API application that takes json requests and outputs an json response.
For instance here is one of the requests that I need to test out, how can I use this json object with my testing to emulate a 'real request'
{
"request" : {
"model" : {
"code" : "PR92DK1Z"
}
}
The response is straightforward (this bit has been done).
From other users on here this is the optimised method using Yii to do this, I am just unsure how to emulate the json request - e.g essentially send a JSON HTTP request, can anyone assist on how to do this?
public function actionMyRequest() {
// somehow add my json request...
$requestBody = Yii::app()->request->getRawBody();
$parsedRequest = CJSON::decode($requestBody);
$code = $parsedRequest["request"]["model"]["code"];
}
I don't understand if you want your app to send an http request and get the result or at the opposite receive a http request
I answered for the first assumption, I'll change my answer if you want the other
For me the best way to send an HTTP request is to use Guzzle http client.
This is not a yii extension, but you can use third party libraries with yii.
Here's an example from Guzzle page:
$client = new GuzzleHttp\Client();
$res = $client->get('https://api.github.com/user', [
'auth' => ['user', 'pass']
]);
echo $res->getStatusCode(); // 200
echo $res->getHeader('content-type'); // 'application/json; charset=utf8'
echo $res->getBody();
So in your case you could do something like:
public function actionMyRequest() {
$client = new GuzzleHttp\Client();
$res = $client->get('https://api.your-url.com/');
$requestBody = $res->getBody();
$parsedRequest = CJSON::decode($requestBody);
$code = $parsedRequest["request"]["model"]["code"];
}
What I want is get an object from an API with a HTTP (eg, jQuery's AJAX) request to an external api. How do I start? I did research on Mr Google but I can't find anything helping.
Im starting to wonder is this is even possible?
In this post Laravel 4 make post request from controller to external url with data it looks like it can be done. But there's no example nor any source where to find some documentation.
Please help me out?
Based upon an answer of a similar question here:
https://stackoverflow.com/a/22695523/1412268
Take a look at Guzzle
$client = new GuzzleHttp\Client();
$res = $client->get('https://api.github.com/user', ['auth' => ['user', 'pass']]);
echo $res->getStatusCode(); // 200
echo $res->getBody(); // { "type": "User", ....
We can use package Guzzle in Laravel, it is a PHP HTTP client to send HTTP requests.
You can install Guzzle through composer
composer require guzzlehttp/guzzle:~6.0
Or you can specify Guzzle as a dependency in your project's existing composer.json
{
"require": {
"guzzlehttp/guzzle": "~6.0"
}
}
Example code in laravel 5 using Guzzle as shown below,
use GuzzleHttp\Client;
class yourController extends Controller {
public function saveApiData()
{
$client = new Client();
$res = $client->request('POST', 'https://url_to_the_api', [
'form_params' => [
'client_id' => 'test_id',
'secret' => 'test_secret',
]
]);
echo $res->getStatusCode();
// 200
echo $res->getHeader('content-type');
// 'application/json; charset=utf8'
echo $res->getBody();
// {"type":"User"...'
}
You just want to call an external URL and use the results? PHP does this out of the box, if we're talking about a simple GET request to something serving JSON:
$json = json_decode(file_get_contents('http://host.com/api/stuff/1'), true);
If you want to do a post request, it's a little harder but there's loads of examples how to do this with curl.
So I guess the question is; what exactly do you want?
As of Laravel v7.X, the framework now comes with a minimal API wrapped around the Guzzle HTTP client. It provides an easy way to make get, post, put, patch, and delete requests using the HTTP Client:
use Illuminate\Support\Facades\Http;
$response = Http::get('http://test.com');
$response = Http::post('http://test.com');
$response = Http::put('http://test.com');
$response = Http::patch('http://test.com');
$response = Http::delete('http://test.com');
You can manage responses using the set of methods provided by the Illuminate\Http\Client\Response instance returned.
$response->body() : string;
$response->json() : array;
$response->status() : int;
$response->ok() : bool;
$response->successful() : bool;
$response->serverError() : bool;
$response->clientError() : bool;
$response->header($header) : string;
$response->headers() : array;
Please note that you will, of course, need to install Guzzle like so:
composer require guzzlehttp/guzzle
There are a lot more helpful features built-in and you can find out more about these set of the feature here: https://laravel.com/docs/7.x/http-client
This is definitely now the easiest way to make external API calls within Laravel.
Updated on March 21 2019
Add GuzzleHttp package using composer require guzzlehttp/guzzle:~6.3.3
Or you can specify Guzzle as a dependency in your project's composer.json
{
"require": {
"guzzlehttp/guzzle": "~6.3.3"
}
}
Include below line in the top of the class where you are calling the API
use GuzzleHttp\Client;
Add below code for making the request
$client = new Client();
$res = $client->request('POST', 'http://www.exmple.com/mydetails', [
'form_params' => [
'name' => 'george',
]
]);
if ($res->getStatusCode() == 200) { // 200 OK
$response_data = $res->getBody()->getContents();
}
Definitively, for any PHP project, you may want to use GuzzleHTTP for sending requests.
Guzzle has very nice documentation you can check here.
I just want to say that, you probably want to centralize the usage of the Client class of Guzzle in any component of your Laravel project (for example a trait) instead of being creating Client instances on several controllers and components of Laravel (as many articles and replies suggest).
I created a trait you can try to use, which allows you to send requests from any component of your Laravel project, just using it and calling to makeRequest.
namespace App\Traits;
use GuzzleHttp\Client;
trait ConsumesExternalServices
{
/**
* Send a request to any service
* #return string
*/
public function makeRequest($method, $requestUrl, $queryParams = [], $formParams = [], $headers = [], $hasFile = false)
{
$client = new Client([
'base_uri' => $this->baseUri,
]);
$bodyType = 'form_params';
if ($hasFile) {
$bodyType = 'multipart';
$multipart = [];
foreach ($formParams as $name => $contents) {
$multipart[] = [
'name' => $name,
'contents' => $contents
];
}
}
$response = $client->request($method, $requestUrl, [
'query' => $queryParams,
$bodyType => $hasFile ? $multipart : $formParams,
'headers' => $headers,
]);
$response = $response->getBody()->getContents();
return $response;
}
}
Notice this trait can even handle files sending.
If you want more details about this trait and some other stuff to integrate this trait to Laravel, check this article. Additionally, if interested in this topic or need major assistance, you can take my course which guides you in the whole process.
I hope it helps all of you.
Best wishes :)
Basic Solution for Laravel 8 is
use Illuminate\Support\Facades\Http;
$response = Http::get('http://example.com');
I had conflict between "GuzzleHTTP sending requests" and "Illuminate\Http\Request;" don't ask me why... [it's here to be searchable]
So looking for 1sec i found in Laravel 8 Doc...
**Guzzle is inside the Laravel 8 Http Request !**
https://laravel.com/docs/8.x/http-client#making-requests
as you can see
https://laravel.com/docs/8.x/http-client#introduction
Laravel provides an expressive, minimal API around the Guzzle HTTP
client, allowing you to quickly make outgoing HTTP requests to
communicate with other web applications. Laravel's wrapper around
Guzzle is focused on its most common use cases and a wonderful
developer experience.
It worked for me very well, have fun and if helpful point up!
I also created trait similar to #JuanDMeGonthat's that u can use anywhere in your project.Please check this out
trait ApiRequests
{
public function get($url, $data = null)
{
try {
$response = Http::get($this->base_url . $url, $data);
} catch (\Exception $e) {
info($e->getMessage());
abort(503);
}
if ( $response->status() == 401) {
throw new AuthenticationException();
} else if (! $response->successful()) {
abort(503);
}
return $response->json();
}
public function post($url, $data = [])
{
$token = session()->get('token');
try {
$response = Http::acceptJson()->withToken($token)->post($this->base_url . $url, $data);
} catch (\Exception $e) {
abort(503);
}
if ($response->status() == 401 && !request()->routeIs('login')) {
throw new AuthenticationException();
}
return $response;
}
}
class Controller extends BaseController
{
protected $base_url;
use AuthorizesRequests, DispatchesJobs, ValidatesRequests, ApiRequests;
public function __construct()
{
$this->base_url = env("BASE_URL","http://192.168.xxxxxxx");
View::share('base_url', $this->base_url);
}
}
You can use Httpful :
Website : http://phphttpclient.com/
Github : https://github.com/nategood/httpful
Here is the simple call for laravel 9.4
Route::get('/currency', function () {
$response = Http::withHeaders([
'x-api-key' => 'prtl6749387986743898559646983194',
])->get('https://partners.api.skyscanner.net/apiservices/v3/culture/currencies');
return response()->json(['status'=> true,'data'=> json_decode($response->body()), 'Message'=>"Currency retrieved successfully"], 200);
});
Don't forget to import
use Illuminate\Support\Facades\Http;
I'm working on crawling web sites and there is no problem for parsing HTML with Goutte so far. But I need to retrieve JSON from a web site and because of the cookie management, I don't want to do this with file_get_contents() - that doesn't work.
I can do with pure cURL but in this case I just want to use Goutte and don't want to use any other library.
So is there any method that I can parse only text via Goutte or do I really have to do this with good old methods?
/* Sample Code */
$client = new Client();
$crawler = $client->request('foo');
$crawler = $crawler->filter('bar'); // of course not working
Thank you.
After very deep search inside Goutte libraries I found a way and I wanted to share. Because Goutte is really powerful library but there are so complicated documentation.
Parsing JSON via (Goutte > Guzzle)
Just get needed output page and store json into an array.
$client = new Client(); // Goutte Client
$request = $client->getClient()->createRequest('GET', 'http://***.json');
/* getClient() for taking Guzzle Client */
$response = $request->send(); // Send created request to server
$data = $response->json(); // Returns PHP Array
Parsing JSON with Cookies via (Goutte + Guzzle) - For authentication
Send request one of the page of the site (main page looks better) to get cookies and then use these cookies for authentication.
$client = new Client(); // Goutte Client
$crawler = $client->request("GET", "http://foo.bar");
/* Send request directly and get whole data. It includes cookies from server and
it automatically stored in Goutte Client object */
$request = $client->getClient()->createRequest('GET', 'http://foo.bar/baz.json');
/* getClient() for taking Guzzle Client */
$cookies = $client->getRequest()->getCookies();
foreach ($cookies as $key => $value) {
$request->addCookie($key, $value);
}
/* Get cookies from Goutte Client and add to cookies in Guzzle request */
$response = $request->send(); // Send created request to server
$data = $response->json(); // Returns PHP Array
I hope it helps. Because I almost spend 3 days to understand Gouttle and it's components.
I figured this out after several hours of search , simply do this :
$client = new Client(); // Goutte Client
$crawler = $client->request("GET", "http://foo.bar");
$jsonData = $crawler->text();
mithataydogmus' solution didn't work for me. I created a new class "BetterClient":
use Goutte\Client as GoutteClient;
class BetterClient extends GoutteClient
{
private $guzzleResponse;
public function getGuzzleResponse() {
return $this->guzzleResponse;
}
protected function createResponse($response)
{
$this->guzzleResponse = $response;
return parent::createResponse($response);
}
}
Usage:
$client = new BetterClient();
$request = $client->request('GET', $url);
$data = $client->getGuzzleResponse()->json();
I also could get JSON with:
$client->getResponse()->getContent()->getContents()