7 * This source file is subject to version 1.0 of the Zend Framework
8 * license, that is bundled with this package in the file LICENSE.txt,
9 * and is available through the world-wide-web at the following URL:
10 * http://framework.zend.com/license/new-bsd. If you did not
11 * receive a copy of the Zend Framework license and are unable to
12 * obtain it through the world-wide-web, please send a note to
13 * license@zend.com so we can mail you a copy immediately.
18 * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com/)
19 * @version $Id: Cookie.php 8064 2008-02-16 10:58:39Z thomas $
20 * @license http://framework.zend.com/license/new-bsd New BSD License
23 require_once 'external/Zend/Uri/Http.php';
26 * Zend_Http_Cookie is a class describing an HTTP cookie and all it's parameters.
28 * Zend_Http_Cookie is a class describing an HTTP cookie and all it's parameters. The
29 * class also enables validating whether the cookie should be sent to the server in
30 * a specified scenario according to the request URI, the expiry time and whether
31 * session cookies should be used or not. Generally speaking cookies should be
32 * contained in a Cookiejar object, or instantiated manually and added to an HTTP
35 * See http://wp.netscape.com/newsref/std/cookie_spec.html for some specs.
39 * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com/)
40 * @license http://framework.zend.com/license/new-bsd New BSD License
42 class Zend_Http_Cookie
{
79 * Whether the cookie is secure or not
86 * Cookie object constructor
88 * @todo Add validation of each one of the parameters (legal domain, etc.)
91 * @param string $value
93 * @param string $domain
97 public function __construct($name, $value, $domain, $expires = null, $path = null, $secure = false) {
98 if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
99 require_once 'external/Zend/Http/Exception.php';
100 throw new Zend_Http_Exception("Cookie name cannot contain these characters: =,; \\t\\r\\n\\013\\014 ({$name})");
103 if (! $this->name
= (string)$name) {
104 require_once 'external/Zend/Http/Exception.php';
105 throw new Zend_Http_Exception('Cookies must have a name');
108 if (! $this->domain
= (string)$domain) {
109 require_once 'external/Zend/Http/Exception.php';
110 throw new Zend_Http_Exception('Cookies must have a domain');
113 $this->value
= (string)$value;
114 $this->expires
= ($expires === null ?
null : (int)$expires);
115 $this->path
= ($path ?
$path : '/');
116 $this->secure
= $secure;
124 public function getName() {
133 public function getValue() {
142 public function getDomain() {
143 return $this->domain
;
147 * Get the cookie path
151 public function getPath() {
156 * Get the expiry time of the cookie, or null if no expiry time is set
160 public function getExpiryTime() {
161 return $this->expires
;
165 * Check whether the cookie should only be sent over secure connections
169 public function isSecure() {
170 return $this->secure
;
174 * Check whether the cookie has expired
176 * Always returns false if the cookie is a session cookie (has no expiry time)
178 * @param int $now Timestamp to consider as "now"
181 public function isExpired($now = null) {
182 if ($now === null) $now = time();
183 if (is_int($this->expires
) && $this->expires
< $now) {
191 * Check whether the cookie is a session cookie (has no expiry time set)
195 public function isSessionCookie() {
196 return ($this->expires
=== null);
200 * Checks whether the cookie should be sent or not in a specific scenario
202 * @param string|Zend_Uri_Http $uri URI to check against (secure, domain, path)
203 * @param boolean $matchSessionCookies Whether to send session cookies
204 * @param int $now Override the current time when checking for expiry time
207 public function match($uri, $matchSessionCookies = true, $now = null) {
208 if (is_string($uri)) {
209 $uri = Zend_Uri_Http
::factory($uri);
212 // Make sure we have a valid Zend_Uri_Http object
213 if (! ($uri->valid() && ($uri->getScheme() == 'http' ||
$uri->getScheme() == 'https'))) {
214 require_once 'external/Zend/Http/Exception.php';
215 throw new Zend_Http_Exception('Passed URI is not a valid HTTP or HTTPS URI');
218 // Check that the cookie is secure (if required) and not expired
219 if ($this->secure
&& $uri->getScheme() != 'https') return false;
220 if ($this->isExpired($now)) return false;
221 if ($this->isSessionCookie() && ! $matchSessionCookies) return false;
223 // Validate domain and path
224 // Domain is validated using tail match, while path is validated using head match
225 $domain_preg = preg_quote($this->getDomain(), "/");
226 if (! preg_match("/{$domain_preg}$/", $uri->getHost())) return false;
227 $path_preg = preg_quote($this->getPath(), "/");
228 if (! preg_match("/^{$path_preg}/", $uri->getPath())) return false;
230 // If we didn't die until now, return true.
235 * Get the cookie as a string, suitable for sending as a "Cookie" header in an
240 public function __toString() {
241 return $this->name
. '=' . urlencode($this->value
) . ';';
245 * Generate a new Cookie object from a cookie string
246 * (for example the value of the Set-Cookie HTTP header)
248 * @param string $cookieStr
249 * @param Zend_Uri_Http|string $ref_uri Reference URI for default values (domain, path)
250 * @return Zend_Http_Cookie A new Zend_Http_Cookie object or false on failure.
252 public static function fromString($cookieStr, $ref_uri = null) {
253 // Set default values
254 if (is_string($ref_uri)) {
255 $ref_uri = Zend_Uri_Http
::factory($ref_uri);
264 $parts = explode(';', $cookieStr);
266 // If first part does not include '=', fail
267 if (strpos($parts[0], '=') === false) return false;
269 // Get the name and value of the cookie
270 list($name, $value) = explode('=', trim(array_shift($parts)), 2);
272 $value = urldecode(trim($value));
274 // Set default domain and path
275 if ($ref_uri instanceof Zend_Uri_Http
) {
276 $domain = $ref_uri->getHost();
277 $path = $ref_uri->getPath();
278 $path = substr($path, 0, strrpos($path, '/'));
281 // Set other cookie parameters
282 foreach ($parts as $part) {
284 if (strtolower($part) == 'secure') {
289 $keyValue = explode('=', $part, 2);
290 if (count($keyValue) == 2) {
291 list($k, $v) = $keyValue;
292 switch (strtolower($k)) {
294 $expires = strtotime($v);
309 return new Zend_Http_Cookie($name, $value, $domain, $expires, $path, $secure);