How to keep PHP session persistent, with custom session ID? - php

Very simple experiment. I have an index.php which contains:
if ( !isset( $_SESSION ) ) {
session_id( random_string() );
session_start();
}
echo session_id();
random_string() simply returns a random 20 char A-Z,a-z,0-9 string.
On reloading this page it will ALWAYS generate a new session ID since there isn't a call to session_start() before that if statement, and the (resuming) $_SESSION super global doesn't exist.
However, if I put a call to session_start() at the top of the script I've lost my chance to specify a custom session ID, since setting a custom ID has to happen before the call to session_start().
I just can't figure this out. Chicken/egg problem. So, how do I successfully implement a custom session ID, which will keep the super global alive between page loads?

You can have your own customized session id throughout pages with the help of file system and database. I've written the following code to keep track of same session id through all the pages using file system method:
if(filesize('session_track.txt') === 0) {
file_put_contents('session_track.txt', random_string());
}
$session_id = file_get_contents('session_track.txt');
session_id($session_id);
session_start();
// Here is the conditional statement, in case you need to regenerate your custom session id again
$regenerate_custom_session_id = false; // if need, set it to true.
// This code depends on your requirements. I just mentioned this conditional statement for your understanding to make it logically work
if($regenerate_custom_session_id === true) {
file_put_contents('session_track.txt', '');
}
I'm not sure how efficient this code is. I've just shared my idea to make it work.

Related

PHP session, why is session_start() required multiple times?

I am writing a web application that saves POSTed data to a session in one page, then redirects to another page to utilize the created session information. This was after I read that the proper way to process data and display data is to separate them into two different scripts so as not to run into a redundant $_POST data issue. That is, not to keep $_POSTing the same data to the server every page refresh.
I have a view page, index.php, and a data processing page, setDate.php. When viewing index.php, the user can choose to set $_POST['month'] and $_POST['year'] variables via an input form, and submit them to setDate to assign $_SESSION['desMonth'] and $_SESSION['desYear'] respectively.
It wasn't until I added a second (IMO redundant) session_start(); declaration on setDate.php that the code started to work the way I wanted to. Without it, it was as if index.php was ignoring setDate.php's $_SESSION[*] modifications completely.
Why do I have to define this redundant session_start(); if I already started the session (and received the PHPSESSID cookie) on the initial index.php where the $_SESSION[*] data is being used?
Here are some working code snippets:
setDate.php
<?php
require_once 'jan.php';
session_start();
//get the requested month and years to view (iterative).
if(isset($_POST['nextMonth']) && filter_var($_POST['nextMonth'], FILTER_SANITIZE_NUMBER_INT)) { //this filter only allows +- and 0-9
$_SESSION['desMonth'] += sanitizeInput($_POST['nextMonth']);
if($_SESSION['desMonth'] > 12) {
$_SESSION['desMonth'] = $_SESSION['desMonth']-12;
$_SESSION['desYear'] += 1;
}
else if($_SESSION['desMonth'] < 1) {
$_SESSION['desMonth'] = 12;
$_SESSION['desYear'] -= 1;
}
}
//get the explicit month and years to view.
if(isset($_POST['month']) && filter_var($_POST['month'], FILTER_SANITIZE_NUMBER_INT)) {
$_SESSION['desMonth'] = sanitizeInput($_POST['month']);
echo "set month";
}
if(isset($_POST['year']) && filter_var($_POST['year'], FILTER_SANITIZE_NUMBER_INT)) {
$_SESSION['desYear'] = sanitizeInput($_POST['year']);
echo "set year";
}
echo $_SESSION['desMonth'];
echo $_SESSION['desYear'];
header("Location: /");
die();
?>
Truncated index.php
<?php
session_start();
require_once 'cellUpdater.php';
$timeForDateUse = mktime(1,1,10,$_SESSION['desMonth'],1,$_SESSION['desYear']); //this line is used for various formatting below.
...
Without the session_start(); declaration in setDate.php the $_SESSION[*] data will not be preserved. Why?
EDIT: Question answered, editing for imaginary internet points
From php.net:
session_start() creates a session or resumes the current one based on
a session identifier passed via a GET or POST request, or passed via a
cookie.
When session_start() is called or when a session auto starts, PHP will
call the open and read session save handlers.
In other words, session_start() does not only create a session when a session does not exists yet, but it also makes it possible for a script to access the current session. It gives read and write access to the $_SESSION variable.
Without session_start, the script cannot write or read from the session, the session is still there but it cannot be read or modified by the script. If you only want to give read access to a session you can call session_write_close(); to close the write access. This can be handy when you want multiple files to open the same session at the same time. When a script has write access it blocks the current session file, blocking all other scripts that want write access to the same session.
If you are lazy and always want a session to be active, you can write
php_flag session.auto_start 1
in a .htaccess file to enable the auto start of a session in php.

