Случайно заметил такой нюанс при использования хранилища сессий в кеше ( в моем случае memcached ) Yii2 создает одновременно ее же и в массиве $_SESSION, хотя по логике не должен его использовать если в настройках указывается другое хранилище
Конфиг: ( пример - http://www.yiiframework.com/doc-2.0/yii-web-cachesession.html )
'cache' => [
'class' => 'yii\caching\MemCache',
'useMemcached' => TRUE,
'servers' => [
[
'host' => '******/.system/memcache/socket',
'port' => 11211,
'weight' => 64,
],
]
],
'session' => [
'class' => 'yii\web\CacheSession',
// 'cache' => 'cache',
],
Создание сессии:
$session = Yii::$app->session;
$userDataStorage = [
'id' => $this->id,
'name' => $this->name,
'settings' => json_decode($this->settings),
];
$session->set('user_data' , $userDataStorage);
Проверяем:
echo 'Yii session -> ';
var_dump(Yii::$app->session->get('user_data') );
echo '-------------
';
echo 'Php session -> ';
var_dump($_SESSION);
echo '-------------
';
var_dump(ini_get('session.save_path'));
Видим:
Yii session -> array(4) {
["id"]=>
int(1)
["name"]=>
string(5) "admin"
["settings"]=>
NULL
}
-------------
Php session -> array(3) {
["__flash"]=>
array(0) {
}
["__id"]=>
int(1)
["user_data"]=>
array(4) {
["id"]=>
int(1)
["name"]=>
string(5) "admin"
["settings"]=>
NULL
}
}
-------------
string(24) "****/.system/tmp"
Собственно это баг или... ? В чем тогда смысль настройки хранения сессий в кеше если он дублируется со стандартным ? Или я что-то делаю не так?
СОРРИ не доглядел. https://github.com/yiisoft/yii2/blob/master/framework/web/Session.php методом registerSessionHandler() устанавливает session_set_save_handler а класс "CacheSession" реализует методы которые будут хранить сессию в кеше определенном в настройках, т.о. $_SESSION хранится уже не в файле папки tmp (как по умолчанию) а в memcached. Вопрос закрыт.
Ответ
Возможно будет кому-то полезно, тогда начну сначала.
Как настроить кеширование Yii2 для работы с memcache или memcached ( в чем отличия я думаю тут описывать нет смысла, в нете масса инфы по этому поводу ), постараюсь кратко изложить саму суть. Итак, для начала
заходим в файл конфигурации проэкта и добавляем настройки кеширования и подключения к серверу
'components' => [
...
'cache' => [
'class' => 'yii\caching\MemCache',
'useMemcached' => TRUE,
'servers' => [
[
'host' => 'localhost',
'port' => 11211,
'weight' => 64,
],
]
],
...
]
Параметр 'useMemcached' ( класс MemCache расположен в директории yii2/caching/MemCache.php ( наследуется от компонента Cache /yii2/caching/Cache.php ) и по умолчанию FALSE, т.е. юзает memcache ) указывает на то что будет использоватся memcache или memcached,
для использования memcached ставим в конфиге 'useMemcached' => TRUE
Далее если все верно настроено прописано можем юзать кеш
\Yii::$app->cache->set('key', 'value');
\Yii::$app->cache->get('key');
//или можем кешировать запросы в БД
$db = Yii::$app->db;
$result = $db->cache(function ($db) {
return $db->createCommand('SELECT * FROM tablename LIMIT 0,1000')->queryAll();
});
// и т.д.
****
Подробнее в доке http://www.yiiframework.com/doc-2.0/guide-caching-data.html
Тут сразу нужно оговорится если вы захотите проверить работу Yii2 memcached напрямую, т.е.
в Yii2
\Yii::$app->cache->set('mykey', 'value');
в произвольном файле
$m = new Memcached();
$m->addServer('localhost', 11211);
var_dump($m->get('mykey'));
У вас ничего не получится т.к. компонент Cache Yii ( /yii2/caching/Cache.php ) методом buildKey так сказать "нормализует" ключи ( описание метода есть в классе ), но можно для теста сделать так
в Yii2
$cache = Yii::$app->cache;
$keyStr = 'cache_test';
$key = $cache->buildKey($keyStr);
$cache->set($keyStr, 'This is mem test!');
$get = $cache->get($keyStr);
var_dump($get , $key); // дампим результат из кеша и сгенерированный ключ ( копируем его )
в произвольном файле
$m = new Memcached();
$m->addServer('localhost', 11211);
$result = $m->get('242c9254b0a4b5ea5c7f0e000f668408'); // Вставляем полученый ключ
var_dump(unserialize($result));
Далее собственно ближе к сути, мы хотим хранить сесии в нашем мемкеше, для этого идем обратно в конфиг и добавляем после настроек кеша следующее
'session' => [
'class' => 'yii\web\CacheSession',
//'cache' => 'cache',
],
Теперь для работы с сессией будет заюзан класс CacheSession ( /yii2/web/CacheSession.php наследуется от Session /yii2/web/Session.php ) и можно создать нашу сессию
\Yii::$app->session->set('Mysession', 'Mem session');
И собственно тут у меня возник некий конфуз, ибо
\Yii::$app->session->get('Mysession'); // Вернет нам значение сессии
$_SESSION // К моему удивлению так же содержал в себе эту сессию
Но на самом деле ничего страшного здесь нет, $_SESSION уже не хранится на сервере в папке tmp как по умолчанию, теперь $_SESSION хранится в мемкешед.
Все дело в том что класс CacheSession переопределяет некоторые методы
класса Session ( в подробности работы вдаватся не буду, можно впринципе пройтись по этим файлам и посмотреть ) в т.ч. getUseCustomStorage(), так же класс Session имеет метод registerSessionHandler()
который вызывается при откритии сессии, метод open(), в Session и вызывает в этом случаи getUseCustomStorage() который был переопределен, собственно после этого и происходит магия переноса $_SESSION в мемкешед, функция session_set_save_handler() ( http://php.net/manual/ru/function.session-set-save-handler.php ) переопределит методы работы с сессией на пользовательские.
После этого если мы сделаем так $_SESSION['mysession'] = 'value' ( так же как и в методе Session set() ), после открытия сесиии медодом Session open(), сессия будет хранится в нашем кеше.
Надеюсь мои изысканя будут кому-то полезными
Комментариев нет:
Отправить комментарий