Kohana Запросы к БД после авторизации.

php_coder

Новичок
После авторизации через Auth (ORM) любой переход по ссылке внутри сайта порождает запрос к БД.
(Код, выводимый профайлером Коханы):
SELECT `user`.`id` AS `id`, `user`.`email` AS `email`, `user`.`username` AS `username`, `user`.`password` AS `password`, `user`.`logins` AS `logins`, `user`.`last_login` AS `last_login` FROM `users` AS `user` WHERE `user`.`id` = '2' LIMIT 1 (1).
Собсно вопросы:
Зачем он нужен?
Какая полседовательность вызовов методов его порождает?
Как его отключить?

Код:
<?php defined('SYSPATH') or die('No direct script access.');
//Пользовательский контроллер подготовительных действий.
abstract class Controller_Prepare extends Controller_Template {
        public $template = 'Base';//основной (главный) шаблон по умолчанию
        protected $session;
        protected $auth;//Экземпляр объекта Auth.
        protected $user;//Текущий пользователь.
       
        public function before()
        {
            parent::before();
           
            View::set_global('bodyClass', 'index');
            View::set_global('title', 'Cool site');
            View::set_global('description', 'Cool site');
            View::set_global('navActive', array('', '', '', '', ''));
           
            $this->auth = Auth::instance();//Получаем экземпляр объекта Auth.
            //Получаем текущего пользователя из сессии (если он залогинился).
            $this->user = $this->auth->get_user();
           
            //$this->session = Session::instance();
            //echo $this->user->get('username');
            echo View::factory('profiler/stats');
           
            $username = '';
            if($this->user)
            $username = $this->user->get('username');
            View::set_global('username', $username);
           
            //View::set_global('username', '');
               
            $this->template->content = '';
            $this->template->styles = ['public/css/style'];
            $this->template->scripts = [];
        }
}
Код:
<?php defined('SYSPATH') OR die('No direct access allowed.');

class Controller_Auth extends Controller_Common
{
    //Создание пользователя.
    private function userCreate()
    {
        $authTpl = View::factory('auth/create')
            ->bind('errors', $errors)
            ->bind('message', $message);
           
        if (HTTP_Request::POST == $this->request->method())
        {     
            try
            {
                // Создать юзера, используя данные формы.
                $user = ORM::factory('user')->create_user($this->request->post(), array(
                    'username',
                    'password',
                    'email'       
                ));
               
                // Предоставить юзеру логин роль.
                $user->add('roles', ORM::factory('role', array('name' => 'login')));
               
                // Сбросить значения формы.
                $_POST = array();
               
                // Установка "успешного" сообщения.
                $message = "Пользователь '{$user->username}' добавлен в БД";
            }
            catch (ORM_Validation_Exception $e)
            { 
                // Установка "неудачного" сообщения.
                $message = 'Имеются поля с некорректными данными.';
               
                // Установка сообщений об ошибках.
                $errors = $e->errors('models');
            }
        }
        return $authTpl;
    }
   
    //Вход пользователя.
    private function userLogin()
    {
        $authTpl = View::factory('auth/login')
            ->bind('errors', $errors)
            ->bind('message', $message);
           
        if (HTTP_Request::POST == $this->request->method())
        {
            // "Запомнить меня".
            $remember = array_key_exists('remember', $this->request->post()) ?
                (bool) $this->request->post('remember') : FALSE;
               
            $user = $this->auth->login($this->request->post('username'),
                $this->request->post('password'), $remember);
           
            // Редирект юзера в случае успеха логина.
            if ($this)
            {
                $this->user = $this->auth->get_user();
                View::set_global('username', $this->user->get('username'));
                // Сбросить значения формы.
                $_POST = array();
                $message = 'С возвращением, '.$this->user->get('username').'!';
            }
            else $message = 'Неверное имя или пароль';
        }
        return $authTpl;
    }
   
    //Выход пользователя.
    private function userLogout()
    {
        // Разлогиниваем юзера.
        $this->auth->logout();
        // Редирект на ту же страницу.
        View::set_global('username', null);
        HTTP::redirect($_SERVER['HTTP_REFERER']);
    }
   
