Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Всем добрый день!
Решил написать свой логгер к сайту, оформил его в виде синглтона и добавил в автозагрузчик
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');
});
Не в сети
То есть, как я понимаю, без сессий не обойтись? Можно ли какими-либо другими способами реализовать это или при каждом запросе придется инициализировать логгер?
- или при каждом запросе придется инициализировать логгер?
А в чём собственно проблема? Каждый запрос на сервер (каждое выполнение PHP-скрипта) — это новая среда выполнения, аналогично запуску обычной программы. Соответственно все переменные инициализирующий умолчательными значениями.
Чтобы придать им какое-то другое значение нужно использовать постоянное (persistent) хранилище — сессии в файлах, СУБД, NoSQL. NoSQL может быть как MongoDB, так и более лёгкие хранилища ключ/значение (Redis, APC, XCache, eAccelerator и т.п.).
Не в сети
Уже нет проблемы, использую сессии, но только memcache. Хотел узнать насчет этого: при закрытии браузера сессия пользователя memcached убивается автоматически?
Не в сети
А где можно посмотреть когда сессия удаляется и можно ли удалить её самому?
Порылся в исходниках и конфигах. Нашел, где выставляется лайфтайм сессии:
/*
|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| The number of minutes a session can be idle before expiring.
|
*/
'lifetime' => 60,
Но в классе Session не нашел метода для принудительного закрытия сессии
Не в сети