Установка пользовательских cookies в WordPress
Я пытаюсь установить cookies для перенаправления вернувшихся пользователей на определенную страницу моего сайта WordPress.
Мне нужен совет по двум вопросам:
- В каких PHP файлах WordPress следует проверять cookies перед загрузкой контента для выполнения перенаправления? Есть ли более предпочтительный файл для этого?
- Как правильно установить cookie в WordPress?
setcookie('cookie_name', 'cookie_value', time()+4000);
похоже не сохраняет никакие cookies в моей системе.
1 - Вы можете проверять наличие куки и выполнять переадресацию, используя хуки, которые вызываются до любого вывода, например, хук 'init':
<?php
// Подключаем функцию "redirect()" к действию "init"
add_action('init', 'redirect');
// Функция redirect() может перенаправить пользователя в зависимости от его куки
function redirect(){
/* КОД */
}
?>
2 - Лучший способ установки куки — использование хука 'init' следующим образом:
<?php
add_action('init', 'my_setcookie');
// Функция my_setcookie() устанавливает куки в домене и директории, где установлен WordPress
function my_setcookie(){
$path = parse_url(get_option('siteurl'), PHP_URL_PATH);
$host = parse_url(get_option('siteurl'), PHP_URL_HOST);
$expiry = strtotime('+1 month');
setcookie('my_cookie_name_1', 'my_cookie_value_1', $expiry, $path, $host);
/* дополнительные куки */
setcookie('my_cookie_name_2', 'my_cookie_value_2', $expiry, $path, $host);
}
?>
Это более согласованный подход. Если ваш блог находится по адресу www.example.com/blog, куки не будут доступны на:
- www.example.com
- www.example.com/store
- example.com
- www2.example.com
- ...
Обновление
Вы также можете использовать константы COOKIE_PATH и COOKIEDOMAIN вместо самостоятельного их определения, что я только что заметил в ответе Andre R Kohl – drzaus

Как можно добавить несколько переменных, например, Firstname, LastName, Random1, Random2 вместо одной переменной 'my_cookie_1'?

О, я не знал, что в одной cookie можно хранить только одну переменную. Есть ли способ устанавливать несколько cookie без необходимости каждый раз указывать время и URL-код, чтобы уменьшить объем кода? Можно ли их поместить в переменную?

вы также можете использовать константы COOKIEPATH
и COOKIEDOMAIN
вместо того, чтобы определять их самостоятельно, что я только что заметил в ответе Andre R Kohl

исправление: COOKIE_DOMAIN

Этот способ сработал:
add_action( 'init', 'function-to-setcookie' );
function function-to-setcookie(){
//используйте условие здесь, на какой странице вы хотите установить куки
//выберите страницу, на которой должно быть установлено куки
$pageurl = get_option('siteurl').'/set-cookie-page';
// используйте функцию для получения текущего URL страницы и примените условие
//для сопоставления с нужной страницей, где должно быть установлено куки
if ( $pageurl === current_page_url() ) {
setcookie( 'cookie_name', 'cookie_value', $expiryTime, $cookiepath, $siteurl );
}
}

Вам нужно удалить cookie до того, как любой контент будет записан на страницу (до отправки заголовков).
Для установки cookie укажите путь, домен, а также я рекомендую установить последние 2 параметра в true ($secure
и $httponly
). Также при удалении cookie вам нужно будет передать те же параметры в setcookie()
, за исключением $expiry
(который должен быть отрицательным) и $value
(который должен быть пустой строкой '').
Если вы передаете JSON через cookie, похоже, что его также нужно закодировать с помощью base64_encode
, иначе он не будет правильно декодирован.
Все это должно быть реализовано в классе, чтобы вы могли получить значение cookie позже в вашем коде. Класс можно добавить в плагин или functions.php.
Вот пример, где мы используем cookie для хранения ответа действия, чтобы затем отобразить его пользователю после перенаправления:
class my_custom_class {
const MY_COOKIE_NAME_JSON = 'my_cookie_name_json';
const COOKIE_LIFETIME = 3600;
private $cookie_value;
function __construct() {
// убедитесь, что cookie удаляется до отправки заголовков
add_action('init', [$this, 'process_cookie_json'], 10);
// использует bootstrap alert для форматирования сообщения
add_filter('the_content', [$this, 'filter_the_content_in_the_main_loop'], 1);
}
static function some_action_that_sets_the_cookie($message, $response_type = 'success') {
$responses = [];
if (isset($_COOKIE[self::MY_COOKIE_NAME_JSON]))
$responses = json_decode(base64_decode($_COOKIE[self::MY_COOKIE_NAME_JSON]));
$responses[$response_type][] = $message;
self::set_cookie_json($responses);
}
static function set_cookie_json(array $cookie_value) {
setcookie(self::MY_COOKIE_NAME_JSON, base64_encode(json_encode($cookie_value)), time() + self::COOKIE_LIFETIME, "/", $_SERVER['HTTP_HOST'], true, true);
}
function process_cookie_json() {
if (!isset($_COOKIE[self::MY_COOKIE_NAME_JSON]))
return false;
$this->cookie_value = json_decode(base64_decode($_COOKIE[self::MY_COOKIE_NAME_JSON]), true);
setcookie(self::MY_COOKIE_NAME_JSON, '', -1, "/", $_SERVER['HTTP_HOST'], true, true);
unset($_COOKIE[self::MY_COOKIE_NAME_JSON]);
}
function filter_the_content_in_the_main_loop($content) {
if (!$this->cookie_value || !is_array($this->cookie_value))
return $content;
$alerts = [];
foreach ($this->cookie_value as $response_type => $messages)
$alerts[] = '<div class="alert alert-' . $response_type . '" role="alert">' . implode(PHP_EOL, $messages) . '</div>';
return implode(null, $alerts) . $content;
}
}
$my_custom_class = my_custom_class;
Затем вы можете установить cookie с помощью:
my_custom_class::some_action_that_sets_the_cookie('сообщение');
