Если вы используете обработку сеансов PHP по умолчанию, единственный способ надежно изменить продолжительность сеанса на всех платформах - это изменить php.ini .Это связано с тем, что на некоторых платформах сборка мусора осуществляется с помощью сценария, который запускается каждый определенный момент времени (сценарий cron ), который читает непосредственно из php.ini , и, следовательно, любые попытки изменить егово время выполнения, например, через ini_set()
, они ненадежны и, скорее всего, не будут работать.
Например, в системах Debian Linux внутренняя сборка мусора в PHP отключена, если в конфигурации в конфигурации по умолчанию установлен session.gc_probability=0
и вместо этого выполняется через /etc/cron.d/php, который выполняется в XX: 09 и XX: 39 (то есть каждые полчаса).Это задание cron ищет сеансы старше session.gc_maxlifetime , указанные в конфигурации, и, если они найдены, они удаляются.Как следствие, в этих системах ini_set('session.gc_maxlifetime', ...)
игнорируется.Это также объясняет, почему в этом вопросе: Сроки PHP слишком быстро истекают , у OP были проблемы на одном хосте, но проблемы прекратились при переключении на другой хост.
Итак, учитывая, что выне иметь доступа к php.ini , если вы хотите сделать это мобильно, использование обработки сеанса по умолчанию не вариант.Очевидно, для вашего хоста было достаточно продлить срок действия файлов cookie, но если вы хотите, чтобы решение работало надежно, даже если вы переключаете хосты, вы должны использовать другую альтернативу.
Доступные альтернативные методы включают в себя:
Установка другого обработчика сеанса (сохранения) в PHP для сохранения сеансов в другом каталоге или в базе данных, как указано в PHP: пользовательские обработчики сеансов (руководство по PHP) ,так что задание cron не достигает его, и происходит только внутренняя сборка мусора в PHP.Эта опция, вероятно, может использовать ini_set()
для установки session.gc_maxlifetime , но я предпочитаю просто игнорировать параметр maxlifetime в моем обратном вызове gc()
и самостоятельно определять максимальное время жизни.
Полностью забудьте о внутренней обработке сессий PHP и реализуйте собственное управление сессиями.У этого метода есть два основных недостатка: вам понадобятся ваши собственные глобальные переменные сеанса, поэтому вы потеряете преимущество суперглобального $_SESSION
, и ему потребуется больше кода, что даст больше возможностей для ошибок и недостатков безопасности.Самое главное, идентификатор сеанса должен быть сгенерирован из криптографически безопасных случайных или псевдослучайных чисел, чтобы избежать предсказуемости идентификатора сеанса (приводящей к возможному угону сеанса), а это не так просто сделать с помощью переносимого PHP.Основным преимуществом является то, что он будет работать согласованно на всех платформах, и вы будете иметь полный контроль над кодом.Такой подход используется, например, программным обеспечением форума phpBB (по крайней мере, версия 1; я не уверен насчет более поздних версий).
Существует пример(1) в документации для session_set_save_handler()
.Пример длинный, но я воспроизведу его здесь с соответствующими изменениями, необходимыми для увеличения продолжительности сеанса.Обратите внимание на добавление session_set_cookie_params()
для увеличения времени жизни куки.
<?php
class FileSessionHandler
{
private $savePath;
private $lifetime;
function open($savePath, $sessionName)
{
$this->savePath = 'my_savepath'; // Ignore savepath and use our own to keep it safe from automatic GC
$this->lifetime = 3600; // 1 hour minimum session duration
if (!is_dir($this->savePath)) {
mkdir($this->savePath, 0777);
}
return true;
}
function close()
{
return true;
}
function read($id)
{
return (string)@file_get_contents("$this->savePath/sess_$id");
}
function write($id, $data)
{
return file_put_contents("$this->savePath/sess_$id", $data) === false ? false : true;
}
function destroy($id)
{
$file = "$this->savePath/sess_$id";
if (file_exists($file)) {
unlink($file);
}
return true;
}
function gc($maxlifetime)
{
foreach (glob("$this->savePath/sess_*") as $file) {
if (filemtime($file) + $this->lifetime < time() && file_exists($file)) { // Use our own lifetime
unlink($file);
}
}
return true;
}
}
$handler = new FileSessionHandler();
session_set_save_handler(
array($handler, 'open'),
array($handler, 'close'),
array($handler, 'read'),
array($handler, 'write'),
array($handler, 'destroy'),
array($handler, 'gc')
);
// the following prevents unexpected effects when using objects as save handlers
register_shutdown_function('session_write_close');
session_set_cookie_params(3600); // Set session cookie duration to 1 hour
session_start();
// proceed to set and retrieve values by key from $_SESSION
Подход (2) более сложный;По сути, вы должны самостоятельно реализовать все функции сеанса.Я не буду вдаваться в подробности здесь.