Skip to content

Cookies

Installation

composer require qubus/http

CodefyPHP Cookies tackles two problems, managing Cookie Request headers and managing Set-Cookie Response headers. It does this by way of introducing a Cookies class to manage collections of Cookie instances and a SetCookies class to manage collections of SetCookie instances.

<?php

// Get a collection representing the cookies in the Cookie headers
// of a PSR-7 Request.
$cookies = Qubus\Http\Cookies\Cookies::fromRequest($request);

// Get a collection representing the cookies in the Set-Cookie headers
// of a PSR-7 Response
$setCookies = Qubus\Http\Cookies\SetCookies::fromResponse($response);

After modifying these collections in some way, they are rendered into a PSR-7 Request or PSR-7 Response like so:

<?php

// Render the Cookie headers and add them to the headers of a
// PSR-7 Request.
$request = $cookies->renderIntoCookieHeader($request);

// Render the Set-Cookie headers and add them to the headers of a
// PSR-7 Response.
$response = $setCookies->renderIntoSetCookieHeader($response);

Like PSR-7 Messages, CookieCollection, Cookies, SetCookieCollection, and SetCookies are all represented as immutable value objects and all mutators will return new instances of the original with the requested changes.

Request Cookies

Requests include cookie information in the Cookie request header. The cookies in this header are represented by the CookieCollection class.

<?php

use Qubus\Http\Cookies\CookieCollection;

$cookie = CookieCollection::create('username', 'davidspade');

To easily work with request cookies, use the CookiesRequest facade.

The get method will return a CookieCollection instance. If no cookie by the specified name exists, the returned CookieCollection instance will have a null value.

The optional third parameter to the get() method sets a default value that should be used if a cookie does not exist.

<?php

use Qubus\Http\Cookies\CookiesRequest;

$cookie = CookiesRequest::get($request, 'userId');
//or with a default value
$cookie = CookiesRequest::get($request, 'userId', '01HDYTTNRME1KRZQJCGTRRH2HV');

The set() method will either add a cookie or replace an existing cookie.

The CookieCollection primitive is used as the second argument.

<?php

use Qubus\Http\Cookies\CookieCollection;
use Qubus\Http\Cookies\CookiesRequest;

$request = CookiesRequest::set($request, CookieCollection::create('userId', '01HDYV2CNCE0F8RCSY8HADMS0M'));

The modify method allows for replacing the contents of a cookie based on the current cookie with the specified name. The third argument is a callable that takes a CookieCollection instance as its first argument and is expected to return a CookieCollection instance.

If no cookie by the specified name exists, a new Cookie instance with a null value will be passed to the callable.

<?php

use Qubus\Http\Cookies\CookieCollection;
use Qubus\Http\Cookies\CookiesRequest;

$modify = function (CookieCollection $cookie) {
    $value = $cookie->getValue();

    // ... inspect current $value and determine if $value should
    // change or if it can stay the same. In all cases, a cookie
    // should be returned from this callback...

    return $cookie->withValue($value);
}

$request = CookiesRequest::modify($request, 'userId', $modify);

The remove() method removes a cookie from the request headers if it exists.

<?php

use Qubus\Http\Cookies\CookiesRequest;

$request = CookiesRequest::remove($request, 'userId');

Note

Note that this does not cause the client to remove the cookie. Take a look at the SetCookie class' expire() method to do that.

Response Cookies

Responses include cookie information in the Set-Cookie response header. The cookies in these headers are represented by the SetCookieCollection class.

<?php

use Qubus\Http\Cookies\SameSite;
use Qubus\Http\Cookies\SetCookieCollection;

$setCookie = SetCookieCollection::create('userId')
    ->withValue('01K5FGJ82ZEEN9M6CTMH144PEX')
    ->withExpires('Mon, 15-Jan-2024 21:47:38 GMT')
    ->withMaxAge(500)
    ->rememberForever()
    ->withPath('/')
    ->withDomain('.example.com')
    ->withSecure(true)
    ->withHttpOnly(true)
    ->withSameSite(SameSite::lax());

Note

To easily work with response cookies, use the CookiesResponse facade.

The get() method will return a SetCookieCollection instance. If no cookie by the specified name exists, the returned SetCookieCollection instance will have a null value.

The optional third parameter to get() sets a default value that should be used if a cookie does not exist.

<?php

use Qubus\Http\Cookies\CookiesResponse;

$setCookie = CookiesResponse::get($response, 'userId');
$setCookie = CookiesResponse::get($response, 'userId', '01HDYTTNRME1KRZQJCGTRRH2HV');

The set() method will either add a cookie or replace an existing cookie.

The SetCookieCollection primitive is used as the second argument.

<?php

use Qubus\Http\Cookies\CookiesResponse;
use Qubus\Http\Cookies\SetCookieCollection;

$response = CookiesResponse::set(
    $response,
    SetCookieCollection::create('token')
        ->withValue('a9s87dfz978a9')
        ->withDomain('example.com')
        ->withPath('/')
);

The modify() method allows for replacing the contents of a cookie based on the current cookie with the specified name. The third argument is a callable that takes a SetCookieCollection instance as its first argument and is expected to return a SetCookieCollection instance.

If no cookie by the specified name exists, a new SetCookieCollection instance with a null value will be passed to the callable.

<?php

use Qubus\Http\Cookies\CookiesResponse;
use Qubus\Http\Cookies\SetCookieCollection;

$modify = function (SetCookieCollection $setCookie) {
    $value = $setCookie->getValue();

    // ... inspect current $value and determine if $value should
    // change or if it can stay the same. In all cases, a cookie
    // should be returned from this callback...

    return $setCookie
        ->withValue($newValue)
        ->withExpires($newExpires);
}

$response = CookiesResponse::modify($response, 'userId', $modify);

The remove() method removes a cookie from the response if it exists.

<?php

use Qubus\Http\Cookies\CookiesResponse;

$response = CookiesResponse::remove($response, 'userId');

The expire() method sets a cookie with an expiry date in the far past. This causes the client to remove the cookie.

Note that in order to expire a cookie, you need to configure its Set-Cookie header just like when you initially wrote the cookie (i.e. same domain/path). The easiest way to do this is to re-use the same code for configuring the header when setting as well as expiring the cookie:

<?php

use Qubus\Http\Cookies\CookiesResponse;
use Qubus\Http\Cookies\SetCookieCollection;

$setCookie = SetCookieCollection::create('token')
    ->withValue('UQdfdafpJJ23k111m')
    ->withPath('/')
    ->withDomain('.example.com');

CookiesResponse::set($response, $setCookie->expire());