# Sessions(會話)
HTTP是一個無狀態協議,但幾乎每個應用程序都需要在請求之間存儲狀態。 購物車的內容 正是為了會話(或關系)是。 這章主要學會以下幾點
* 怎樣使用Sessions
* 怎樣避免命名沖突
* 設置Sessions過期時間
* 怎樣安全抵御漏洞
使用會話時,每個訪問網頁的用戶都會收到一個唯一的會話ID標識符,該標識符由Cookie傳遞。 它用作會話數據的鍵。 它與存儲在瀏覽器端的Cookie不同,會話數據存儲在服務器端。
# Sections(部分)
在純PHP里會話數據存儲為一個數組,可通過全局變量$ _SESSION訪問。 問題是,應用程序通常由幾個獨立的部分組成,如果每個部分都可以使用相同的數組,你必須及早解決命名沖突。
Nette框架通過將會話空間劃分為段(Nette \ Http \ SessionSection對象)來解決這個問題。 因此,一個程序的每個部分都使用它自己的部分具有唯一的名稱,并且不會發生沖突。
讓我們從會話管理器開始,這是Nette \ Http \ Session類的一個對象。 我們可以直接從控制器訪問此服務:
~~~
// $this stands for presenter
$session = $this->getSession();
$mySection = $this->getSession('mySection');
~~~
或者我們可以要求在我們的構造函數中使用依賴注入:
~~~
use Nette;
class MyService {
/** @var Nette\Http\Session */
private $session;
/** @var Nette\Http\SessionSection */
private $sessionSection;
public function __construct(Nette\Http\Session $session)
{
$this->session = $session;
// get section by identifier 'mySection':
$this->sessionSection = $session->getSection('mySection');
}
}
~~~
我們可以使用一個方法hasSection('myCounter')來檢查變量的存在。
沒有必要啟動或關閉該會話,它是由框架本身自動完成。 但是我們可以通過調用$ session-> start()手動啟動它。 如果我們多次調用start()方法,沒有什么發生,它將沒有效果。 您還可以在配置中修改此行為。
然后,使用該部分非常簡單:
~~~
// variable writing
$section->userName = 'franta'; // or $section['userName'] = 'franta';
// variable reading
echo $section->userName; // or echo $section['userName'];
// variable cancellation
unset($section->userName); // unset($section['userName']);
~~~
可以使用foreach循環從section獲取所有變量:
~~~
foreach ($section as $key => $val) {
echo "$key = $val";
}
~~~
## 示例:訪問計數器
我們將從訪問計數器的示例開始,其中顯示用戶顯示頁面的次數。
~~~
$section = $container->getService('session')->getSection('myCounter');
$section->count++; // increment counter by one
echo "You displayed this page $section->count ×";
~~~
訪問不存在的變量不會生成錯誤(變量具有NULL值)。 在某些情況下,這可能是不希望的行為,這就是為什么有可能改變它:
~~~
$section->warnOnUndefined = TRUE;
~~~
## 如何設置過期時間
非常有用的功能是為每個部分或變量設置自己的過期時間的可能性。 所以我們可以讓用戶登錄,但仍記得購物車的內容。
~~~
// section will expire after 2 minutes
$section->setExpiration('2 minutes');
// variable $section->a will expire after 10 seconds
$section->setExpiration(10, 'a');
~~~
除了相對時間(以秒為單位),可以使用UNIX時間戳或文本形式。 有趣的是值為0,它設置到用戶關閉瀏覽器時的到期時間:
~~~
// variable $section->password will expire when a user closes a browser
$section->setExpiration(0, 'password');
~~~
請記住,整個會話的過期時間(請參閱會話配置)必須等于或大于為單獨的段或變量設置的時間。
可以通過調用remove Expiration()方法來取消先前設置的到期。 立即取消整個段由remove()方法處理。
## 會話配置
會話的配置必須在使用之前完成。 最好的地方是config.neon。
要配置什么? 過期時間。 如果未進行此設置,則每次會話變量將在瀏覽器窗口關閉時過期。 在窗口關閉之后存儲會話對于例如長時間用戶登錄是有用的。
~~~
session:
expiration: 14 days
~~~
您還可以配置會話自動啟動。
~~~
session:
autoStart: true # 'smart' is default value
~~~
如果您使用共享主機,則適合使用自定義目錄來存儲具有會話關系的文件:
~~~
session:
savePath: "%tempDir%/sessions"
~~~
在這種情況下,%tempDir%將替換為您在bootstrap.php中的$ configurator-> setTempDirectory()中設置的值。
如果你想擴展子域的會話(或認證)的有效性,讓我們設置另一個cookie參數:
~~~
// sets cookie validity for all subdomains
$session->setCookieParameters('/', '.example.com');
session:
cookiePath: '/'
cookieDomain: '.example.com'
~~~
## 安全第一
服務器假定它與同一用戶通信,只要請求包含相同的會話ID。 安全機制的任務是確保這種行為真正有效,并且不可能替換或竊取標識符。
這就是為什么Nette框架正確配置PHP指令只在cookie中傳輸會話ID,以避免從JavaScript訪問和忽略URL中的標識符。 此外,在關鍵時刻,例如用戶登錄,它生成一個新的會話ID。
函數ini_set用于配置PHP,但不幸的是,它的使用是禁止在某些網絡托管服務。 如果是這樣,請嘗試請您的托管提供商為您允許此功能,或至少正確配置其服務器。
## 已知限制
在Chrome瀏覽器的“系統”部分中,Chrome瀏覽器關閉時繼續運行后臺應用,此選項默認為啟用。 它導致具有設置過期的cookie關閉瀏覽器,cookie仍然存在。 截至到期0,當關閉瀏覽器時不會被刪除。
小章總結:
這章主要教大家學會用session(),學會PHP都明白什么是會話了吧。
在這個框架怎樣使用它這個會話呢?!
- Nette簡介
- 快速開始
- 入門
- 主頁
- 顯示文章詳細頁
- 文章評論
- 創建和編輯帖子
- 權限驗證
- 程序員指南
- MVC應用程序和控制器
- URL路由
- Tracy - PHP調試器
- 調試器擴展
- 增強PHP語言
- HTTP請求和響應
- 數據庫
- 數據庫:ActiveRow
- 數據庫和表
- Sessions
- 用戶授權和權限
- 配置
- 依賴注入
- 獲取依賴關系
- DI容器擴展
- 組件
- 字符串處理
- 數組處理
- HTML元素
- 使用URL
- 表單
- 驗證器
- 模板
- AJAX & Snippets
- 發送電子郵件
- 圖像操作
- 緩存
- 本土化
- Nette Tester - 單元測試
- 與Travis CI的持續集成
- 分頁
- 自動加載
- 文件搜索:Finder
- 原子操作