/src/YurunHttp/Cookie/CookieManager.php
https://github.com/Yurunsoft/YurunHttp · PHP · 317 lines · 190 code · 19 blank · 108 comment · 25 complexity · c76395ef334427e0715dda48981dcbb4 MD5 · raw file
- <?php
- namespace Yurun\Util\YurunHttp\Cookie;
- use Yurun\Util\YurunHttp\Http\Psr7\Uri;
- class CookieManager
- {
- /**
- * Cookie 列表
- *
- * @var \Yurun\Util\YurunHttp\Cookie\CookieItem[]
- */
- protected $cookieList;
- /**
- * 关联集合
- *
- * @var array
- */
- protected $relationMap;
- /**
- * 自增ID
- * 会比当前列表长度+1
- *
- * @var int
- */
- protected $autoIncrementId;
- /**
- * __construct
- * @param array $cookieList
- */
- public function __construct($cookieList = [])
- {
- $this->setCookieList($cookieList);
- }
- /**
- * 设置 Cookie 列表
- *
- * @param array $cookieList
- * @return void
- */
- public function setCookieList($cookieList)
- {
- $this->autoIncrementId = 1;
- $this->cookieList = [];
- $this->relationMap = [];
- foreach($cookieList as $item)
- {
- $item = CookieItem::newInstance($item);
- $this->insertCookie($item);
- }
- }
- /**
- * 获取 Cookie 列表
- *
- * @return array
- */
- public function getCookieList()
- {
- return $this->cookieList;
- }
- /**
- * 添加 Set-Cookie
- *
- * @param string $setCookie
- * @return \Yurun\Util\YurunHttp\Cookie\CookieItem
- */
- public function addSetCookie($setCookie)
- {
- $item = CookieItem::fromSetCookie($setCookie);
- if(($id = $this->findCookie($item)) > 0)
- {
- $this->updateCookie($id, $item);
- }
- else
- {
- $this->insertCookie($item);
- }
- return $item;
- }
- /**
- * 设置 Cookie
- *
- * @param string $name
- * @param string $value
- * @param integer $expires
- * @param string $path
- * @param string $domain
- * @param boolean $secure
- * @param boolean $httpOnly
- * @return \Yurun\Util\YurunHttp\Cookie\CookieItem
- */
- public function setCookie($name, $value, $expires = 0, $path = '/', $domain = '', $secure = false, $httpOnly = false)
- {
- $item = new CookieItem($name, $value, $expires, $path, $domain, $secure, $httpOnly);
- if(($id = $this->findCookie($item)) > 0)
- {
- $this->updateCookie($id, $item);
- }
- else
- {
- $this->insertCookie($item);
- }
- return $item;
- }
- /**
- * Cookie 数量
- *
- * @return int
- */
- public function count()
- {
- return count($this->cookieList);
- }
- /**
- * 获取请求所需 Cookie 关联数组
- *
- * @param \Psr\Http\Message\UriInterface $uri
- * @return array
- */
- public function getRequestCookies($uri)
- {
- if(defined('SWOOLE_VERSION') && SWOOLE_VERSION < 4.4)
- {
- // Fix bug: https://github.com/swoole/swoole-src/pull/2644
- $result = json_decode('[]', true);
- }
- else
- {
- $result = [];
- }
- $uriDomain = Uri::getDomain($uri);
- $uriPath = $uri->getPath();
- $cookieList = &$this->cookieList;
- foreach($this->relationMap as $relationDomain => $list1)
- {
- if('' === $relationDomain || $this->checkDomain($uriDomain, $relationDomain))
- {
- foreach($list1 as $path => $idList)
- {
- if($this->checkPath($uriPath, $path))
- {
- foreach($idList as $id)
- {
- $cookieItem = $cookieList[$id];
- if((0 === $cookieItem->expires || $cookieItem->expires > time()) && (!$cookieItem->secure || 'https' === $uri->getScheme() || 'wss' === $uri->getScheme()) )
- {
- $result[$cookieItem->name] = $cookieItem->value;
- }
- }
- }
- }
- }
- }
- return $result;
- }
- /**
- * 获取请求所需 Cookie 关联数组
- *
- * @param \Psr\Http\Message\UriInterface $uri
- * @return string
- */
- public function getRequestCookieString($uri)
- {
- $content = '';
- foreach($this->getRequestCookies($uri) as $name => $value)
- {
- $content .= "{$name}={$value}; ";
- }
- return $content;
- }
- /**
- * 获取 CookieItem
- *
- * @param string $name
- * @param string $domain
- * @param string $path
- * @return \Yurun\Util\YurunHttp\Cookie\CookieItem
- */
- public function getCookieItem($name, $domain = '', $path = '/')
- {
- if(isset($this->relationMap[$domain][$path][$name]))
- {
- $id = $this->relationMap[$domain][$path][$name];
- return $this->cookieList[$id];
- }
- return null;
- }
- /**
- * 检查 uri 域名和 cookie 域名
- *
- * @param string $uriDomain
- * @param string $cookieDomain
- * @return boolean
- */
- private function checkDomain($uriDomain, $cookieDomain)
- {
- return ($uriDomain === $cookieDomain)
- || (isset($cookieDomain[0]) && '.' === $cookieDomain[0] && substr($uriDomain, -strlen($cookieDomain) - 1) === '.' . $cookieDomain)
- ;
- }
- /**
- * 检查 uri 路径和 cookie 路径
- *
- * @param string $uriDomain
- * @param string $cookieDomain
- * @return boolean
- */
- private function checkPath($uriPath, $cookiePath)
- {
- $uriPath = rtrim($uriPath, '/');
- $cookiePath = rtrim($cookiePath, '/');
- if($uriPath === $cookiePath)
- {
- return true;
- }
- $uriPathDSCount = substr_count($uriPath, '/');
- $cookiePathDSCount = substr_count($cookiePath, '/');
- if('' === $uriPath)
- {
- $uriPath = '/';
- }
- if('' === $cookiePath)
- {
- $cookiePath = '/';
- }
- if($uriPathDSCount > $cookiePathDSCount)
- {
- if(version_compare(PHP_VERSION, '7.0', '>='))
- {
- $path = dirname($uriPath, $uriPathDSCount - $cookiePathDSCount);
- }
- else
- {
- $count = $uriPathDSCount - $cookiePathDSCount;
- $path = $uriPath;
- while($count--)
- {
- $path = dirname($path);
- }
- }
- if('\\' === DIRECTORY_SEPARATOR && false !== strpos($path, DIRECTORY_SEPARATOR))
- {
- $path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
- }
- return $path === $cookiePath;
- }
- else
- {
- return false;
- }
- }
- /**
- * 更新 Cookie 数据
- *
- * @param int $id
- * @param \Yurun\Util\YurunHttp\Cookie\CookieItem $item
- * @return int
- */
- private function updateCookie($id, $item)
- {
- if(isset($this->cookieList[$id]))
- {
- $object = $this->cookieList[$id];
- }
- foreach($item as $k => $v)
- {
- $object->$k = $v;
- }
- }
- /**
- * 插入 Cookie 数据
- *
- * @param \Yurun\Util\YurunHttp\Cookie\CookieItem $item
- * @return int
- */
- private function insertCookie($item)
- {
- $id = $this->autoIncrementId++;
- $this->cookieList[$id] = $item;
- $this->relationMap[$item->domain][$item->path][$item->name] = $id;
- return $id;
- }
- /**
- * 查找 Cookie ID
- *
- * @param \Yurun\Util\YurunHttp\Cookie\CookieItem $item
- * @return int|null
- */
- private function findCookie($item)
- {
- if(isset($this->relationMap[$item->domain][$item->path][$item->name]))
- {
- return $this->relationMap[$item->domain][$item->path][$item->name];
- }
- else
- {
- return null;
- }
- }
- }