Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 26.04.2013 11:07:32

mephis

Автозагрузка библиотеки и хранение ее состояния на протяжение сеанса

Всем добрый день!
Решил написать свой логгер к сайту, оформил его в виде синглтона и добавил в автозагрузчик

Autoloader::map(array(
	'Base_Controller' => path('app').'controllers/base.php',
	'Logger' => path('app').'libraries/Logger.php'
));

У логгера есть несколько статических аттрибутов (user_data, filename, destination).
При заходе на корневой роут '/' я его инициализирую, т.е. присваиваю аттрибутам некие значения и использую (к примеру пишу в файл "юзер :юзер посетил главную страницу").
Проблема в том, что если я захожу на роут '/s' и проверяю состояние аттрибутов, то они удаляются и мне заново приходится инициализировать логгер.

Мне нужно, чтобы логгер инициализировался один раз и на протяжении от начала и до выхода из приложения хранил в себе аттрибуты. Как такое реализовать без использования сессий?

Код логгера:

abstract class Logger {
    
    private static $filename;
    private static $destination;
    
    private static $initialized = FALSE;
    
    private static $user_data = [];

    private static function getDestination() {
        return self::$destination;
    }
    
    private static function getFilename() {
        return self::$filename;
    }
    
    private static function getUserData() {
        return self::$user_data;
    }
    
    private static function setDestination($destination) {
        self::$destination = $destination;
        return;
    }
    
    private static function setFilename($filename) {
        self::$filename = $filename;
        return;
    }
    
    private static function setUserData($user_data) {
        self::$user_data = $user_data;
        return;
    }
    
    private static function generateFilename() {
        if(self::$user_data['auth']) {
            self::setFilename(self::$user_data['name'] . '(' . self::$user_data['ip_address'] . ')' . '.log');
        } else {
            self::setFilename(self::$user_data['country'] . '(' . self::$user_data['ip_address'] . ')' . '.log');
        }
        return self::$filename;
    }
    
    private static function fileExists() {
        return File::exists(self::$destination . self::$filename);
    }
    
    private static function fileCreate() {
        if(self::fileExists()) {
            return self::$filename;
        } else {
            File::put(self::$destination . self::$filename, Lang::line('logger.start', array('time' => date('d F Y H:i:s'))));
        }
        return self::$filename;
    }
    
    public static function addLine($line) {
        if(!empty($line)) {
            $string = "[" . date('d F Y H:i:s') . "] " . self::$user_data['country'] . ": " . $line . "\n";
            File::append(self::$destination . self::$filename, $string);
        } else {
            return FALSE;
        }
        return TRUE;
    }
    
    public static function isInitialized() {
        return self::$initialized;
    }
    
    public static function initialize($user_data, $destination = NULL) {
        if(is_null($destination)) {
            self::setDestination(path('storage').'logs/');
        } else {
            self::setDestination($destination);
        }
        if(isset($user_data['country'], $user_data['ip_address'], $user_data['auth'])) {
            self::setUserData($user_data);
            self::generateFilename();
            self::fileCreate();
            self::$initialized = TRUE;
        }
        else {
            return FALSE;
        }
        return TRUE;
    }
    
    public static function traceState() {
        print_r('Destination: ' . self::$destination . '<br> User data: ');
        print_r(self::$user_data);
        print_r('<br>');
        print_r('File name: ' .self::$filename . '<br>');
        print_r('Initialized:' . (self::$initialized ? 'TRUE' : 'FALSE') . '<br>');
    }
}

Код роутера:

Route::get('/', function()
{
    $user_data = array(
        'name' => 'Ilya',
        'ip_address' => $_SERVER['REMOTE_ADDR'],
        'auth' => TRUE,
        'country' => 'Ukraine'
    );
    Logger::traceState();
    if(!Logger::isInitialized()){
        Logger::initialize($user_data);
    }
    Logger::addLine('User visited home page');
    Logger::traceState();
});

Route::get('/s', function()
{
    Logger::traceState();
    Logger::addLine('User visited /s/ page');

});

#2 26.04.2013 11:21:15

Re: Автозагрузка библиотеки и хранение ее состояния на протяжение сеанса

Статические переменные «статические» только в рамках одного запроса. Сессии как раз и существуют для восстановления состояния между несколькими запросами.

p.s: использование self:: — это PHP ⇐ 5.2; оно не поддерживает наследование, поэтому лучше использовать static::.

Не в сети

#3 26.04.2013 11:28:23

mephis

Re: Автозагрузка библиотеки и хранение ее состояния на протяжение сеанса

То есть, как я понимаю, без сессий не обойтись? Можно ли какими-либо другими способами реализовать это или при каждом запросе придется инициализировать логгер?

#4 26.04.2013 13:27:51

Re: Автозагрузка библиотеки и хранение ее состояния на протяжение сеанса

  1. или при каждом запросе придется инициализировать логгер?

А в чём собственно проблема? Каждый запрос на сервер (каждое выполнение PHP-скрипта) — это новая среда выполнения, аналогично запуску обычной программы. Соответственно все переменные инициализирующий умолчательными значениями.

Чтобы придать им какое-то другое значение нужно использовать постоянное (persistent) хранилище — сессии в файлах, СУБД, NoSQL. NoSQL может быть как MongoDB, так и более лёгкие хранилища ключ/значение (Redis, APC, XCache, eAccelerator и т.п.).

Не в сети

#5 26.04.2013 15:47:11

mephis

Re: Автозагрузка библиотеки и хранение ее состояния на протяжение сеанса

Уже нет проблемы, использую сессии, но только memcache. Хотел узнать насчет этого: при закрытии браузера сессия пользователя memcached убивается автоматически?

#6 26.04.2013 15:52:31

Re: Автозагрузка библиотеки и хранение ее состояния на протяжение сеанса

Сессия привязывается к конкретному посетителю сохранением её ID в долгоживущем cookie.

Не в сети

#7 26.04.2013 16:27:22

mephis

Re: Автозагрузка библиотеки и хранение ее состояния на протяжение сеанса

А где можно посмотреть когда сессия удаляется и можно ли удалить её самому?

#8 26.04.2013 16:44:37

mephis

Re: Автозагрузка библиотеки и хранение ее состояния на протяжение сеанса

Порылся в исходниках и конфигах. Нашел, где выставляется лайфтайм сессии:

/*
	|--------------------------------------------------------------------------
	| Session Lifetime
	|--------------------------------------------------------------------------
	|
	| The number of minutes a session can be idle before expiring.
	|
	*/

	'lifetime' => 60,

Но в классе Session не нашел метода для принудительного закрытия сессии

#9 29.04.2013 13:11:18

Re: Автозагрузка библиотеки и хранение ее состояния на протяжение сеанса

  1. А где можно посмотреть когда сессия удаляется и можно ли удалить её самому?
PHP
Session::flush();

См. session/payload.php.

Не в сети

Подвал раздела