1: <?php
2: /**
3: * This file contains classes implementing security manager feature.
4: *
5: * @author Qiang Xue <qiang.xue@gmail.com>
6: * @link http://www.yiiframework.com/
7: * @copyright 2008-2013 Yii Software LLC
8: * @license http://www.yiiframework.com/license/
9: */
10:
11: /**
12: * CStatePersister implements a file-based persistent data storage.
13: *
14: * It can be used to keep data available through multiple requests and sessions.
15: *
16: * By default, CStatePersister stores data in a file named 'state.bin' that is located
17: * under the application {@link CApplication::getRuntimePath runtime path}.
18: * You may change the location by setting the {@link stateFile} property.
19: *
20: * To retrieve the data from CStatePersister, call {@link load()}. To save the data,
21: * call {@link save()}.
22: *
23: * Comparison among state persister, session and cache is as follows:
24: * <ul>
25: * <li>session: data persisting within a single user session.</li>
26: * <li>state persister: data persisting through all requests/sessions (e.g. hit counter).</li>
27: * <li>cache: volatile and fast storage. It may be used as storage medium for session or state persister.</li>
28: * </ul>
29: *
30: * Since server resource is often limited, be cautious if you plan to use CStatePersister
31: * to store large amount of data. You should also consider using database-based persister
32: * to improve the throughput.
33: *
34: * CStatePersister is a core application component used to store global application state.
35: * It may be accessed via {@link CApplication::getStatePersister()}.
36: * page state persistent method based on cache.
37: *
38: * @author Qiang Xue <qiang.xue@gmail.com>
39: * @package system.base
40: * @since 1.0
41: */
42: class CStatePersister extends CApplicationComponent implements IStatePersister
43: {
44: /**
45: * @var string the file path storing the state data. Make sure the directory containing
46: * the file exists and is writable by the Web server process. If using relative path, also
47: * make sure the path is correct.
48: */
49: public $stateFile;
50: /**
51: * @var string the ID of the cache application component that is used to cache the state values.
52: * Defaults to 'cache' which refers to the primary cache application component.
53: * Set this property to false if you want to disable caching state values.
54: */
55: public $cacheID='cache';
56:
57: /**
58: * Initializes the component.
59: * This method overrides the parent implementation by making sure {@link stateFile}
60: * contains valid value.
61: */
62: public function init()
63: {
64: parent::init();
65: if($this->stateFile===null)
66: $this->stateFile=Yii::app()->getRuntimePath().DIRECTORY_SEPARATOR.'state.bin';
67: $dir=dirname($this->stateFile);
68: if(!is_dir($dir) || !is_writable($dir))
69: throw new CException(Yii::t('yii','Unable to create application state file "{file}". Make sure the directory containing the file exists and is writable by the Web server process.',
70: array('{file}'=>$this->stateFile)));
71: }
72:
73: /**
74: * Loads state data from persistent storage.
75: * @return mixed state data. Null if no state data available.
76: */
77: public function load()
78: {
79: $stateFile=$this->stateFile;
80: if($this->cacheID!==false && ($cache=Yii::app()->getComponent($this->cacheID))!==null)
81: {
82: $cacheKey='Yii.CStatePersister.'.$stateFile;
83: if(($value=$cache->get($cacheKey))!==false)
84: return unserialize($value);
85: elseif(($content=@file_get_contents($stateFile))!==false)
86: {
87: $cache->set($cacheKey,$content,0,new CFileCacheDependency($stateFile));
88: return unserialize($content);
89: }
90: else
91: return null;
92: }
93: elseif(($content=@file_get_contents($stateFile))!==false)
94: return unserialize($content);
95: else
96: return null;
97: }
98:
99: /**
100: * Saves application state in persistent storage.
101: * @param mixed $state state data (must be serializable).
102: */
103: public function save($state)
104: {
105: file_put_contents($this->stateFile,serialize($state),LOCK_EX);
106: }
107: }
108: