PHPackages                             initphp/cookies - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Security](/categories/security)
4. /
5. initphp/cookies

ActiveLibrary[Security](/categories/security)

initphp/cookies
===============

InitPHP Cookie Manager

1.1(3y ago)0841MITPHPPHP &gt;=7.2CI passing

Since Jul 25Pushed 3w ago1 watchersCompare

[ Source](https://github.com/InitPHP/Cookies)[ Packagist](https://packagist.org/packages/initphp/cookies)[ RSS](/packages/initphp-cookies/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (2)Dependencies (1)Versions (2)Used By (1)

InitPHP Cookies
===============

[](#initphp-cookies)

A signed, tamper-evident cookie manager for PHP. Values are stored in a single browser cookie whose payload is authenticated with an HMAC-SHA256 signature, so a client cannot read-tamper its way into forging cookie data. Each value can carry its own time-to-live.

[![CI](https://github.com/InitPHP/Cookies/actions/workflows/ci.yml/badge.svg)](https://github.com/InitPHP/Cookies/actions/workflows/ci.yml)[![Latest Stable Version](https://camo.githubusercontent.com/7c61df63993a08333674d9e34068e56141d2c5a45f3e8ce5ccc7b0dba3f9ed54/68747470733a2f2f706f7365722e707567782e6f72672f696e69747068702f636f6f6b6965732f76)](https://packagist.org/packages/initphp/cookies)[![License](https://camo.githubusercontent.com/c13441b6dd2ad4c81ac0fbe284e50a08ffbc7cb247bd78ff11c59040a626afd5/68747470733a2f2f706f7365722e707567782e6f72672f696e69747068702f636f6f6b6965732f6c6963656e7365)](./LICENSE)

Features
--------

[](#features)

- **Signed payload** — the whole cookie is signed with HMAC-SHA256 and verified in constant time (`hash_equals`). A tampered cookie is rejected and transparently re-issued clean.
- **Hardened against object injection** — deserialization runs only *after* the signature check and forbids object instantiation (`allowed_classes => false`).
- **Per-key TTL** — every value may expire independently; expired values are dropped on read and never re-sent.
- **One browser cookie, many values** — group related values under a single named, signed cookie.
- **Deferred writes** — mutations are staged in memory and flushed with a single `send()` (or by the destructor as a safety-net).
- **Testable by design** — the raw cookie source and the low-level writer are injectable, so no superglobal or header juggling is needed in tests.

Requirements
------------

[](#requirements)

- PHP 7.4, 8.0, 8.1, 8.2, 8.3 or 8.4
- [initphp/parameterbag](https://github.com/InitPHP/ParameterBag) `^2.0`

Installation
------------

[](#installation)

```
composer require initphp/cookies
```

Quick start
-----------

[](#quick-start)

```
require_once __DIR__ . '/vendor/autoload.php';

use InitPHP\Cookies\Cookie;

// The salt is the HMAC secret. Keep it private and stable across requests.
$cookie = new Cookie('app_session', getenv('COOKIE_SALT'));

$cookie->set('user_id', 42);
$cookie->set('flash', 'Saved!', 60); // expires in 60 seconds

// Flush the staged changes to the browser before any output is sent.
$cookie->send();
```

On the next request:

```
$cookie = new Cookie('app_session', getenv('COOKIE_SALT'));

$cookie->has('user_id');     // true
$cookie->get('user_id');     // 42 (int — scalar types are preserved)
$cookie->get('missing', '-'); // '-' (default)
$cookie->pull('flash');      // reads the value once, then removes it
```

> **Important:** like PHP's native `setcookie()`, `send()` writes HTTP headers, so it must run before any output. Call it explicitly at the end of your request handling. The destructor calls `send()` as a safety-net, but relying on it is discouraged.

How it works
------------

[](#how-it-works)

The manager keeps an in-memory working copy of your values. Mutating methods change only that copy; nothing reaches the browser until `send()` is called. On `send()` the working copy is:

1. stripped of expired entries,
2. `serialize()`-d and base64-encoded into a `payload`,
3. signed: `signature = hash_hmac('sha256', payload, salt)`,
4. written as the cookie value `"{payload}.{signature}"`.

On construction the incoming cookie is verified before anything is deserialized: the signature is recomputed and compared with `hash_equals()`. If it does not match (tampering, a different salt, a truncated value), the payload is discarded and a clean cookie is re-issued. Because deserialization happens only after that check and with `allowed_classes => false`, a malicious cookie cannot trigger PHP object injection.

Configuration
-------------

[](#configuration)

The third constructor argument overrides the default cookie attributes. Only the keys you pass are changed; the rest keep their defaults.

```
$cookie = new Cookie('app_session', $salt, [
    'ttl'      => 2592000, // transport-cookie lifetime in seconds (30 days)
    'path'     => '/',
    'domain'   => null,
    'secure'   => false,
    'httponly' => true,
    'samesite' => 'Strict', // 'Strict' | 'Lax' | 'None'
]);
```

OptionTypeDefaultDescription`ttl``int``2592000`Lifetime of the **browser** cookie in seconds. Per-value TTLs are separate.`path``string``'/'`Cookie path.`domain``string|null``null`Cookie domain. Omitted from the header when `null`.`secure``bool``false`Send only over HTTPS.`httponly``bool``true`Hide the cookie from JavaScript.`samesite``string``'Strict'``Strict`, `Lax` or `None`. `None` automatically forces `secure => true`.### `ttl` vs. per-key TTL

[](#ttl-vs-per-key-ttl)

- The `ttl` **option** controls how long the *browser* keeps the single transport cookie.
- The `$ttl` **argument** of `set()` / `setArray()` / `push()` controls how long an *individual value* is considered valid by the manager. A `null` per-key TTL means "live as long as the transport cookie".

API
---

[](#api)

```
public function has(string $key): bool;
public function get(string $key, mixed $default = null): mixed;
public function pull(string $key, mixed $default = null): mixed;
public function set(string $key, string|int|float|bool $value, ?int $ttl = null): self;
public function setArray(array $assoc, ?int $ttl = null): self;
public function push(string $key, string|int|float|bool $value, ?int $ttl = null): mixed;
public function all(): array;
public function remove(string ...$key): self;
public function send(): bool;
public function flush(): bool;
public function destroy(): bool;
```

MethodDescription`has`Whether a non-expired value exists. An expired value is removed and reported as absent.`get`The value for `$key`, or `$default` when absent/expired. Scalar types are preserved.`pull`Like `get`, but removes the value afterwards (read-once).`set`Stage a single value. `$ttl` is seconds from now, or `null` for no per-key expiry.`setArray`Stage several values from an associative array sharing one TTL.`push`Like `set`, but returns the staged value.`all`All non-expired values as a `key => value` map.`remove`Stage removal of one or more keys.`send`Write the staged state to the browser. No-op when nothing changed.`flush`Empty all values; the next `send()` writes an empty (still signed) cookie.`destroy`Immediately expire and clear the transport cookie in the browser.Allowed value types are `string`, `bool`, `int`, `float` and numeric strings. Anything else throws `InitPHP\Cookies\Exception\CookieInvalidArgumentException`.

Documentation
-------------

[](#documentation)

Full developer documentation lives in [`docs/`](./docs/README.md): getting started, usage guides, the configuration reference, the security model, the API reference and practical recipes.

Upgrading from 1.x
------------------

[](#upgrading-from-1x)

Version 2.0 is a security and correctness release with intentional breaking changes:

- **Cookie format changed.** The payload is now signed with HMAC-SHA256 (was MD5) and the envelope layout is different, so cookies issued by 1.x are not readable by 2.x — clients simply receive a fresh cookie. The previous 1.x behaviour also made any value set with an explicit TTL unreadable; 2.0 fixes that.
- **PHP 7.4+** is now required (1.x advertised 7.2, but already relied on the PHP 7.3 `setcookie()` options array).
- **`Cookie` is `final`** and its properties are `private`. Extend by composition rather than inheritance.
- **`new` optional constructor arguments** — `$source` (raw cookie array) and `$writer` (low-level writer) were added after `$options`for testability; existing 3-argument calls are unaffected.

Testing
-------

[](#testing)

```
composer install
composer test        # PHPUnit
composer analyse     # PHPStan (level 8)
composer cs:check    # PHP-CS-Fixer (dry-run)
```

Credits
-------

[](#credits)

- [Muhammet ŞAFAK](https://github.com/muhammetsafak) &lt;&gt;

License
-------

[](#license)

Released under the [MIT License](./LICENSE). Copyright © 2022 InitPHP.

###  Health Score

32

—

LowBetter than 69% of packages

Maintenance62

Regular maintenance activity

Popularity9

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1438d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/4b6b34f3ac8938d8ee52ba3bd260680855dc5715c7b2929d9380de30d15a67dd?d=identicon)[muhammetsafak](/maintainers/muhammetsafak)

---

Top Contributors

[![muhammetsafak](https://avatars.githubusercontent.com/u/104234499?v=4)](https://github.com/muhammetsafak "muhammetsafak (4 commits)")

---

Tags

cookiecookie-managercookieshmachmac-sha256initphpphpphp74php8securitysigned-cookiestamper-evident

### Embed Badge

![Health badge](/badges/initphp-cookies/health.svg)

```
[![Health](https://phpackages.com/badges/initphp-cookies/health.svg)](https://phpackages.com/packages/initphp-cookies)
```

###  Alternatives

[mews/purifier

Laravel 5/6/7/8/9/10 HtmlPurifier Package

2.0k18.7M143](/packages/mews-purifier)[paragonie/ecc

PHP Elliptic Curve Cryptography library

24820.0k37](/packages/paragonie-ecc)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
