Страницы

Поиск по вопросам

пятница, 13 марта 2020 г.

Yii2 CacheSession создает сессию в $_SESSION и в кеше одновременно

#php #yii2


Случайно заметил такой нюанс при использования хранилища сессий в кеше ( в моем случае
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. Вопрос закрыт.


Ответы

Ответ 1



Возможно будет кому-то полезно, тогда начну сначала. Как настроить кеширование 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(), сессия будет хранится в нашем кеше. Надеюсь мои изысканя будут кому-то полезными

Комментариев нет:

Отправить комментарий