Настройка сессионного механизма PHP через параметры php.ini

Раздел: Администрирование PHP -> Настройка PHP

Основы настройки сессий в PHP

Наиболее эффективный способ настройки сессий - редактирование файла php.ini.

Этот метод применяется при наличии доступа к серверной конфигурации и позволяет задать параметры для всех скриптов. Рекомендуемые значения для production:


session.save_handler = files
session.save_path = "/var/lib/php/sessions"
session.name = SESSID
session.cookie_lifetime = 0
session.cookie_secure = 1
session.cookie_httponly = 1
session.cookie_samesite = "Lax"
session.use_strict_mode = 1
session.use_cookies = 1
session.use_only_cookies = 1
session.gc_maxlifetime = 1440
session.gc_probability = 1
session.gc_divisor = 1000
session.sid_length = 48
session.sid_bits_per_character = 6

Php выделить память (выделение памяти php)

Пояснение настроек:

  • session.save_handler - определяет способ хранения. files - файлы на диске, подходит для небольших проектов.
  • session.save_path - каталог для хранения файлов сессий. Важно, чтобы у веб-сервера были права на запись.
  • session.name - имя cookie (по умолчанию PHPSESSID). Рекомендуется изменить для снижения узнаваемости.
  • session.cookie_lifetime = 0 - cookie удаляется при закрытии браузера (сессионная).
  • session.cookie_secure = 1 - передача cookie только по HTTPS.
  • session.cookie_httponly = 1 - запрет доступа к cookie из JavaScript (защита от XSS).
  • session.cookie_samesite = "Lax" - ограничение отправки cookie с межсайтовыми запросами.
  • session.use_strict_mode = 1 - отклонение неинициализированных идентификаторов сессии.
  • session.use_cookies и session.use_only_cookies - использование только cookie для передачи ID сессии.
  • session.gc_maxlifetime - время жизни данных сессии на сервере (1440 секунд = 24 минуты).
  • session.gc_probability и session.gc_divisor - вероятность запуска сборщика мусора (1/1000 = 0.1% при каждом старте).
  • session.sid_length и session.sid_bits_per_character - длина и энтропия идентификатора. 48 символов с 6 битами на символ дают 288 бит энтропии.

Типичная ошибка:

При изменении session.save_path без создания каталога и установки прав сессии не будут записываться. Ошибка в логах: "Warning: session_start(): open(/path/to/sessions/..., O_RDWR) failed: No such file or directory". Решение - создать каталог и выдать права 0777 (или 0733) для веб-сервера.

Как изменить параметры сессий без доступа к php.ini?

Если нет возможности редактировать глобальный php.ini, можно использовать функцию ini_set() в начале скрипта. Однако настройки будут действовать только для текущего запроса и не влияют на уже запущенные сессии. Параметры, которые требуются до session_start(), необходимо задавать до вызова этой функции.


<?php
// Устанавливаем параметры сессии до session_start()
ini_set('session.name', 'MYAPPID');
ini_set('session.cookie_lifetime', 3600);
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1);
ini_set('session.use_strict_mode', 1);
ini_set('session.sid_length', 64);
ini_set('session.sid_bits_per_character', 6);

session_start();
?>

Php ini timezone (настройка часового пояса в php (date.timezone))

Важно: некоторые директивы (например, session.save_handler) нельзя изменить после начала сессии, а session.save_path можно, но только до session_start().

Проблема:

Если php.ini уже содержит session.auto_start = 1, то сессия запускается автоматически, и ini_set() не успеет примениться. В таких случаях следует отключить session.auto_start в php.ini или использовать .htaccess.

Как организовать хранение сессий в Redis для повышения производительности?

Redis обеспечивает быстрое чтение/запись и удобен для масштабирования. Для этого нужен модуль redis (phpredis) или predis. Установка: pecl install redis или через менеджер пакетов. Далее в php.ini:


session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379?auth=password&database=0&prefix=PHPSESS:"

