14

I have this page that sets a cookie and echos out a string if you check a checkbox. The string prints correctly, but the cookie never gets set and I have no idea why.

<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<label for="checkbox">Option 1:</label>
<input type="checkbox" name="checkbox" id="checkbox"><br>
<input type="submit" name="submit" value="Submit">
</form>
  <?php
if (isset($_POST['checkbox'])) {
  setcookie("cookie", "on", time()+3600*24);
  echo "You checked the checkbox and a cookie was set with a value of:<br>";
}
else {
  setcookie("cookie", "off", time()+3600*24);
  echo "You didn't check the checkbox and a cookie was set with a value of:<br>";
}
echo $_COOKIE['cookie'];
  ?>

Does anyone know why the above code does not work?

Tim
  • 2,123
  • 4
  • 27
  • 44

4 Answers4

19

PHP superglobals are populated at script start-up time, and then are NOT modified or touched by PHP again for the life of the script. That means $_COOKIE represents the cookies that were sent to the server in the http request that fired up the script. It will NOT show any cookies you've added/changed/deleted during the life of the script. Those changes will only show up on the NEXT request.

The only exception to this is $_SESSION, which is populated when you call session_start().

If you need those values to be in $_COOKIE immediately, you'll have to add them manually, e.g.

setcookie('cookie', $value, ....);
$_COOKIE['cookie'] = $value;
Marc B
  • 356,200
  • 43
  • 426
  • 500
15

According to the PHP Manual at http://php.net/manual/en/function.setcookie.php:

If output exists prior to calling this function, setcookie() will fail and return FALSE. If setcookie() successfully runs, it will return TRUE. This does not indicate whether the user accepted the cookie.

In other words, the function setcookie() is not working because it is inside the page. If you want it to work, you will need to put that function before the page, specifically before any headers.

Do this:

<?php
  if ( isset($_POST['checkbox']) ) {
     setcookie("cookie", "on", time()+3600*24);
     echo "You checked the checkbox and a cookie was set with a value of:<br>";
  } else {
     setcookie("cookie", "off", time()+3600*24);
     echo "You didn't check the checkbox and a cookie was set with a value of:<br>";
  }

  echo $_COOKIE['cookie'];
?>
<!doctype html>
<html>
  <head>...</head>
  <body>
      <form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
         <label for="checkbox">Option 1:</label>
         <input type="checkbox" name="checkbox" id="checkbox"><br>
         <input type="submit" name="submit" value="Submit">
      </form>
  </body>
</html>
JDot
  • 194
  • 2
  • 10
  • This is the correct answer. The question asked by Tim was "set cookie not working", and not "cannot access $_COOKIE value": the code given by Tim still won't work with the " $_COOKIE['cookie'] = $value; " trick suggested by Marc B. – Dugh Dec 16 '16 at 08:25
4

Cookies don't kick in until after they are set and a new page request is sent. This is because cookies are sent with page requests, they just don't magically appear to a the server.

Your solution is to do a page refresh after setting the cookie.

// set cookie
setcookie("cookie", "off", time()+3600*24);
// not available because this cookie was not sent with the page request.
echo $_COOKIE['cookie'];
John Conde
  • 217,595
  • 99
  • 455
  • 496
  • How would I do a page refresh after setting the cookie? I don't think page refreshes can be done with php... Would I use `header` to redirect to the same page or use javascript? – Tim Jul 09 '14 at 19:55
  • You would use `header()` since you would do the redirect from the server. – John Conde Jul 09 '14 at 19:58
0

Recently I also faced that issue. Finally got right solution. Actually the third param should be getter then current time. use like following:

$my_time = 100; //It's in second
setcookie($cookine_name, $cookine_value, time() + $my_time);

This will work obviously.

Saiful Islam
  • 332
  • 6
  • 15