defaults = array_merge([ 'expires' => 0, 'path' => '/', 'domain' => '', 'secure' => false, 'httponly' => true, 'samesite' => 'Lax' ], $defaults); } /** * Set a cookie */ public function set(string $name, string $value, array $options = []): bool { $options = array_merge($this->defaults, $options); // Convert lifetime to expires timestamp if provided if (isset($options['lifetime'])) { $options['expires'] = time() + $options['lifetime']; unset($options['lifetime']); } return setcookie($name, $value, $options); } /** * Get a cookie value */ public function get(string $name, ?string $default = null): ?string { return $_COOKIE[$name] ?? $default; } /** * Check if a cookie exists */ public function has(string $name): bool { return isset($_COOKIE[$name]); } /** * Delete a cookie */ public function delete(string $name, array $options = []): bool { $options = array_merge($this->defaults, $options); $options['expires'] = time() - 3600; // Remove from $_COOKIE superglobal unset($_COOKIE[$name]); return setcookie($name, '', $options); } /** * Set a cookie that expires when browser closes */ public function setSession(string $name, string $value, array $options = []): bool { $options['expires'] = 0; return $this->set($name, $value, $options); } /** * Set a cookie with specific lifetime in seconds */ public function setWithLifetime(string $name, string $value, int $lifetime, array $options = []): bool { $options['lifetime'] = $lifetime; return $this->set($name, $value, $options); } /** * Set a cookie that expires in specified days */ public function setForDays(string $name, string $value, int $days, array $options = []): bool { return $this->setWithLifetime($name, $value, $days * 86400, $options); } /** * Set a cookie that expires in specified hours */ public function setForHours(string $name, string $value, int $hours, array $options = []): bool { return $this->setWithLifetime($name, $value, $hours * 3600, $options); } /** * Set a cookie that expires in specified minutes */ public function setForMinutes(string $name, string $value, int $minutes, array $options = []): bool { return $this->setWithLifetime($name, $value, $minutes * 60, $options); } /** * Set a forever cookie (5 years) */ public function forever(string $name, string $value, array $options = []): bool { return $this->setWithLifetime($name, $value, 157680000, $options); // 5 years } /** * Get all cookies */ public function all(): array { return $_COOKIE; } /** * Clear all cookies */ public function clear(): void { foreach ($_COOKIE as $name => $value) $this->delete($name); } /** * Set default options */ public function setDefaults(array $defaults): void { $this->defaults = array_merge($this->defaults, $defaults); } /** * Get default options */ public function getDefaults(): array { return $this->defaults; } /** * Create a signed cookie value */ public function sign(string $value, string $secret): string { $signature = hash_hmac('sha256', $value, $secret); return base64_encode($value . '|' . $signature); } /** * Verify and extract signed cookie value */ public function verify(string $signedValue, string $secret): ?string { $decoded = base64_decode($signedValue); if (!$decoded || !str_contains($decoded, '|')) return null; [$value, $signature] = explode('|', $decoded, 2); $expectedSignature = hash_hmac('sha256', $value, $secret); if (!hash_equals($expectedSignature, $signature)) return null; return $value; } /** * Set a signed cookie */ public function setSigned(string $name, string $value, string $secret, array $options = []): bool { $signedValue = $this->sign($value, $secret); return $this->set($name, $signedValue, $options); } /** * Get and verify a signed cookie */ public function getSigned(string $name, string $secret, ?string $default = null): ?string { $signedValue = $this->get($name); if ($signedValue === null) return $default; $value = $this->verify($signedValue, $secret); return $value !== null ? $value : $default; } /** * Encrypt a cookie value */ public function encrypt(string $value, string $key): string { $iv = random_bytes(16); $encrypted = openssl_encrypt($value, 'AES-256-CBC', $key, 0, $iv); return base64_encode($iv . '|' . $encrypted); } /** * Decrypt a cookie value */ public function decrypt(string $encryptedValue, string $key): ?string { $decoded = base64_decode($encryptedValue); if (!$decoded || !str_contains($decoded, '|')) return null; [$iv, $encrypted] = explode('|', $decoded, 2); $decrypted = openssl_decrypt($encrypted, 'AES-256-CBC', $key, 0, $iv); return $decrypted !== false ? $decrypted : null; } /** * Set an encrypted cookie */ public function setEncrypted(string $name, string $value, string $key, array $options = []): bool { $encryptedValue = $this->encrypt($value, $key); return $this->set($name, $encryptedValue, $options); } /** * Get and decrypt a cookie */ public function getEncrypted(string $name, string $key, ?string $default = null): ?string { $encryptedValue = $this->get($name); if ($encryptedValue === null) return $default; $value = $this->decrypt($encryptedValue, $key); return $value !== null ? $value : $default; } }