15

I am trying to set cookies to re-route returning users to my a specific page within my Wordpress site.

I'd like some advice with these 2 things:

  1. Where in the Wordpress php files should cookies be checked before loading any content to handle a redirect? Is there a good file this should exist in over others?
  2. How do I properly set a cookie within Wordpress? setcookie('cookie_name', 'cookie_value', time()+4000); doesn't seem to be saving any cookies to my system.
5
  • 1
    Ah, realized I needed to hook this into the init(). SOLUTION: I created a function in functions.php that would set and check the cookie. for this to work properly, after defining the function, outside the function call this: add_action('init', 'function-name');
    – Atticus
    Jul 2, 2011 at 4:07
  • 4
    You are allowed to answer your own question... Jul 2, 2011 at 4:12
  • 2
    In fact, it's explicitly encouraged. Please do answer it yourself. I'm also sending this to WordPress.SE, since it seems more appropriate there.
    – Michael Myers
    Jul 2, 2011 at 4:49
  • Thanks guys -- i did not realize there was a Wordpress area. And thanks for the tip to answer myself :) APpreciated, +1s.
    – Atticus
    Jul 5, 2011 at 4:34
  • Make sure you use the pre-baked cookie constants WordPress offers, check this article out for more info on how to set, get & delete cookies properly benmarshall.me/setting-cookies-in-wordpress Jul 31, 2020 at 2:20

5 Answers 5

20

1 - You can check for cookies and do your redirect using hooks that are called before any output like the 'init' hook:

<?php

// Hook the function "redirect()" on to the "init" action
add_action('init', 'redirect');

// redirect() may redirect the user depending on the cookies he has
function redirect(){
  /* CODE */
}

?>

2 - The best way to set cookies would be using the 'init' hook like this:

<?php

add_action('init', 'my_setcookie');

// my_setcookie() set the cookie on the domain and directory WP is installed on
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);
  /* more cookies */
  setcookie('my_cookie_name_2', 'my_cookie_value_2', $expiry, $path, $host);
}

?>

This is more consistent, if you have a blog at www.example.com/blog, the coockie(s) will not be available at

  • www.example.com
  • www.example.com/store
  • example.com
  • www2.example.com
  • ...

Update

you should also be able to use the COOKIE_PATH and COOKIEDOMAIN constants rather than figuring them out yourself, which I just noticed in Andre R Kohl's answer – drzaus

5
  • How you you put multiple varibles, for example Firstname, LastName, Random1, Random2 instead of just the 'my_cookie_1' variable.?
    – Damainman
    Oct 27, 2013 at 0:14
  • 1
    Just add more setcookie() Oct 27, 2013 at 0:33
  • Oh, I didn't know cookies only hold one variable per cookie. Is there a way to set multiple cookies without needing to have the time and url code above so that it amounts to less code? Would they be put into a variable?
    – Damainman
    Oct 27, 2013 at 0:34
  • 1
    you should also be able to use the COOKIEPATH and COOKIEDOMAIN constants rather than figuring them out yourself, which I just noticed in Andre R Kohl's answer
    – drzaus
    Dec 11, 2015 at 20:07
  • correction: COOKIE_DOMAIN
    – drzaus
    Dec 11, 2015 at 21:13
14

You probably should use the constants COOIKEPATH and COOKIE_DOMAIN, existing since WP 3.0

setcookie("your_cookie", $your_value, time()+3600, COOKIEPATH, COOKIE_DOMAIN);
7

Ah, realized I needed to hook this into the init().

SOLUTION: I created a function in functions.php that would set and check the cookie. for this to work properly, after defining the function, outside the function call this:

add_action('init', 'function-name'); 
1
  • this is not a solution, please add the full code of your function, furthermore hyphens in function names will not work.
    – Aurovrata
    Sep 11, 2020 at 8:36
1

This way worked :

    add_action( 'init', 'function-to-setcookie' ); 

    function function-to-setcookie(){

        //use condition here , in which page you eant to set cookie
        //choose a page where you want the cookie to be set
        $pageurl = get_option('siteurl').'/set-cookie-page'; 

       // use a function to get current page url and use condition 
       //to match it with the desired page where you want to set cookie 
       if ( $pageurl === current_page_url() ) {
           setcookie( 'cookie_name', 'cookie_value', $expiryTime, $cookiepath, $siteurl );
         }

    }
3
  • 1
    Please fix your code formatting.
    – Jevuska
    May 27, 2016 at 8:53
  • Also a small content about the source is really helpful.
    – bueltge
    May 27, 2016 at 10:40
  • 1
    Dashes in function names definitely won't work.
    – alpipego
    Apr 10, 2020 at 4:03
1

You will want to delete your cookie before any content is written to the page (before headers are sent).

To set the cookie, include the path, domain, and I also recommend setting the last 2 parameters to true ($secure and $httponly). You will also need to supply the same parameters to setcookie() when deleting, aside from the $expiry (which should be negative) and the $value (which should be empty '').

If you are passing json through the cookie, it seems like you need to base64_encode it as well, or it won't properly decode.

All of this should be done in a class so you can access the value of the cookie later on in your code. The class can be added to a plugin or functions.php.

Here is an example where we use a cookie to store an action response to then display it to the user after we redirect them:

class my_custom_class {

    const MY_COOKIE_NAME_JSON = 'my_cookie_name_json';
    const COOKIE_LIFETIME = 3600;

    private $cookie_value;

    function __construct() {
        // ensure you are deleting cookie before headers are sent
        add_action('init', [$this, 'process_cookie_json'], 10);
        // uses bootstrap alert to format return message
        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;

You can then set the cookie via:

my_custom_class::some_action_that_sets_the_cookie('the message');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.