Why does PHP setcookie work on localhost but not in the browser?

I’ve created a cookie for my website to store the user’s language choice. It works fine on localhost. But after uploading the website to my webspace, the cookie doesn’t get set by any browser I tested (Firefox, Chrome and Opera, each via dev tools). I made sure these browsers accept cookies.

The cookie gets set before any html , before the DOCTYPE opening tag. There are only some PHP variable declarations above it. The cookie expires after 24h. Setting a longer expiration date didn’t help, either.
I also tested to replace '/' in the cookie path with my URL, like ('mysite.de') , which had no effect.

Some info on the server: it’s hosted by my webspace provider, not myself. The webspace where I upload files for testing does not have SSL, but for publishing I always use it. The cookie doesn’t get set in either case (I tried with and without SSL).

I tried to use only setcookie('language', 'lang-en', time() + 86400, '/', $_SERVER['HTTP_HOST']);. This does set the cookie when run by the server.

Next, I made a php file with only the code necessary to place the cookie, as follows:

  <?php
    // i18n language class setup
    require_once 'i18n.class.php';
    $i18n = new i18n('lang/lang_{LANGUAGE}.ini', 'langcache/', 'de');

    $i18n->setForcedLang('de'); // DE = default language

    // get language cookie
    if (isset($_COOKIE['language']) && $_COOKIE['language']== "lang-de") {
      echo " got German cookie! ";
      $i18n->setForcedLang('de');
    } elseif (isset($_COOKIE['language']) && $_COOKIE['language']== "lang-en") {
      echo " got English cookie! ";
      $i18n->setForcedLang('en');
    } else {
      echo " got no cookie ";
    }

    // language buttons & set cookie
    if(isset($_GET['lang'])) {

      echo " - GET_lang is: " . $_GET['lang'] . " - ";

      $lang=$_GET['lang'];

      if ($lang == 'de') {
        $i18n->setForcedLang('de');
        echo " button clicked: german language set, forced language set: DE - setcookie should happen here... - ";
        setcookie('language', 'lang-de', time() + 86400, '/', $_SERVER['HTTP_HOST']);
      }
      if ($lang == 'en') {
        $i18n->setForcedLang('en');
        echo " button clicked: english language set, forced language set: EN - setcookie should happen here... - ";
        setcookie('language', 'lang-en', time() + 86400, '/', $_SERVER['HTTP_HOST']);
      }
    }

    // init object: load language files, parse them if not cached, and so on.
    $i18n->init();
    ?>

    <!DOCTYPE html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
      <meta http-equiv="x-ua-compatible" content="ie=edge">
    </head>
      <body>
            <div class="language">
              <a href="?lang=de" name="lang-de" class="lang-de">DE</a>/
              <a href="?lang=en" name="lang-en" class="lang-en">EN</a>
            </div>
      </body>
    </html>

On localhost, this code returns e.g.:
got English cookie! - GET_lang is: en - button clicked: english language set, forced language set: EN -
After uploading it to the server, it returns e.g. (always “got no cookie”):
got no cookie - GET_lang is: en - button clicked: english language set, forced language set: EN -

Why does my code work fine on localhost, but not on the web server?

Help on what is going wrong here is much appreciated. I’m really stuck on how to make this work. Thanks!

EDIT:
This is mocking me :confounded: It worked on the server! Now it’s suddenly not working anymore…

Well, that is not a very secure way to handle this. Cookies can be copied, changed or deleted. So, not stable. Normally, you would do this in the user’s profile page and keep it with their other data.

But, try replacing the $_SERVER['HTTP_HOST'] with the actual domain name. Depending on the server, you might need www.zyx.com or just zyx.com… On a local test system using Wamp, Lamp or Xamp or other server software, the value would be “localhost” for this section. On a server it must be the actual domain name. Remove the www. prefix if you have sub-domains.

Also, I would test it in one page without the additional libraries. Just a couple lines, one to set it, one to read it. You can view the entire cookie’s info. Just use this:

<?PHP
setcookie('language', 'lang-en', time() + 96400, '/', 'your-domain.de');    //  change to your domain
print_r($_COOKIE)
?>

Then, put on your server and view in a browser and see what is going on…

Sponsor our Newsletter | Privacy Policy | Terms of Service