Coding, PHP

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.

3 thoughts on “Guzzle 6 PSR7 Request: How to send custom headers, body and cookies

  1. Gabrieli says:

    Thank you!
    I was looking for this a few days, you saved med. Good post, really helpful!

  2. Kyle says:

    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.

    1. abir says:

      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]);

Leave a Reply

Your email address will not be published. Required fields are marked *