Я хотів би продовжити час сеансу в php
Я знаю, що це можна зробити, змінивши файл php.ini. Але я не маю до нього доступу.
То чи можна це робити тільки за допомогою php-коду?
Я хотів би продовжити час сеансу в php
Я знаю, що це можна зробити, змінивши файл php.ini. Але я не маю до нього доступу.
То чи можна це робити тільки за допомогою php-коду?
Відповіді:
Час очікування сеансу - це поняття, яке потрібно реалізувати в коді, якщо ви хочете суворих гарантій; це єдиний спосіб, коли ви можете бути абсолютно впевнені, що жоден сеанс не переживе після Хвилини бездіяльності.
Якщо розслабити цю вимогу трохи прийнятно, і ви добре ставите нижню межу замість суворого обмеження тривалості, ви можете це зробити легко і без написання спеціальної логіки.
Якщо ваші сеанси реалізовані за допомогою файлів cookie (які вони, мабуть, є), і якщо клієнти не є шкідливими, ви можете встановити верхню межу тривалості сеансу, налаштувавши певні параметри. Якщо ви використовуєте PHP-сеанс за замовчуванням, обробляючи файли cookie, налаштування session.gc_maxlifetime
разом із session_set_cookie_params
файлом має працювати так:
// server should keep session data for AT LEAST 1 hour
ini_set('session.gc_maxlifetime', 3600);
// each client should remember their session id for EXACTLY 1 hour
session_set_cookie_params(3600);
session_start(); // ready to go!
Це працює, налаштовуючи сервер для збереження даних про сеанс принаймні на одну годину бездіяльності та вказуючи своїм клієнтам, що вони повинні «забути» свій ідентифікатор сеансу після того ж періоду часу. Обидва ці кроки необхідні для досягнення очікуваного результату.
Якщо ви не скажете клієнтам забути ідентифікатор сеансу через годину (або якщо клієнти зловмисні і вирішили ігнорувати ваші вказівки), вони продовжуватимуть використовувати той самий ідентифікатор сеансу, і його ефективна тривалість не буде детермінованою. Це тому, що сеанси, термін служби яких закінчився на стороні сервера, не збираються сміттям негайно, а лише кожного разу, коли починається GC сеансу .
GC - це потенційно дорогий процес, тому типова ймовірність досить мала або навіть нульова (веб-сайт, який отримує величезну кількість звернень, ймовірно, повністю відмовиться від ймовірнісного GC і запланував, щоб це відбувалося у фоновому режимі кожні X хвилин). В обох випадках (припускаючи, що не співпрацюють клієнти) нижня межа ефективного життя сесії буде session.gc_maxlifetime
, але верхня межа буде непередбачуваною.
Якщо ви не встановите один session.gc_maxlifetime
і той же проміжок часу, сервер може відкинути дані про сеанси в режимі очікування раніше; у цьому випадку клієнт, який все ще запам'ятовує свій ідентифікатор сеансу, представить його, але сервер не знайде жодних даних, пов’язаних із цим сеансом, фактично веде себе так, ніби сесія щойно розпочалася.
Ви можете зробити речі повністю контрольованими, використовуючи власну логіку, щоб також розмістити верхню межу бездіяльності сеансу; разом із нижньою межею зверху це призводить до суворої обстановки.
Зробіть це, зберігаючи верхню межу разом із рештою даних сеансу:
session_start(); // ready to go!
$now = time();
if (isset($_SESSION['discard_after']) && $now > $_SESSION['discard_after']) {
// this session has worn out its welcome; kill it and start a brand new one
session_unset();
session_destroy();
session_start();
}
// either new or old, it should live at most for another hour
$_SESSION['discard_after'] = $now + 3600;
Поки ми взагалі не переймалися точними значеннями кожного ідентифікатора сеансу, лише тим, що дані повинні існувати до тих пір, поки нам це потрібно. Будьте в курсі, що у (маловірогідному) випадку, коли ідентифікатор сеансу має значення для вас, потрібно ретельно відновити їх, session_regenerate_id
коли це потрібно.
session_start()
(інакше взагалі немає ефекту), і лише якщо ви завжди дзвоните ці два раніше session_start
(інакше gc_maxlifetime
це може вплинути на всі відкриті сесії, хоча це session_set_cookie_params
може вплинути лише на новий сеанс, який починається з поточний запит).
Якщо ви використовуєте обробку сеансу PHP за замовчуванням, єдиний спосіб надійно змінити тривалість сеансу на всіх платформах - це змінити php.ini . Це тому, що на деяких платформах збирання сміття реалізується за допомогою скрипту, який працює кожен певний час ( сценарій cron ), який читається безпосередньо з php.ini , і тому будь-які спроби змінити його під час виконання, наприклад, через ini_set()
, є ненадійними та, швидше за все, не буде працювати.
Наприклад, в системах Debian Linux внутрішнє збирання сміття PHP відключається шляхом встановлення session.gc_probability=0
за замовчуванням у конфігурації, а замість цього здійснюється через /etc/cron.d/php, який працює в XX: 09 та XX: 39 (тобто кожні півгодини). Це завдання на роботу з хроном шукає сесії, старші за вказаний у конфігурації сеанс.gc_maxlifetime , і якщо такі знайдені, вони видаляються. Як наслідок, у цих системах ini_set('session.gc_maxlifetime', ...)
ігнорується. Це також пояснює, чому в цьому питанні: PHP-сесії закінчилися занадто швидко , у ОП були проблеми в одному хості, але проблеми припинилися при переході на інший хост.
Отже, зважаючи на те, що у вас немає доступу до 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()
щоб збільшити термін служби файлів cookie.
<?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) складніший; По суті, вам доведеться самостійно реалізовувати всі функції сеансу. Я тут не буду вникати в деталі.
php.ini
ваших практичних варіантів, суворо обмежено.
/usr/lib/php5/maxlifetime
, що не обчислює значення нижче 24 хвилин. Таким чином, ви не можете встановити час очікування на сеанс нижче, ніж це.
Додавання коментарів для тих, хто користується Plesk, який має проблеми з будь-яким із перерахованих вище, оскільки він зводив мене з розуму, встановлюючи session.gc_maxlifetime зі свого сценарію PHP, звичайно не працюючи, оскільки Plesk має власний сценарій збору сміття, запущений з cron.
Я використовував рішення, розміщене за посиланням нижче, щоб перемістити роботу cron з погодинної в щоденну, щоб уникнути цього питання, тоді головна відповідь вище повинна працювати:
mv /etc/cron.hourly/plesk-php-cleanuper /etc/cron.daily/
https://websavers.ca/plesk-php-sesions-timing-earlier- очікується
Помістіть $_SESSION['login_time'] = time();
на попередню сторінку аутентифікації. І фрагменти, наведені нижче, на будь-якій іншій сторінці, де ви хочете перевірити час очікування сеансу.
if(time() - $_SESSION['login_time'] >= 1800){
session_destroy(); // destroy session.
header("Location: logout.php");
die(); // See https://thedailywtf.com/articles/WellIntentioned-Destruction
//redirect if the page is inactive for 30 minutes
}
else {
$_SESSION['login_time'] = time();
// update 'login_time' to the last time a page containing this code was accessed.
}
Редагувати: це працює лише в тому випадку, якщо ви вже використовували перетворення в інших публікаціях або вимкнено збирання сміття та хочете вручну перевірити тривалість сеансу. Не забудьте додати die()
після переадресації, оскільки деякі сценарії / роботи можуть ігнорувати це. Крім того, безпосередньо знищити сеанс, session_destroy()
а не покладатися на переспрямування, це може бути кращим варіантом, знову ж таки, у випадку зловмисного клієнта або робота.
Просто повідомлення про розміщення хостинг- сервера або додане на домени =
Щоб ваші налаштування працювали, ви повинні мати інший dir-сеанс збереження для доданого домену, використовуючи php_value session.save_path "папкаA / sessionA".
Тож створіть папку на своєму кореневому сервері, а не в public_html та не публікуйтеся ззовні. Для мого cpanel / сервера відмінно працювали дозволи на папки 0700. Спробуйте ...
php код =
#Session timeout, 2628000 sec = 1 month, 604800 = 1 week, 57600 = 16 hours, 86400 = 1 day
ini_set('session.save_path', '/home/server/.folderA_sessionsA');
ini_set('session.gc_maxlifetime', 57600);
ini_set('session.cookie_lifetime', 57600);
ini_set('session.cache_expire', 57600);
ini_set('session.name', 'MyDomainA');
перед session_start ();
або
.htaccess =
php_value session.save_path /home/server/.folderA_sessionsA
php_value session.gc_maxlifetime 57600
php_value session.cookie_lifetime 57600
php_value session.cache_expire 57600
php_value session.name MyDomainA
Після багатьох досліджень і тестувань це спрацювало чудово для спільного сервера cpanel / php7. Велике спасибі: NoiS
Ні. Якщо у вас немає доступу до php.ini, ви не можете гарантувати, що зміни матимуть будь-який ефект.
Я сумніваюся, що вам потрібно продовжити час на сеанси.
На даний момент у нього досить розумний тайм-аут, і немає причин продовжувати його.
SELECT id FROM gallery WHERE SortOrder > $currentsortorder LIMIT 1
Ви можете змінити значення в php.ini зі свого PHP-коду, використовуючи ini_set()
.
session.gc_maxlifetime
не є настройкою, яка контролює час роботи сеансу. Це може бути здивовано працювати так, якщо ви налаштовані session.gc_divisor
на це 1
, але це просто жахливо.
gc_maxlifetime
встановлює інтервал, через який дані сеансу підлягають збору сміття - якщо GC відбудеться після того, як пройде багато часу, дані сеансу будуть знищені (для налаштувань за замовчуванням це те саме, що закінчується сеанс). Але GC спрацьовує ймовірнісно на кожному запуску сеансу, тому немає гарантії, що сеанс дійсно закінчиться - ви можете побудувати криву зондування проти часу, але він не буде схожий на цегляну стіну. Ось лише верхівка айсберга; см stackoverflow.com/questions/520237 / ...