Home > Article > Backend Development > Analyze related operations of cookie and session functions in PHP's Yii framework_php skills
Sessions
Similar to requests and responses, sessions can be accessed by default through the session application component of the yiiwebSession instance.
Open and close Sessions
You can use the following code to open and close the session.
$session = Yii::$app->session; // 检查session是否开启 if ($session->isActive) ... // 开启session $session->open(); // 关闭session $session->close(); // 销毁session中所有已注册的数据 $session->destroy();
Calling the yiiwebSession::open() and yiiwebSession::close() methods multiple times will not cause an error, because the method will first check whether the session is open.
Access Session Data
To access the data stored in session, you can do the following:
$session = Yii::$app->session; // 获取session中的变量值,以下用法是相同的: $language = $session->get('language'); $language = $session['language']; $language = isset($_SESSION['language']) ? $_SESSION['language'] : null; // 设置一个session变量,以下用法是相同的: $session->set('language', 'en-US'); $session['language'] = 'en-US'; $_SESSION['language'] = 'en-US'; // 删除一个session变量,以下用法是相同的: $session->remove('language'); unset($session['language']); unset($_SESSION['language']); // 检查session变量是否已存在,以下用法是相同的: if ($session->has('language')) ... if (isset($session['language'])) ... if (isset($_SESSION['language'])) ... // 遍历所有session变量,以下用法是相同的: foreach ($session as $name => $value) ... foreach ($_SESSION as $name => $value) ...
When the session data is an array, the session component will restrict you from directly modifying the unit items in the data, for example:
$session = Yii::$app->session; // 如下代码不会生效 $session['captcha']['number'] = 5; $session['captcha']['lifetime'] = 3600; // 如下代码会生效: $session['captcha'] = [ 'number' => 5, 'lifetime' => 3600, ]; // 如下代码也会生效: echo $session['captcha']['lifetime'];
$session = Yii::$app->session; // 直接使用$_SESSION (确保Yii::$app->session->open() 已经调用) $_SESSION['captcha']['number'] = 5; $_SESSION['captcha']['lifetime'] = 3600; // 先获取session数据到一个数组,修改数组的值,然后保存数组到session中 $captcha = $session['captcha']; $captcha['number'] = 5; $captcha['lifetime'] = 3600; $session['captcha'] = $captcha; // 使用ArrayObject 数组对象代替数组 $session['captcha'] = new \ArrayObject; ... $session['captcha']['number'] = 5; $session['captcha']['lifetime'] = 3600; // 使用带通用前缀的键来存储数组 $session['captcha.number'] = 5; $session['captcha.lifetime'] = 3600;
Customized Session Storage
The yiiwebSession class stores session data as files on the server by default. Yii provides the following session classes to implement different session storage methods:
Note: If you access a session using a custom storage medium through $_SESSION, you need to ensure that the session has been opened using yiiwebSession::open(). This is because the custom session storage processor is registered in this method.
To learn how to configure and use these component classes, please refer to their API documentation. The following is an example showing how to configure yiiwebDbSession in the application configuration to use the data table as the session storage medium.
return [ 'components' => [ 'session' => [ 'class' => 'yii\web\DbSession', // 'db' => 'mydb', // 数据库连接的应用组件ID,默认为'db'. // 'sessionTable' => 'my_session', // session 数据表名,默认为'session'. ], ], ];
CREATE TABLE session ( id CHAR(40) NOT NULL PRIMARY KEY, expire INTEGER, data BLOB )
Flash data
Flash data is a special kind of session data. Once it is set in a request, it will only be valid in the next request, and then the data will be automatically deleted. It is often used to implement information that only needs to be displayed to the end user once, such as displaying confirmation information after the user submits a form.Session can be set or accessed through the session application component, for example:
$session = Yii::$app->session; // 请求 #1 // 设置一个名为"postDeleted" flash 信息 $session->setFlash('postDeleted', 'You have successfully deleted your post.'); // 请求 #2 // 显示名为"postDeleted" flash 信息 echo $session->getFlash('postDeleted'); // 请求 #3 // $result 为 false,因为flash信息已被自动删除 $result = $session->hasFlash('postDeleted');
When calling yiiwebSession::setFlash(), any existing data with the same name will be automatically overwritten. To append data to the existing flash with the same name, you can call yiiwebSession::addFlash() instead. For example:
$session = Yii::$app->session; // 请求 #1 // 在名称为"alerts"的flash信息增加数据 $session->addFlash('alerts', 'You have successfully deleted your post.'); $session->addFlash('alerts', 'You have successfully added a new friend.'); $session->addFlash('alerts', 'You are promoted.'); // 请求 #2 // $alerts 为名为'alerts'的flash信息,为数组格式 $alerts = $session->getFlash('alerts');
Cookies
Read Cookies
The currently requested cookie information can be obtained through the following code:
// 从 "request"组件中获取cookie集合(yii\web\CookieCollection) $cookies = Yii::$app->request->cookies; // 获取名为 "language" cookie 的值,如果不存在,返回默认值"en" $language = $cookies->getValue('language', 'en'); // 另一种方式获取名为 "language" cookie 的值 if (($cookie = $cookies->get('language')) !== null) { $language = $cookie->value; } // 可将 $cookies当作数组使用 if (isset($cookies['language'])) { $language = $cookies['language']->value; } // 判断是否存在名为"language" 的 cookie if ($cookies->has('language')) ... if (isset($cookies['language'])) ...
Send Cookies
You can send cookies to end users using the following code: You can use the following code to send cookies to end users:
// 从"response"组件中获取cookie 集合(yii\web\CookieCollection) $cookies = Yii::$app->response->cookies; // 在要发送的响应中添加一个新的cookie $cookies->add(new \yii\web\Cookie([ 'name' => 'language', 'value' => 'zh-CN', ])); // 删除一个cookie $cookies->remove('language'); // 等同于以下删除代码 unset($cookies['language']);
除了上述例子定义的 yii\web\Cookie::name 和 yii\web\Cookie::value 属性 yii\web\Cookie 类也定义了其他属性来实现cookie的各种信息,如 yii\web\Cookie::domain, yii\web\Cookie::expire 可配置这些属性到cookie中并添加到响应的cookie集合中。
注意: 为安全起见yii\web\Cookie::httpOnly 被设置为true,这可减少客户端脚本访问受保护cookie(如果浏览器支持)的风险, 更多详情可阅读 httpOnly wiki article for more details.
Cookie验证
在上两节中,当通过request 和 response 组件读取和发送cookie时,你会喜欢扩展的cookie验证的保障安全功能,它能 使cookie不被客户端修改。该功能通过给每个cookie签发一个哈希字符串来告知服务端cookie是否在客户端被修改, 如果被修改,通过request组件的yii\web\Request::cookiescookie集合访问不到该cookie。
注意: Cookie验证只保护cookie值被修改,如果一个cookie验证失败,仍然可以通过$_COOKIE来访问该cookie, 因为这是第三方库对未通过cookie验证自定义的操作方式。
Cookie验证默认启用,可以设置yii\web\Request::enableCookieValidation属性为false来禁用它,尽管如此,我们强烈建议启用它。
注意: 直接通过$_COOKIE 和 setcookie() 读取和发送的Cookie不会被验证。
当使用cookie验证,必须指定yii\web\Request::cookieValidationKey,它是用来生成s上述的哈希值, 可通过在应用配置中配置request 组件。
return [ 'components' => [ 'request' => [ 'cookieValidationKey' => 'fill in a secret key here', ], ], ];
补充: yii\web\Request::cookieValidationKey 对你的应用安全很重要, 应只被你信任的人知晓,请不要将它放入版本控制中。