1

I am maintaining the code for an eCommerce website, they use a highly modified version of osCommerce v2.2 RC2. Was noticing an issue where the session isn't started for a new user until they visit the 2nd page of the site.

Looking at the code, before starting the session, it tries to set a cookie. If it detects the cookie it starts the session. Something along this line:

setcookie('cookie_test', 'please_accept_for_session', time()+60*60*24*30, $cookie_path, $cookie_domain);

if (isset($_COOKIE['cookie_test'])) {
      session_start();
...

I found an article here that talks about a situation like this, it states:

The first time you only tell the browser to set the cookie, at the time, there is no cookie data in the request header (which could get from $_COOKIE).

Which explains why it takes two page loads for the session to be started. One to set the cookie and one to get notification from the browser that the cookie is set.

My question is, is there anyway around having to go through two page loads to detect the cookie was successfully set on the users browser?

I found this question that didn't really answer my question completely. The highest voted solution was:

setcookie('uname', $uname, time()+60*30);
$_COOKIE['uname'] = $uname;

Which may make it "work" but it doesn't truely tell me that the script was able to set a cookie successfully.

I also found this question, that suggested accessing the headers_list to find the cookie information like so:

function getcookie($name) {
    $cookies = [];
    $headers = headers_list();
    // see http://tools.ietf.org/html/rfc6265#section-4.1.1
    foreach($headers as $header) {
        if (strpos($header, 'Set-Cookie: ') === 0) {
            $value = str_replace('&', urlencode('&'), substr($header, 12));
            parse_str(current(explode(';', $value, 1)), $pair);
            $cookies = array_merge_recursive($cookies, $pair);
        }
    }
    return $cookies[$name];
}
// [...]
setcookie('uname', $uname, time() + 60 * 30);
echo "Cookie value: " . getcookie('uname');

Which, again, doesn't seem to be verifying that the cookie was set successfully. All this appears to do is search the headers being sent to the browser for the cookie value.

The only solution I can think of is to redirect on the first visit after setting the cookie. Is there any other way?

Community
  • 1
  • 1
peteb
  • 11
  • 1
  • 2
  • Start the session without any condition ...? If you need to, you can still check whether cookies are accepted later. – CBroe Nov 23 '16 at 20:36
  • I'm thinking that's my only choice. I've looked at JavaScript cookie validation but I don't like that method due to the fact that JavaScript can disabled. What surprises me is there doesn't seem to be any industry wide accepted methodology for this process. When designing a website and it's interactions, if you accept the current "accepted method" of validation, first visits always have to happen in two steps before validation can occur. What if you are sending someone to a page, for a referral for example, and you need to capture something to the session immediately? – peteb Dec 04 '16 at 14:05
  • Sessions can work without cookies (and as a default fallback, they usually do - until cookie support can be determined automatically.) – CBroe Dec 05 '16 at 08:38
  • Yes, I understand that Sessions can work without cookies, but, the code I am using persists the Sessions using cookies, cookies are required for me. I does seem like I just need to act as though cookies can be set and proceed accordingly. It's a chicken and the egg. – peteb Dec 06 '16 at 11:47
  • 1
    You need a second request to see if the cookie gets send back by the client. That second request does not necessarily mean that the user has to change to a second page; it could f.e. also be an AJAX request in the background. – CBroe Dec 06 '16 at 12:34

1 Answers1

0

Here is the answer:

<?php

function set_cookie($name, $value) {
    if (!isset($_COOKIE[$name]) || ($_COOKIE[$name] != $value)) {
        $_COOKIE[$name] = $value;
    }
    setcookie($name, $value, strtotime('+1 week'), '/');
}

// Usage:
set_cookie('username', 'ABC'); //Modify the value to see the change 

echo $_COOKIE['username'];
Long Pham
  • 1
  • 1