2

From my web page I want to write (async via ajax) to an SQL table, using a generated value as a unique key. Later (could be 1 minute or 1 day, but within the same browser session) from another page, I want to be able to update that SQL record. I could pass the key value in the url but prefer to use session variables. To avoid the possibility that another web page destroys the session I am trying to use a custom cookie (not PHPSESSID), but the session variables aren't updating.

To simplify, I took the code out of ajax and ran it direct from my browser. There are no errors or messages.

Here are the two pieces of code: page1.php


    <?php
    if(isset($_COOKIE["gcpp_imp"])){$impressionId=$_COOKIE["gcpp_imp"];}
    else{$impressionId="Imp".substr(microtime(),11,11).substr(microtime(),1,7);
    setcookie("gcpp_imp", $impressionId, 0, "/");}
    session_name("gcpp_imp");
    session_id($impressionId);
    session_start();
    $_SESSION["Test"] = "Hello";
    if(isset($_SESSION["Number"])){
        $_SESSION["Number"] = $_SESSION["Number"]+1;
    }
    else{
        $_SESSION["Number"] = 1;
    }
    echo "PAGE 1<br>";
    echo "session_save_path = ".session_save_path()."<br>";
    if (is_writable(session_save_path())) {
        echo "Session path '".session_save_path()."' is writable for PHP!<br>"; 
    }
    else {
        echo "Session path '".session_save_path()."' is not writable for PHP!<br>"; 
    }
    echo "session_name = ".session_name()."<br>";
    echo "session_id = ".session_id()."<br>";
    echo "session_status = ".session_status()."<br>";
    echo "session_Test = ".$_SESSION["Test"]."<br>";
    echo "session_Number = ".$_SESSION["Number"]."<br>";
    ?>

and page2.php


    <?php
    session_name("gcpp_imp");
    session_id($_COOKIE["gcpp_imp"]);
    session_start();
    echo "PAGE 2<br>";
    echo "session_save_path = ".session_save_path()."<br>";
    if (is_writable(session_save_path())) {
        echo "Session path '".session_save_path()."' is writable for PHP!<br>"; 
    }
    else {
        echo "Session path '".session_save_path()."' is not writable for PHP!<br>"; 
    }
    echo "session_name = ".session_name()."<br>";
    echo "session_id = ".session_id()."<br>";
    echo "session_status = ".session_status()."<br>";
    echo "session_Test = ".$_SESSION["Test"]."<br>";
    echo "session_Number = ".$_SESSION["Number"]."<br>";
    ?>

Output from page1.php

PAGE 1
session_save_path = /var/cpanel/php/sessions/ea-php56
Session path '/var/cpanel/php/sessions/ea-php56' is writable for PHP!
session_name = gcpp_imp
session_id = Imp1568485583.309708
session_status = 2
session_Test = Hello
session_Number = 1

Output from page2.php

PAGE 2
session_save_path = /var/cpanel/php/sessions/ea-php56
Session path '/var/cpanel/php/sessions/ea-php56' is writable for PHP!
session_name = gcpp_imp
session_id = Imp1568485583.309708
session_status = 2
session_Test =
session_Number =

The pages are both run from https, with no subdomain, from the same folder. My server is a VPS shared hosting at Hostiso, running PHP Version 5.6.40.

phpinfo.php shows session.gc_divisor = 0, session.gc_maxlifetime = 2880 (I will want to increase this) and session.gc_probability = 0.

When I refresh page1.php the output stays the same. So the cookie gcpp_imp is being set once and once only, the key/session_id $impressionId is being generated once and once only, and I can see the cookie and value in my browser. But $_SESSION["Number"] is not being updated in page1.php and neither session variable is being displayed in page2.php.

What am I missing?

Markus Zeller
  • 8,516
  • 2
  • 29
  • 35
Nitram
  • 49
  • 7
  • 2
    *"First question asked - please be gentle!"* ... Ignore the votes :) this is SO. Regarding your queestion, *"I will want to increase this"* .... I think you answered your own question, if I got it right, check this [how-to-change-the-session-timeout-in-php](https://stackoverflow.com/questions/8311320/how-to-change-the-session-timeout-in-php) – Accountant م Sep 14 '19 at 20:27
  • @Accountant I will want to increase session.gc_maxlifetime in production, but for my test 48 minutes is more than enough. –  Nitram Sep 14 '19 at 20:53

2 Answers2

1

change the position of session_start(); it should be the first line any of your pages.

page 1

      session_start();   <-----
      session_name("gcpp_imp");
      session_id($impressionId);

page 2

       session_start();   <-----
      session_name("gcpp_imp");
      session_id($_COOKIE["gcpp_imp"]);
eladcm
  • 574
  • 6
  • 11
  • 1
    session_start(); needs to be before any HTML output, but it does not need to be the very first line of code. Specifically, if I want to set session_name and session_id I need to do this before the session_start(); - see PHP manual https://www.php.net/manual/en/function.session-id.php –  Nitram Sep 14 '19 at 20:58
  • have a look in the docs link you posted : Note: When using session cookies, specifying an id for session_id() will always send a new cookie when session_start() is called, regardless if the current session id is identical to the one being set. your cookie is being rewrite ... – eladcm Sep 14 '19 at 21:04
  • The answer is there in the link I posted, but it's not that. Thanks for pointing me in that direction - please see my answer to my own question. –  Nitram Sep 14 '19 at 21:22
1

The answer is that "the file session handler only allows characters in the range a-z A-Z 0-9 , (comma) and - (minus)!": see https://www.php.net/manual/en/function.session-id.php I was generating my session_id() with $impressionId="Imp".substr(microtime(),11,11).substr(microtime(),1,7) resulting in a string in the format Imp1568485583.309708 As soon as I removed the decimal point it worked!

I spent 3 days breaking my head over this, and as soon as I posted here I get the answer.

Nitram
  • 49
  • 7