Client Cookies

Zend\Http\Cookies can be used with Zend\Http\Client to manage sending cookies in the request and setting cookies from the response; it is populated from the Set-Cookie headers obtained from a client response, and then used to populate the Cookie headers for a client request. This is highly useful in cases where you need to maintain a user session over consecutive HTTP requests, automatically sending the session ID cookies when required. Additionally, the Zend\Http\Cookies object can be serialized and stored in $_SESSION when needed.

Zend\Http\Client already provides methods for managing cookies for requests; Zend\Http\Cookies manages the parsing of Set-Cookie headers returned in the response, and allows persisting them. Additionally, Cookies can return a subset of cookies that match the current request, ensuring you are only sending relevant cookies.

Usage

Cookies is an extension of Zend\Http\Headers, and inherits its methods. It can be instantiated without any arguments.

use Zend\Http\Cookies;

$cookies = new Cookies();

On your first client request, you likely won't have any cookies, so the instance does nothing.

Once you've made your first request, you can start using it. Populate it from the response:

$response = $client->send();

$cookies->addCookiesFromResponse($response, $client->getUri());

Alternately, you can create your initial Cookies instance using the static fromResponse() method:

$cookies = Cookies::fromResponse($response, $client->getUri());

On subsequent requests, we'll notify the client of our cookies. To do this, we should use the same URI we'll use for the request.

$client->setUri($uri);
$client->setCookies($cookies->getMatchingCookies($uri));

After the request, don't forget to add any cookies returned!

Essentially, Cookies aggregates all cookies for our client interactions, and allows us to send only those relevant to a given request.

Serializing and caching cookies

To cache cookies — e.g., to store in $_SESSION, or between job invocations — you will need to serialize them. Zend\Http\Cookies provides this functionality via the getAllCookies() method.

If your cache storage allows array structures, use the COOKIE_STRING_ARRAY constant:

$cookiesToCache = $cookies->getAllCookies($cookies::COOKIE_STRING_ARRAY);

If your cache storage only allows string values, use COOKIE_STRING_CONCAT:

$cookiesToCache = $cookies->getAllCookies($cookies::COOKIE_STRING_CONCAT);

When you retrieve the value later, you can test its type to determine how to deserialize the values:

use Zend\Http\Cookies;
use Zend\Http\Headers;

$cookies = new Cookies();

if (is_array($cachedCookies)) {
    foreach ($cachedCookies as $cookie) {
        $cookies->addCookie($cookie);
    }
} elseif (is_string($cachedCookies)) {
    foreach (Headers::fromString($cachedCookies) as $cookie) {
        $cookies->addCookie($cookie);
    }
}

Public methods

Besides the methods demonstrated in the examples, Zend\Http\Cookies defines the following:

Method signature Description
static fromResponse(Response $response, string $refUri) : Cookies Create a Cookies instance from a response and the request URI. Parses all Set-Cookie headers, maps them to the URI, and aggregates them.
addCookie(string|SetCookie $cookie, string $refUri = null) : void Add a cookie, mapping it to the given URI. If no URI is provided, it will be inferred from the cookie value's domain and path.
addCookiesFromResponse(Response $response, string $refUri) : void Add all Set-Cookie values from the provided response, mapping to the given URI.
getAllCookies(int $retAs = self::COOKIE_OBJECT) : array|string Retrieve all cookies. Returned array will have either SetCookie instances (the default), strings for each Set-Cookie declaration, or a single string containing all declarations, based on the COOKIE_* constant used.
getCookie(/* ... */) : string|SetCookie Retrieve a single cookie by name for the given URI. See below for argument details.
getMatchingCookies(/* ... */) : array See below for details.
isEmpty() : bool Whether or not the instance aggregates any cookies currently.
reset() : void Clear all aggregated cookies from the instance.

getCookie() accepts the following arguments, in the following order:

Argument Description
string $uri URI to match when retrieving the cookie. Will use its protocol, domain, and path.
string $cookieName The specific cookie name to retrieve.
int $retAs = self::COOKIE_OBJECT How to return matched cookies; defaults to SetCookie objects. Can be any of the Cookies::COOKIE_* constant values.

getMatchingCookies() accepts the following arguments, in the following order:

Argument Description
string $uri URI to match when retrieving cookies. Will use its protocol, domain, and path.
bool $matchSessionCookies = true Whether or not to also return related session cookies.
int $retAs = self::COOKIE_OBJECT How to return matched cookies; defaults to SetCookie objects. Can be any of the Cookies::COOKIE_* constant values.
int $now = null Timestamp against which to match; defaults to time(). Any expired cookies will be ignored.