Xampp php ini (настройка php.ini в xampp)

Параметр auth - если требуется пароль, database - номер БД, prefix - префикс ключей.

Пример настройки через ini_set():


<?php
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379');
session_start();
?>

Php ini sessions (настройка сессий в php (session.*))

Типичная ошибка:

Если Redis не запущен или указан неверный порт, session_start() вызовет предупреждение "Failed to read session data: redis". Решение - проверить подключение: redis-cli ping должно вернуть PONG.

Как установить разное время жизни для cookie сессии и данных на сервере?

session.cookie_lifetime управляет временем жизни cookie в браузере. session.gc_maxlifetime - временем, после которого данные сессии считаются устаревшими и могут быть удалены сборщиком мусора. Для долгих сессий (например, "запомнить меня") можно установить cookie_lifetime в большое значение, а gc_maxlifetime оставить по умолчанию или увеличить. Однако надо помнить, что GC запускается с вероятностью, поэтому данные могут храниться дольше.


; php.ini
session.cookie_lifetime = 86400 ; 24 часа
session.gc_maxlifetime = 86400  ; данные тоже хранятся 24 часа

Php ini extension (настройка расширений php (extension_dir, extension))

Если нужно, чтобы cookie жила дольше, а данные удалялись раньше, можно использовать session_set_cookie_params():


<?php
// Устанавливаем cookie на 7 дней
session_set_cookie_params(7*24*3600);
session_start();
?>

ограничение памяти php (ограничение памяти php)

Проблема:

Если gc_maxlifetime меньше cookie_lifetime, то после удаления данных сессия станет невалидной, хотя cookie все еще будет отправляться. Рекомендуется устанавливать gc_maxlifetime не меньше cookie_lifetime.

Как защитить сессионные cookie от XSS и CSRF?

Установка флагов Secure, HttpOnly, SameSite. В php.ini:


session.cookie_secure = 1
session.cookie_httponly = 1
session.cookie_samesite = "Strict"

изменить настройки php (изменение настроек php)

В коде через session_set_cookie_params():


<?php
session_set_cookie_params([
    'lifetime' => 0,
    'path' => '/',
    'domain' => 'example.com',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Strict'
]);
session_start();
?>

Index php page info (страница phpinfo())

Флаг SameSite=Strict полностью блокирует отправку cookie с межсайтовых запросов, но может сломать некоторые сценарии (например, переход по ссылке с внешнего сайта). Lax - компромисс.

Ошибка:

Если сайт использует HTTP и установлен session.cookie_secure = 1, cookie не будет отправлена, и сессия не начнется. Решение - использовать HTTPS или отключить secure для разработки.

Как отключить автоматический сборщик мусора и запускать его по расписанию?

Для больших сайтов автоматический GC (вероятностный) может вызывать нежелательные задержки. Можно установить session.gc_probability = 0 и запускать очистку через cron с помощью функции session_gc() (PHP 7.1+). В php.ini:


session.gc_probability = 0
session.gc_divisor = 1

Php ini memory (настройка memory_limit в php)

Скрипт очистки (запускается cron, например, раз в час):


<?php
// gc.php
session_start();
session_gc(); // удаляет сессии, срок которых истек
session_write_close();
?>

Php post size (размер post данных в php)

Предостережение:

session_gc() работает только для текущего save_handler. Для files она удаляет файлы из save_path. Для Redis надо использовать отдельные инструменты (например, скрипт redis-cli или TTL).

Как сделать идентификаторы сессий более устойчивыми к угадыванию?

Увеличить session.sid_length (максимум 256) и session.sid_bits_per_character (4,5,6). Бит на символ: 4 = hex (0-9a-f), 5 = base32 (0-9a-v), 6 = base64 (0-9a-zA-Z,-). Чем выше, тем больше энтропия, но и длина строки меньше при том же количестве бит. Рекомендуется:


session.sid_length = 48
session.sid_bits_per_character = 6

битрикс restore php (восстановление php в битрикс)