PHP session variable not accessible on another page

After trawling through other posts, I could not find the answer.
The problem is that when i create a custom session name, I am not able to access session variables on any other pages. How can I get this working with custom session variable?
Scenario A
Login page
after successful login, the following is called
function initiatenewsession($app, $userid){
$session_name = getuniquesessionid($app,$userid); // Set a custom session name
session_name($session_name);
session_start();
session_regenerate_id(true);
$_SESSION["loggeduserid"] = $user_id;
echo("1a)SESSION NAME[".session_name()."]");
echo("1b)logged user[".$_SESSION["loggeduserid"]."]");
}
Echo result
1a) SESSION NAME[myappsessionid6520150528184534]
1b) logged user[65]
Registration page (User clicks a link after logging in)
session_start();
echo("2a)SESSION NAME[".session_name()."]");
echo("2b)logged user[".$_SESSION["loggeduserid"]."]");
2a)SESSION NAME[PHPSESSID]
2b)logged user[]
Scenario B
Login page
after successful login, the following is called
function initiatenewsession($app, $userid){
session_start();
session_regenerate_id(true);
$_SESSION["loggeduserid"] = $user_id;
echo("1a)SESSION NAME[".session_name()."]");
echo("1b)logged user[".$_SESSION["loggeduserid"]."]");
}
Echo result
1a) SESSION NAME[PHPSESSID]
1b) logged user[65]
Registration page (User clicks a link after logging in)
session_start();
echo("2a)SESSION NAME[".session_name()."]");
echo("2b)logged user[".$_SESSION["loggeduserid"]."]");
2a)SESSION NAME[PHPSESSID]
2b)logged user[65]
As per my comment, when you do session_start(), php will check if you set a session name via session_name(), otherwise it'll use its default.
Session startup is basically like this, in php-ish pseudocode:
if (custom_session_name_was_set()) {
$session_name = get_custom_session_name();
} else {
$session_name = ini_get('session.name');
}
if (isset($_COOKIE[$session_name])) {
$id = $_COOKIE[$session_name];
} else {
$id = generate_new_random_id();
setcookie($session_name, $id);
}
$session_data = file_get_contents('/path/to/session/files/' . $id);
$_SESSION = unserialize($session_data);
For your first bit of code, you set a custom name, so that's the name that's used for the session cookie.
In your other code, you do NOT set a custom name, so php uses its default: PHPSESSID. Now you've got two sessions floating around, each with their own unique names, and their own different IDs, and their own separate data in $_SESSION.
If you're going to be using custom session names, you have do session_name($customName) EVERYWHERE you have session_start().
If using a custom session name you must call session_name().
You must call session_start() before headers_sent().
On servers with multiple PHP version support check phpversion() to ensure that the server did not decide to run the wrong version (and hence the wrong session_save_path()).

Using session variable to use info on different pages

