KodeFor.Me
KodeFor.Me

Reputation: 13511

PHP Cookie, is that wrong?

I try to create a WordPress plugin, that can hold an ID in a cookie and I use the following code:

$cookie_value = $this->unique_id();

if ( ! isset( $_COOKIE['iwc'] ) ) {
    setcookie( 'iwc', $cookie_value, DAY_IN_SECONDS * 30 );
} else {
    $cookie_value = $_COOKIE['iwc'];
}

but when I refresh my site, and go in my console under the Resources tab, the cookie does not appear, or can be anything wrong that I don't consider as wrong right now ?

Do you see anything wrong with this code that I don't see ?

If I print_r the $_COOKIE before the if statement I get the following result:

Array
(
    [wordpress_logged_in_87b1a17cb008ee1e12b7ec6e4e541675] => merianos|1442410181|Ddk8wElp9avfkeNXUXdcgiOnyYNNXsGLIXh8STtt0KZ|cb06a47b07c47c358799d51e7e63af1a4385badb17577f2638916c47f58cde17
    [wordpress_sec_2a5b5b648d80646a801feae602295c7a] => merianos|1442487966|3M9DcmRZifiL1e23B6iVN8vypxUTDYtZCtut75XmTJh|87e1b80dc84d4c21cebab68ea284900e53310d6d747be7db9ad756de7c7c3b73
    [wordpress_logged_in_2a5b5b648d80646a801feae602295c7a] => merianos|1442487966|3M9DcmRZifiL1e23B6iVN8vypxUTDYtZCtut75XmTJh|0a8b402565762e23c6c3cba6e34795370d25b00af393881635fba0c520f5cfc9
    [wp-settings-time-1] => 1441357608
)

and if I print it out after the cookie set I get this:

Array
(
    [wordpress_logged_in_87b1a17cb008ee1e12b7ec6e4e541675] => merianos|1442410181|Ddk8wElp9avfkeNXUXdcgiOnyYNNXsGLIXh8STtt0KZ|cb06a47b07c47c358799d51e7e63af1a4385badb17577f2638916c47f58cde17
    [wordpress_sec_2a5b5b648d80646a801feae602295c7a] => merianos|1442487966|3M9DcmRZifiL1e23B6iVN8vypxUTDYtZCtut75XmTJh|87e1b80dc84d4c21cebab68ea284900e53310d6d747be7db9ad756de7c7c3b73
    [wordpress_logged_in_2a5b5b648d80646a801feae602295c7a] => merianos|1442487966|3M9DcmRZifiL1e23B6iVN8vypxUTDYtZCtut75XmTJh|0a8b402565762e23c6c3cba6e34795370d25b00af393881635fba0c520f5cfc9
    [wp-settings-time-1] => 1441359132
)

In addition, I have try the following in the main file of my plugin and still doesn't work:

function c() {
    setcookie('iwc', 'nikos', DAY_IN_SECONDS * 30, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN, is_ssl(), false);
}
add_action( 'init', 'c' );

Finally I try the following code directly in my plugin main file and still the cookie doesn't set:

setcookie('iwc', 'nikos', DAY_IN_SECONDS * 30, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN, is_ssl(), false);

Upvotes: 0

Views: 123

Answers (2)

axiac
axiac

Reputation: 72256

An excerpt from the setcookie() documentation:

expire

The time the cookie expires. This is a Unix timestamp so is in number of seconds since the epoch. In other words, you'll most likely set this with the time() function plus the number of seconds before you want it to expire. Or you might use mktime(). time()+60*60*24*30 will set the cookie to expire in 30 days. If set to 0, or omitted, the cookie will expire at the end of the session (when the browser closes).

In plain English, the argument $expire is not the life time of the cookie, as you tried to set it, but the absolute moment in time when the cookie expires.

As the documentation explains, you can/should use the result returned by time() and add the desired cookie life time (in seconds) to it.

The correct code is:

setcookie('iwc', $cookie_value, time() + DAY_IN_SECONDS * 30, '/');

Of course, you should not forget to set the correct path (/ or another one) where you want your cookie to be used (as indicated by Mike Vranckx int his answer).

Why your code doesn't work?

It works, but it does a different thing. You pass "30 days" on the $expire argument to setcookie() and that means "30 days after Jan 1, 1970 0:00", i.e. a date in the past. PHP generates and sends the correct Set-Cookie header and the browser, because of the date in the past, understands that it has to remove any cookie it has with name iwc for the matching path and domain.

You can see the response received from the server in the Network tab of the Developers Tool and you can see the Set-Cookie header is present and it has a date in the past on the expires field.

Upvotes: 2

Mike Vranckx
Mike Vranckx

Reputation: 5577

Code looks correct, but currently you are setting a cookie for the current path, not for the global website.

You should need to set it like this, by passing / as path argument, if you want it to be global

setcookie( 'iwc', $cookie_value, DAY_IN_SECONDS * 30, '/' );

Upvotes: 1

Related Questions