Проверить текущий ID:


<?php
session_start();
echo session_id();
?>

Ошибка:

Если sid_bits_per_character установлен в 6, но в среде есть проблемы с генерацией случайных чисел (например, отсутствует openssl или /dev/urandom), PHP может выдать предупреждение. Решение - проверить работу random_bytes() или переключиться на 5.

- Change php (изменение php)
- Debian php (установка php на debian)
- Php ubuntu (php на ubuntu)

Расширенные примеры конфигурации сессий

Пример 1: Проверка текущих настроек через phpinfo() и php -i

Пример

<?php
// Создайте файл info.php с содержимым:
phpinfo();
?>
После запуска найдите раздел "session" - все директивы session.*

В командной строке:

Пример

php -i | grep session
session.auto_start => Off => Off
session.cache_expire => 180 => 180
...
session.save_handler => files => files

Пример 2: Настройка сессий через .htaccess

Пример

# .htaccess
php_value session.name MYID
php_value session.cookie_lifetime 3600
php_value session.cookie_secure 1
php_value session.cookie_httponly 1
php_value session.gc_maxlifetime 3600
php_value session.save_path "/tmp/php_sessions"

Требуется, чтобы в конфигурации Apache был разрешен AllowOverride Options и Limits.

Пример 3: Установка параметров cookie через session_set_cookie_params()

Пример

<?php
// Устанавливаем cookie только для конкретной сессии
$cookieParams = session_get_cookie_params();
$cookieParams['lifetime'] = 0;
$cookieParams['secure'] = true;
$cookieParams['httponly'] = true;
$cookieParams['samesite'] = 'None'; // требует Secure
session_set_cookie_params($cookieParams);
session_start();
?>

Важно: вызов session_set_cookie_params() должен происходить до session_start(). Если вызвать после, изменения не применятся.

Пример 4: Хранение сессий в Memcached

Пример

; php.ini
session.save_handler = memcached
session.save_path = "127.0.0.1:11211?persistent=1&weight=2&timeout=1&retry_interval=15"

Убедитесь, что модуль memcached установлен. redis и memcached - популярные альтернативы files.

Пример 5: Скрипт для cron по очистке файлов сессий

Пример

<?php
// cleanup_sessions.php
$maxLifetime = ini_get('session.gc_maxlifetime');
$savePath = session_save_path();
if (!$savePath) $savePath = sys_get_temp_dir();

foreach (glob($savePath . '/sess_*') as $file) {
    if (filemtime($file) + $maxLifetime < time()) {
        unlink($file);
    }
}
?>

Добавить в crontab: 0 * * * * php /path/to/cleanup_sessions.php

Пример 6: Работа с блокировкой сессий (session_write_close)

По умолчанию PHP блокирует файл сессии при вызове session_start(), чтобы избежать гонок. Если скрипт выполняет длительные операции, другие запросы того же пользователя будут ждать. Решение - закрыть сессию после чтения:

Пример

<?php
session_start();
$user = $_SESSION['user'];
// Сессионные данные больше не нужны, можно закрыть
session_write_close();

// Длительная операция (например, генерация отчета)
sleep(10);
echo "Hello, $user";
?>

Параллельные запросы теперь не блокируются.

Пример 7: Перегенерация ID сессии для защиты от фиксации

Пример

<?php
session_start();
// После успешной аутентификации
if ($_POST['login']) {
    // Проверка пароля...
    session_regenerate_id(true); // true - удалить старую сессию
    $_SESSION['user_id'] = 123;
}
?>

Это предотвращает session fixation.

Пример 8: Установка собственного идентификатора сессии

Пример

<?php
$customId = 'my-custom-id-' . bin2hex(random_bytes(16));
session_id($customId);
session_start();
echo session_id(); // выведет my-custom-id-...
?>

Используется для интеграции с внешними системами, но требует осторожности - нужно гарантировать уникальность.

Настройка сессий в PHP (session.*) - comments

En
Php ini sessions (php)