
Guzzle 6 PSR7 Request: How to send custom headers, body and cookies
So, I recently upgraded to Guzzle 6. It has PSR7 Request/Response classes which have a lot of new features.
Documentation is quite good and is located here:
http://docs.guzzlephp.org/en/latest/psr7.html
But I was still having some trouble forming a request for my Data Mining php code.
I needed to send a request with custom headers, body and also some modified cookies.
My Sample Code:
Firstly, if you are using guzzle phar, then include it:
require_once ("lib\guzzle.phar");
Initialize Client:
$client = new GuzzleHttp\Client(
array(
"defaults" => array(
"allow_redirects" => true, "exceptions" => true,
"decode_content" => true, "verify" => false,
),
//'cookies' => $cookie_jar,
'cookies' => true,
)
);
If you are sending requests to a site with certificate issues, it’s best to keep “verify” => false which won’t verify the certificate.
Also, if response content is gzipped you can keep: “decode_content” => true
Note the line: ‘cookies’ => true
If you have a common client which will make multiple requests to the same site and you need to share cookies then just define ‘cookies’ as true.
If however you need to have different cookie jars or you need to modify cookies before making any requests, then create a cookie jar.
Using a cookie jar $cookie_jar: ‘cookies’ => $cookie_jar
Function to Request URL:
This function sends a request, gets the response and returns a Symfony Crawler object (Symfony\Component\DomCrawler\Crawler).
$url var is a string (URL to be requested)
$params var contains the request type, all header values and body.
/**
* Function to use GET request to get URL
* @param $params Request parameters
* @return returns null if error or returns crawler var if success
*/
function crawlURL($url, $params = null) {
try {
// init
$body = null;
$request_params = array();
$headers = array();
// Init cookie jar here
$cookie_jar = null;
$client = new GuzzleHttp\Client(
array(
"defaults" => array(
"allow_redirects" => true, "exceptions" => true,
"decode_content" => true,
),
//'cookies' => $cookie_jar,
'cookies' => true,
'verify' => false,
)
);
if($params == null) {
$params = array();
}
// Default type is GET
if(!isset($params["type"])) {
$params["type"] = "GET";
}
// Get custom headers
if($params != null) {
foreach($params as $param_name => $param_value) {
if($param_name == "type") {
// ignore
continue;
}
if($param_name == "body") {
$body = $params["body"];
continue;
}
$headers[$param_name] = $param_value;
}
}
$request_params['headers'] = $headers;
if($body != null) {
$request_params['body'] = $body;
}
$request = new GuzzleHttp\Psr7\Request($params["type"], $url, $headers, $body);
$response = $client->send($request);
$response_body = $response->getBody();
$crawler = new Symfony\Component\DomCrawler\Crawler((string) $response_body, $url);
$status_code = $response->getStatusCode();
if($cookie_jar == null) {
$cookie_jar = new \GuzzleHttp\Cookie\CookieJar;
$cookie_jar->extractCookies($request, $response);
// Make changes to cookies if required
// and send next request here using the new cookie jar
//if($cookie_jar != null) {
// $request_params['cookies'] = $cookie_jar;
//}
//$response = $client->request($params["type"], $url, $request_params);
}
return $crawler;
} catch(Exception $e) {
echo $e->getMessage();
return null;
}
}
Usage:
$params = array();
$params['Proxy-Connection'] = 'keep-alive';
$params['Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
$params['Accept-Encoding'] = 'gzip, deflate, sdch';
$params['Accept-Language'] = 'en-US,en;q=0.8';
$params['Cache-Control'] = 'max-age=0';
$params['type'] = 'POST';
$params['body'] = 'somevar=somevalue';
$crawler = crawlURL("http://sample.url", $params);
If you are using common cookies and are using: ‘cookies’ => true
then you don’t need this code:
if($cookie_jar == null) {
$cookie_jar = new \GuzzleHttp\Cookie\CookieJar;
$cookie_jar->extractCookies($request, $response);
// Make changes to cookies if required
}
This is only useful when you need to change the cookies inside cookie jar and send only selective cookies.
You can do that using the setCookie function of your CookieJar.
This way to send request:
$response = $client->request($params["type"], $url, $request_params);
Is useful when there is a specific cookie_jar.
Make sure cookies are set:
Best way to make sure that cookies are being set is to capture the HTTP requests using a tool like Fiddler.
Check out this post on how to use fiddler with Guzzle:
https://tricksty.com/coding/guzzle-how-to-capture-requests-responses-using-fiddler
If you have already been using a previous Guzzle library, then migrating to the new PSR7 approach can be a bit time consuming. But it will be good for you in the long term. This will give you greater control over your Request/Response objects. And also, working with any other library that utilizes PSR-7 interfaces will be a lot easier.
Thank you!
I was looking for this a few days, you saved med. Good post, really helpful!
Good Post!
How do I send a cookie jar var with this code?
$request = new GuzzleHttp\Psr7\Request($params[“type”], $url, $headers, $body);
$response = $client->send($request);
Put it directly in headers? Because its not working.
Hi Kyle,
You can send your custom cookie jar with the send function:
$request = new GuzzleHttp\Psr7\Request($params["type"], $url, $headers, $body);
$response = $client->send($request, ["cookies" => $cookie_jar]);