Setting custom cookies in WordPress

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.

Related posts

Leave a Reply

5 comments

  1. 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 http://www.example.com/blog, the coockie(s) will not be available at


    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

  2. 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);
    
  3. 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'); 
    
  4. 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 );
             }
    
        }
    
  5. 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');