Как правильно подключить session_start() при создании плагина WordPress?
Изучая работу с сессиями, я выяснил, что session_start()
должен идти сразу после <?php
, согласно Где именно размещать SESSION_START?. Я хотел создать плагин, который добавлял бы session_start()
в header.php
после открывающего тега <?php
, но после поиска я не смог точно определить правильный способ сделать это.
Я искал информацию по сессиям, но в разных вопросах и ответах встречаются разные подходы, в основном используют:
init
: Сессия не начинаетсяwp_head
: Подключение к wp_head(); в плагинеwp_loaded
: Получение ошибки headers already sent от плагина
Итак, при создании плагина, который использует сессии и должен добавлять их в header.php, какой хук наиболее подходит для добавления session_start()
?

Обычного вывода нет, и, следовательно, заголовки не отправляются до хука template_redirect
на фронтенде. Если вам нужны сессии и в бэкенде, используйте действие wp_loaded
, чтобы охватить оба случая.
Пример:
add_action( 'template_redirect', function() {
$status = session_status();
if ( PHP_SESSION_DISABLED === $status ) {
// Вот почему нельзя полагаться на сессии!
return;
}
if ( PHP_SESSION_NONE === $status ) {
session_start();
}
$_SESSION[ 'foo' ] = 'bar';
});
Помните, что использование сессий добавляет целый набор очень сложных проблем в ваш код, включая вопросы безопасности, масштабируемости (балансировщики нагрузки) и последующие трудоемкие вопросы поддержки. Я не рекомендую их использовать.

Хорошо, если сессии работают плохо, я думаю, стоит посмотреть на PHP-функцию 'set_cookie()'. Полагаю, здесь можно применить такой же подход, как у вас - использовать 'template_redirect' или 'wp_loaded'?

Я нашел этот небольшой документ весьма информативным, по крайней мере в части проблем с сессиями в WordPress: https://pressjitsu.com/blog/wordpress-sessions-performance/

Вот еще одно решение, которое подходит для всех версий PHP, и вы можете найти его в плагине CF Geo:
if (version_compare(PHP_VERSION, '7.0.0') >= 0) {
if(function_exists('session_status') && session_status() == PHP_SESSION_NONE) {
session_start(array(
'cache_limiter' => 'private_no_expire',
'read_and_close' => false,
));
}
}
else if (version_compare(PHP_VERSION, '5.4.0') >= 0)
{
if (function_exists('session_status') && session_status() == PHP_SESSION_NONE) {
session_cache_limiter('private_no_expire');
session_start();
}
}
else
{
if(session_id() == '') {
if(version_compare(PHP_VERSION, '4.0.0') >= 0){
session_cache_limiter('private_no_expire');
}
session_start();
}
}
С этим решением вы можете избежать любых проблем с сессиями и запускать их в любое время, когда это необходимо.

Мы можем использовать простой способ через хук init. Добавьте эту функцию в файл function.php
function register_my_session() {
if( !session_id() )
session_start();
}
add_action('init', 'register_my_session');
После добавления этой функции в function.php вы можете устанавливать значения в сессии, например:
$_SESSION['user_country'] = 'india';
Получить значение из сессии:
echo $_SESSION['user_country'];
Для удаления значения из сессии:
unset($_SESSION["user_country"]);
