Класс Session (сессии)
Класс Session позволяет вам сохранять пользовательские "состояния" и отслеживать их активность, пока они перемещаются по вашему сайту. Класс Session сохраняет информацию сессий для каждого пользователя в сериализованных (и опционально — зашифрованных) данных в куки. Также он может сохранять данные сессий в таблице базы данных для большей безопасности. Идентификатор сессии в куке пользователя будет сопоставляться с идентификатором, сохраненным в базе данных. По умолчанию используются только куки. Если вы выбрали работу с базой данных, вы должны создать таблицу, как показано ниже.
Примечание: Класс Session НЕ заменяет родные сессии PHP. Он генерирует собственные данные сессий, предлагая больше гибкости для разработчиков.
Примечание: Даже если вы не используете шифрование сессий, вы должны установить шифрующий ключ в вашем конфигурационном файле, который будет использоваться для предотвращения манипуляций с данными сессии.
Инициализация сессии
Сессии обычно запускаются глобально при каждой загрузке страницы, поэтому класс сессий должен инициализироваться в конструкторе вашего контроллера или загружаться автоматически системой. По большей части класс Session будет работать в фоновом режиме, поэтому простая инициализация класса заставит его читать, создавать и обновлять сессии.
Для того, чтобы инициализировать класс Session вручную в вашем контроллере, используйте функцию $this->load->library:
$this->load->library('session');
Загруженная библиотека Sessions будет доступна как $this->session
Как работают сессии?
Когда страница загружается, класс Session проверяет наличие правильных данных сессии, присутствующие в пользовательской куке. Если данные сессии не существуют (или если время сессии истекло), новая сессия будет создана и сохранена в куки. Если сессия существует, ее информация и кука будут обновлены. С каждым обновлением session_id будет перегенерирован.
Важно понимать, что класс Session после инициализации работает автоматически. Вы можете работать с данными сессии, или добавлять собственные данные в пользовательскую сессию, но процедуры чтения, записи и обновления сессии происходят автоматически.
Что такое данные сессии?
Сессия, в понимании CodeIgniter, это просто массив, содержащий следующую информацию:
- Уникальный идентификатор пользователя (случайная строка с очень высокой энтропией, хешированная в MD5 для совместимости, и перегенерируемая по умолчанию каждые 5 минут).
- IP-адрес пользователя
- Данные User Agent (первые 50 символов строки, которой представляется браузер)
- Timestamp "последней активности" (timestamp — время в формате unix time).
Данные выше сохраняются в куки в виде сериализованного массива по этому прототипу:
[array]
(
'session_id' => random hash,
'ip_address' => 'string — user IP address',
'user_agent' => 'string — user agent data',
'last_activity' => timestamp
)
Если вы включили опцию шифрования, сериализованный массив будет зашифрован перед сохранением в куки, что делает данные более безопасными и устойчивыми к несанкционированному чтению. Больше информации, касаемо шифрования можно найти здесь, хотя класс Session будет заботиться об инициализации и шифровании данных автоматически.
Примечание: куки сессии по умолчанию обновляются каждые пять минут для того, чтобы снизить нагрузку на процессор. Если вы перезагружаете страницу чаще, вы можете заметить, что время "последней активности" обновляется каждые пять минут или реже, с момента, как записана кука. Это время конфигурируется изменением параметра $config['sess_time_to_update'] в вашем system/config/config.php file.
Получение данных сессии
Элементы массива сессии доступны к использованию через следующую функцию:
$this->session->userdata('item');
Где item - это индекс массива, соответствующий элементу, который вы хотите получить. Например, для того, чтобы получить ID сессии, используйте:
$session_id = $this->session->userdata('session_id');
Примечание: функция возвращает FALSE, если элемент не существует.
Добавление пользовательских данных в сессию
Полезный аспект массива сессии - это то, что вы можете добавлять собственные данные в него, и они будут сохраняться в пользовательской куке. Почему вы захотите сделать это? Вот один пример:
Давайте предположим, что некоторый пользователь залогинился на вашем сайте. Авторизовавшись, вы должны сообщить - добавить его имя и адрес почты в куку сессии, чтобы сделать эти данные глобально доступными без дополнительного запроса в базу данных.
Для того, чтобы добавить ваши данные в массив сессии, передайте массив, содержащий данные, в эту функцию:
$this->session->set_userdata($array);
Где $array - это ассоциативный массив, содержащий ваши новые данные. Вот пример:
$newdata = array(
'username' => 'johndoe',
'email' => 'johndoe@some-site.com',
'logged_in' => TRUE
);
$this->session->set_userdata($newdata);
Если вы хотите добавлять по одному значению, set_userdata() также поддерживает такой синтаксис.
$this->session->set_userdata('some_name', 'some_value');
Примечание: Куки могут содержать не более 4KB данных, поэтому будьте осторожны, чтобы не превысить допустимую емкость. Процесс кодирования обычно увеличивает длину данных, поэтому вы должны позаботиться о количестве сохраняемых данных.
Удаление данных сессии
Также, как и set_userdata() добавляет информацию в сессию, unset_userdata() будет удалять их, через ключ сессии. Например, если вы хотите удалить 'some_name' из информации в вашей сессии:
$this->session->unset_userdata('some_name');
Эта функция также может принимать ассоциативный массив элементов, которые надо удалить.
$array_items = array('username' => '', 'email' => '');
$this->session->unset_userdata($array_items);
Flashdata
CodeIgniter поддерживает "flashdata" — это данные сессии, которые будут доступны только при следующем запросе, а потом автоматически удалены. Это очень полезно и обычно используется для информации или статусных сообщений (например: "запись 2 удалена").
Примечание: Переменные Flash предваряются префиксом "flash_", поэтому избегайте этого префикса в ваших собственных именах.
Чтобы добавить flashdata:
$this->session->set_flashdata('item', 'value');
Также вы можете передать массив функции set_flashdata(), также, как и set_userdata().
Чтобы прочесть переменную flashdata:
$this->session->flashdata('item');
Если вы сочли необходимым сохранить данные flashdata для следующего запроса, вы можете сделать это, используя функцию keep_flashdata().
$this->session->keep_flashdata('item');
Сохранение данных сессии в базе данных
Хотя массив сессии данных, хранящихся в куки пользователя, содержит ID сессии, если вы храните данные сессии в базе данных, не существует способа, чтобы проверить его. Для некоторых приложений, которые практически не требуют безопасности, проверка идентификатора сессии, возможно, не необходима. Но если ваше приложение требует безопасности, проверка является обязательной. В противном случае, старые сессии могут быть восстановлены пользователем через изменение собственных кук.
Когда данные сессии сохраняются в базе данных, каждый раз, когда обнаруживается правильная сессия в пользовательской куки, выполняется запрос в базу данных в поисках соответствующей записи. Если ID сессии не найден, сессия уничтожается. ID сессии не может быть обновлен, он может быть только генерирован при создании новой сессии.
Для того, чтобы сохранять данные сессий, сперва создайте таблицу в базе данных. Вот основной прототип таблицы (для MySQL), требуемый классом Session:
Примечание: По умолчанию таблица называется ci_sessions, но вы можете переименовать ее по своему усмотрению, в вашем application/config/config.php. После того, как вы создали таблицу в базе данных, вы можете включить опцию сохранения сессий в конфигурационном файле:
$config['sess_use_database'] = TRUE;
Теперь класс Session будет сохранять данные сессии в базе данных.
Убедитесь, что вы указали правильное имя таблицы в конфигурации:
$config['sess_table_name'] = 'ci_sessions';
Примечание: Класс Session самостоятельно вычищает мусор — истекшие сессии, поэтому, при его использовании вы не должны делать это самостоятельно.
Уничтожение сессии
Для того, чтобы очистить сессию, используйте:
$this->session->sess_destroy();
Примечание: Эта функция должна вызываться последней. После ее выполнения все переменные flashdata будут недоступны. Если вы хотите удалить только некоторые элементы, а не все, используйте unset_userdata().
Настройки сессии
Следующие параметры доступны в файле конфигурации application/config/config.php:
Параметр | По умолчанию | Опции | Описание |
---|---|---|---|
sess_cookie_name | ci_session | Нет | Имя сохраняемой куки сессии. |
sess_expiration | 7200 | Нет | Количество секунд, которые живет сессия. По умолчанию установлено 2 часа (7200 секунд). Если вы хотите, чтобы сессии не заканчивались, установите ноль: 0 |
sess_expire_on_close | FALSE | TRUE/FALSE (boolean) | Указывает, что сессия закрывается автоматически при закрытии браузера. |
sess_encrypt_cookie | FALSE | TRUE/FALSE (boolean) | Указывает, шифровать ли данные сессии. |
sess_use_database | FALSE | TRUE/FALSE (boolean) | Указывает, сохранять ли данные сессии в базу данных. Вы должны создать таблицу в базе данных перед использованием этой функции. |
sess_table_name | ci_sessions | Любое правильное имя таблицы базы данных | Имя таблицы базы данных для сохранения данных сессии. |
sess_time_to_update | 300 | Время в секундах | Опционально указывает, насколько часто класс Session должен регенерировать себя, и создать новый идентификатор сессии. |
sess_match_ip | FALSE | TRUE/FALSE (boolean) | Должен ли совпадать IP-адрес пользователя при чтении данных сессии. Учитывайте, что многие провайдеры динамически меняют IP-адреса пользователей, поэтому при использовании неистекающих сессий желательно установить этот параметр в FALSE. |
sess_match_useragent | TRUE | TRUE/FALSE (boolean) | Должен ли совпадать User Agent при чтении данных сессии. |