Cookie.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\BrowserKit;
  11. /**
  12. * Cookie represents an HTTP cookie.
  13. *
  14. * @author Fabien Potencier <fabien@symfony.com>
  15. *
  16. * @api
  17. */
  18. class Cookie
  19. {
  20. const DATE_FORMAT = 'D, d-M-Y H:i:s T';
  21. protected $name;
  22. protected $value;
  23. protected $expires;
  24. protected $path;
  25. protected $domain;
  26. protected $secure;
  27. protected $httponly;
  28. protected $rawValue;
  29. /**
  30. * Sets a cookie.
  31. *
  32. * @param string $name The cookie name
  33. * @param string $value The value of the cookie
  34. * @param string $expires The time the cookie expires
  35. * @param string $path The path on the server in which the cookie will be available on
  36. * @param string $domain The domain that the cookie is available
  37. * @param Boolean $secure Indicates that the cookie should only be transmitted over a secure HTTPS connection from the client
  38. * @param Boolean $httponly The cookie httponly flag
  39. * @param Boolean $encodedValue Whether the value is encoded or not
  40. *
  41. * @api
  42. */
  43. public function __construct($name, $value, $expires = null, $path = '/', $domain = '', $secure = false, $httponly = true, $encodedValue = false)
  44. {
  45. if ($encodedValue) {
  46. $this->value = urldecode($value);
  47. $this->rawValue = $value;
  48. } else {
  49. $this->value = $value;
  50. $this->rawValue = urlencode($value);
  51. }
  52. $this->name = $name;
  53. $this->expires = null === $expires ? null : (integer) $expires;
  54. $this->path = empty($path) ? '/' : $path;
  55. $this->domain = $domain;
  56. $this->secure = (Boolean) $secure;
  57. $this->httponly = (Boolean) $httponly;
  58. }
  59. /**
  60. * Returns the HTTP representation of the Cookie.
  61. *
  62. * @return string The HTTP representation of the Cookie
  63. *
  64. * @api
  65. */
  66. public function __toString()
  67. {
  68. $cookie = sprintf('%s=%s', $this->name, $this->rawValue);
  69. if (null !== $this->expires) {
  70. $cookie .= '; expires='.substr(\DateTime::createFromFormat('U', $this->expires, new \DateTimeZone('UTC'))->format(static::DATE_FORMAT), 0, -5);
  71. }
  72. if ('' !== $this->domain) {
  73. $cookie .= '; domain='.$this->domain;
  74. }
  75. if ('/' !== $this->path) {
  76. $cookie .= '; path='.$this->path;
  77. }
  78. if ($this->secure) {
  79. $cookie .= '; secure';
  80. }
  81. if ($this->httponly) {
  82. $cookie .= '; httponly';
  83. }
  84. return $cookie;
  85. }
  86. /**
  87. * Creates a Cookie instance from a Set-Cookie header value.
  88. *
  89. * @param string $cookie A Set-Cookie header value
  90. * @param string $url The base URL
  91. *
  92. * @return Cookie A Cookie instance
  93. *
  94. * @api
  95. */
  96. static public function fromString($cookie, $url = null)
  97. {
  98. $parts = explode(';', $cookie);
  99. if (false === strpos($parts[0], '=')) {
  100. throw new \InvalidArgumentException('The cookie string "%s" is not valid.');
  101. }
  102. list($name, $value) = explode('=', array_shift($parts), 2);
  103. $values = array(
  104. 'name' => trim($name),
  105. 'value' => trim($value),
  106. 'expires' => null,
  107. 'path' => '/',
  108. 'domain' => '',
  109. 'secure' => false,
  110. 'httponly' => false,
  111. 'passedRawValue' => true,
  112. );
  113. if (null !== $url) {
  114. if ((false === $parts = parse_url($url)) || !isset($parts['host']) || !isset($parts['path'])) {
  115. throw new \InvalidArgumentException(sprintf('The URL "%s" is not valid.', $url));
  116. }
  117. $values['domain'] = $parts['host'];
  118. $values['path'] = substr($parts['path'], 0, strrpos($parts['path'], '/'));
  119. }
  120. foreach ($parts as $part) {
  121. $part = trim($part);
  122. if ('secure' === strtolower($part)) {
  123. $values['secure'] = true;
  124. continue;
  125. }
  126. if ('httponly' === strtolower($part)) {
  127. $values['httponly'] = true;
  128. continue;
  129. }
  130. if (2 === count($elements = explode('=', $part, 2))) {
  131. if ('expires' === $elements[0]) {
  132. if (false === $date = \DateTime::createFromFormat(static::DATE_FORMAT, $elements[1], new \DateTimeZone('UTC'))) {
  133. throw new \InvalidArgumentException(sprintf('The expires part of cookie is not valid (%s).', $elements[1]));
  134. }
  135. $elements[1] = $date->getTimestamp();
  136. }
  137. $values[strtolower($elements[0])] = $elements[1];
  138. }
  139. }
  140. return new static(
  141. $values['name'],
  142. $values['value'],
  143. $values['expires'],
  144. $values['path'],
  145. $values['domain'],
  146. $values['secure'],
  147. $values['httponly'],
  148. $values['passedRawValue']
  149. );
  150. }
  151. /**
  152. * Gets the name of the cookie.
  153. *
  154. * @return string The cookie name
  155. *
  156. * @api
  157. */
  158. public function getName()
  159. {
  160. return $this->name;
  161. }
  162. /**
  163. * Gets the value of the cookie.
  164. *
  165. * @return string The cookie value
  166. *
  167. * @api
  168. */
  169. public function getValue()
  170. {
  171. return $this->value;
  172. }
  173. /**
  174. * Gets the raw value of the cookie.
  175. *
  176. * @return string The cookie value
  177. *
  178. * @api
  179. */
  180. public function getRawValue()
  181. {
  182. return $this->rawValue;
  183. }
  184. /**
  185. * Gets the expires time of the cookie.
  186. *
  187. * @return string The cookie expires time
  188. *
  189. * @api
  190. */
  191. public function getExpiresTime()
  192. {
  193. return $this->expires;
  194. }
  195. /**
  196. * Gets the path of the cookie.
  197. *
  198. * @return string The cookie path
  199. *
  200. * @api
  201. */
  202. public function getPath()
  203. {
  204. return $this->path;
  205. }
  206. /**
  207. * Gets the domain of the cookie.
  208. *
  209. * @return string The cookie domain
  210. *
  211. * @api
  212. */
  213. public function getDomain()
  214. {
  215. return $this->domain;
  216. }
  217. /**
  218. * Returns the secure flag of the cookie.
  219. *
  220. * @return Boolean The cookie secure flag
  221. *
  222. * @api
  223. */
  224. public function isSecure()
  225. {
  226. return $this->secure;
  227. }
  228. /**
  229. * Returns the httponly flag of the cookie.
  230. *
  231. * @return Boolean The cookie httponly flag
  232. *
  233. * @api
  234. */
  235. public function isHttpOnly()
  236. {
  237. return $this->httponly;
  238. }
  239. /**
  240. * Returns true if the cookie has expired.
  241. *
  242. * @return Boolean true if the cookie has expired, false otherwise
  243. *
  244. * @api
  245. */
  246. public function isExpired()
  247. {
  248. return (null !== $this->expires) && $this->expires < time();
  249. }
  250. }