i'm having a bit of a problem. I'm trying to set up a simple webpage with only three .php pages. I want a session variable $_SESSION['userID'] to be set when a user is logged in and I want the index page to show extra info if someone is logged in.
On index.php I want to show some info, if a user is logged in I want to show some extra info.
login.php - simple log in form.
login_exe.php - takes care of database connection and verification.
So this was my idea:
On index.php, check if session is started, if not: start.
<?php
if (!isset($_SESSION)) {
session_start();
echo "session started";
}
later on, check if $_SESSION['userID'] contains a value, if so: print a string
if($_SESSION['userID'] != null){
echo "User logged in";
}
On login_exe.php i've almost the same code:
<?php
if (!isset($_SESSION)) {
session_start();
echo "session started";
}
in verification function:
$_SESSION['userID'] = $data['userID'];
header("Location: index.php");
The problem is that a new session is started on every page. How can I fix this and only start the session once? Thanks in advance
You should just put session_start() on top of documents that using sessions. Say, if you have 5 .php files that using sessions, then put 5 times the session_start() on top of them.
This is because session_start() sends headers and headers must be sent before any output (for example, any echo or whitespace).
Then, you should use something like isset($_SESSION["foo"]) and not just the entire $_SESSION array, where foo is something you set previously.
If you dont want sessions at all or need to reset the entire array, just call session_destroy() which effectively destroy the current session. Use unset($_SESSION["foo"]) when you want to get rid of a key.
Finally, you might get weird cases where you cannot read session key you write at. In these cases check what is the path of sessions and if they're writeable, or change their path:
$path = session_save_path(); // what is the path
is_writable($path); // can i write to it?
session_save_path("my/new/path"); // change the darn path;
// put -even- before session_start()!
:)
glad i help
I think the PHP manuals are really good compared to ...ahm, so just read about session_start(). It says:
session_start() creates a session or resumes the current one (...)
so all you need is session_start() very early in your code. This must be executed on every request (maybe as include).
Your code checking the userId looks fine, one important hint here: you should know exactly what isset(), empty() and the like mean in PHP, so always have the comparision of comparison at hand.
You should not ask new answers (edit: questions) in comments. Be as systematic here as you are in coding.
How to end a session:
This gives room for discussion, because there is the session cookie, which is client side, and the session data, which is server side.
I recommend:
$_SESSION = null;
Reason: this will clear all login and other associated data immediately. It leaves the cookie intact, which is normally of no concern, since all associated data is gone.

Passing a variable from one page to another in Wordpress

I was wondering if anyone could give me an idea of how to pass a variable to another page in Wordpress.
I need to be able to use the get_the_ID(); function to set a variable which can be accessed from any page.
Would I be able to store the variable in a session or would that be a security issue?
Am I completely on the wrong track because to be honest, I have no idea what I'm doing.Any help would go a long way.
Cheers
Using session is not a security issue as long as you not getting any user input (otherwise sanitize/encrypt your value).
Go ahead and use it like this
<?php
$_SESSION['next-page-id'] = get_the_ID(); // once set
Now in your whole application you can access your session variable like this:
if ( isset( $_SESSION['next-page-id'] ) ) { // remember to check if it set or not
echo $_SESSION['next-page-id'];
}
Edited:
You don't have to use session_start() on top of each page instead you should add a function in init hook.
Just paste this tiny code to your functions.php file
function session_initialize() {
if ( ! session_id() ) {
session_start();
}
}
add_action( 'init', 'session_initialize' );
Is it possible for a user to view session variables?
No, a user can't able to view your session at all. If they don't have access to your files.
How does wordpress stop users from creating their own session variables?
Remember Wordpress not use session in its whole application (Only Cookies). Users cannot create session variables. As said above they have to write code to your php file (or somehow they inject code to your application if any plugin or theme found vulnerable).

Check if session is set or not, and if not create one?

I want to check if a session is currently set, and if so do allow the page to run as normal (do nothing) if not create a session.
I had a look at another SO question, in which the following code was posted:
if ( empty( $_SESSION['login'] )) { } else { }
Would the easiest way to do this be to set something like $_SESSION['a'] for each session, and then run if(empty($_SESSION['a'])) to check if a session exists?
Then again, can you use a session variable without invoking session_start() in the first place, thus making it obsolete (I tried this yesterday, as an echo though, not an if statement to check that a variable was carrying through without realizing that session_start() needed to be invoked before I could echo the variable).
There's probably an easy way that's oft used, I just can't seem to find it.
Any help would be greatly appreciated!
session_id() returns the string identifying the current session. If a session hasn't been initialized, it will return an empty string.
if(session_id())
{
// session has been started
}
else
{
// session has NOT been started
session_start();
}

Categories