    //Общий экшн авторизации/регистрации.
    private function action_index($arg = '')
    {
        View::set_global('bodyClass', 'movies');
        $errors = array();
       
        //Если юзер уже вошёл или "запомнен" в куках.
        if ($this->user)
        {
            if($arg == 'login')
                $this->colL_content .= '<h3>Вы уже вошли на сайт.</h3>';
            else if($arg == 'reg')
                $this->colL_content .= '<h3>Вы уже зарегистрированы.</h3>';
            else if($arg == 'logout')
                $this->colL_content .= $this->userLogout();
        }
        else
        {
            if($arg == 'login')
                $this->colL_content .= $this->userLogin();
            else if($arg == 'reg')
                $this->colL_content .= $this->userCreate();
        }
       
        $this->action_pageBuild();
       
        $this->template->scripts[] = 'public/js/jquery-1.10.1.min';
        $this->template->scripts[] = 'public/js/select';
        $this->template->content = $this->content;
    }
   
    //Экшн авторизации.
    public function action_login(){ $this->action_index('login'); }
   
    //Экшн регистрации.
    public function action_registration(){ $this->action_index('reg'); }
   
    //Экшн логаута.
    public function action_logout(){ $this->action_index('logout'); }
}
 

флоппик

promotor fidei
Команда форума
Партнер клуба
PHP:
//Получаем текущего пользователя из сессии (если он залогинился).
            $this->user = $this->auth->get_user();
Потому что он не из сессии получается, конечно.
В конкретном случае нужно просто на продакшене включать в конфиге базы caching = true, и эти запросы будут реже.
На практике - вообще пофиг, потому что запрос 1 строки с условием по первичному ключу это самый быстрый запрос к БД.

Нужно это для того, конечно, что бы нормально проверять изменения прав и данных пользователя.
 

Здыхлик

Kohaner
Команда форума
PHP:
//Получаем текущего пользователя из сессии (если он залогинился).
            $this->user = $this->auth->get_user();
Потому что он не из сессии получается, конечно.
1. Этот метод возвращает как раз из сессии
2. Каждый объект ORM при восстановлении из сессии (читай десериализация) заново загружается из БД. Соответственно это можно отключить через свойство $_reload_on_wakeup (TRUE по умолчанию), но для юзеров точно не стоит, согласен.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
1. Этот метод возвращает как раз из сессии
2. Каждый объект ORM при восстановлении из сессии (читай десериализация) заново загружается из БД. Соответственно это можно отключить через свойство $_reload_on_wakeup (TRUE по умолчанию), но для юзеров точно не стоит, согласен.
Ну, вообще я выразился криво, да, я имел ввиду, что модель один фиг заполняется заново из базы, если даже была положена в сессию.
 

php_coder

Новичок
модель один фиг заполняется заново из базы, если даже была положена в сессию.
Но не при каждом же клике по ссылке! Этак 100 посетителей без всяких ддосов серв положат. Короч мне нужно чтобы Auth лез в бд только 1 раз когда юзер логинится, а все последующие разы Auth лез в $_SESSION/куки/хз-куда лишь бы не в БД. Собсно мне нужно всегда иметь под рукой имя пользователя и его роль.
И как я успел понять не $this->user = $this->auth->get_user(); порождает запрос к БД, а $this->auth = Auth::instance(), который создаёт внутри себя Session::instance(), который созадёт эземпляр класса Session_Native. И вот где-то тут уже идёт запрос к БД. Но я так и не смог докопаться где именно. Кэш в конфиге включил - не помогло. Как установить $_reload_on_wakeup в False не могу понять.
 

php_coder

Новичок
Только сейчас добрались руки до кэша.
Запрос, порождаемый Auth::instance(); выпилил.
Запрос, порождаемый $this->auth->get_user(); оставил, как посоветовал Иван в посте №3.
Парни, спасибо за помощь ещё раз.
 
Сверху