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.
Related
I'm trying to use an AJAX call to update a session variable, then redirect and get that variable on the next page. My problem is that once the page has redirected, the session is not updated until I refresh.
I think this might be to do with the fact that the session is the first thing that gets loaded, but I can't find a way around it. Here is my relevant code:
Input page
$.post('save.php', {data:$input})
.done(function() {
window.location.replace('result.php');
}
);
save.php
session_start();
// make sure previous value has been deleted
unset($_SESSION['word']);
$_SESSION['word'] = $_POST['word'];
result.php
session_start();
$data = $_SESSION['word'];
print_r($data);
Thanks!
I think #skywalker has a very good point, but if you want to do it with ajax like now:
In your php file where you save the session change it to
session_start();
// make sure previous value has been deleted // <--- not needed
unset($_SESSION['word']);
$_SESSION['word'] = $_POST['word'];
session_write_close(); //<---------- Add this to close the session so that reading from the session will contain the new value.
To explain: the session is stored in files on the server. When you edit the session, the files are locked for writing but not for reading. When the server did not write all the changes yet to the session files and the next php script tries to read the session, you will get the 'old' values. To force the server to write all changes to the session, close the session for writing before reading with the next script.
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.
Newbie question, but I'm wondering if I'm missing something elementary here.
If I register a session variable in a page - isn't this variable supposed to be accessible from another page on the same site?
First, I register a variable in the file session_var_register.php:
<?php
$_SESSION["myusername"] = 'user';
if (isset($_SESSION['myusername'])) {
echo 'Session var myusername is set to '.$_SESSION['myusername'];
}
?>
When I open this page, it writes:
Session var myusername is set to user
As expected.
Then I open another tab and another page, check_session_var.php:
<?php
if (isset($_SESSION['myusername'])) {
echo 'Session var myusername is set to '.$_SESSION['myusername'];
}
?>
This page is blank.
Isn't the point of a session variable that it should be accessible in the browser session, until the session is programatically destroyed or the browser closed?
I'm using IE 8 and Firefox 24, btw. Identical results.
You forgot
session_start()
On top, before using
$_SESSION
PS: Remember to call session_start() in every page you want to use $_SESSION.
The PHP docs state that you must call session_start() to start or resume a PHP session. This must be done before you try to access or use session variables. Read more here.
session_start();
Your session variables will be available on different pages of the same site but on top of each of these pages you must have at least:
session_start();
It works but not in all cases. You must also use the same session name (essentially a cookie name that stores id of your session) on all pages. Moreover cookies (which are essential (mostly) for sessions to work) may be made visible only in specific directory. So if for example you share the same host with other guys that use sessions too you do not want to see their variables and vice versa so you may want to have sth like that:
1) session_name( 'my_session_id' );
2) session_set_cookie_params( 0, '/my_dir', $_SERVER['HTTP_HOST'], false, true );
3) session_start();
You may also want to see your session variables on other servers and in such case custom session handlers may be useful. Take a day or two to implement yourself - great way to understand how sessions work hence I recommend.
Method
session_start();
Description
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.
Usage in your case (and in the most of cases):
Put it before the $_SESSION usage.
Reference: session_start()
First Of all start session on that page
session_start();
your page like this way
<?php
session_start();
if (isset($_SESSION['myusername'])) {
echo 'Session var myusername is set to '.$_SESSION['myusername'];
}
?>
Just wondering how to check if a PHP session exists... My understanding is that no matter what, if I am using sessions, I have to start my files with session_start() to even access the session, even if I know it already exists.
I've read to user session_id() to find out if a session exists, but since I have to use session_start() before calling session_id(), and session_start() will create a new ID if there isn't a session, how can I possible check if a session exists?
In PHP versions prior to 5.4, you can just the session_id() function:
$has_session = session_id() !== '';
In PHP version 5.4+, you can use session_status():
$has_session = session_status() == PHP_SESSION_ACTIVE;
isset($_SESSION)
That should be it. If you wanna check if a single session variable exists, use if(isset($_SESSION['variablename'])).
I find it best many times (depends on the nature of the application) to simply test to see if a session cookie is set in the client:
<?php
if (isset($_COOKIE["PHPSESSID"])) {
echo "active";
} else {
echo "don't see one";
}
?>
Of course, replace the default session name "PHPSESSID" with any custom one you are using.
In PHP there is something called the session name. The name is co-related to the cookie that will be being set if the session was already started.
So you can check the $_COOKIE array if there is a session cookie available. Cookies are normally the preferred form to interchange the session id for the session name with the browser.
If a cookie already exists this means that a PHP session was started earlier. If not, then session_start() will create a new session id and session.
A second way to check for that is to check the outgoing headers if the cookie for the session is set there. It will be set if it's a new session. Or if the session id changed.
isset($_SESSION) isn't sufficient because if a session has been created and destroyed (with session_destroy()) in the same execution, isset($_SESSION) will return true. And this situation may happen without your knowing about it when a 3rd party code is used. session_id() correctly returns an empty string, though, and can be called prior to session_start().
Check if session exists before calling session_start()
if(!isset($_SESSION))session_start();
You can call session_id before session_start. http://www.php.net/manual/en/function.session-id.php - read the id param
I've always simply used
if (#session_id() == "") #session_start();
Hasn't failed me yet.
Been quite a long time using this.
NOTE: # simply suppresses warnings.
Store the session_id in $_SESSION and check against it.
First time
session_start();
$_SESSION['id'] = session_id();
Starts a session and stores the randomly given session id.
Next time
session_start();
$valid_session = isset($_SESSION['id']) ? $_SESSION['id'] === session_id() : FALSE;
if (!$valid_session) {
header('Location: login.php');
exit();
}
Starts a session, checks if the current session id and the stored session id are identical (with the ternary ? as replacement for the non-existing short circuit AND in php). If not, asks for login again.
switch off the error reporting if noting is working in your php version put top on your php code
error_reporting(0);
I solved this three years ago, but I inadvertently erased the file from my computer.
it went like this. 3 pages that the user had to visit in the order I wanted.
1) top of each php page
enter code heresession start();enter code here
2) first page:
a) enter code here$_session["timepage1"] = a php date function; time() simple to use
b) enter code here$_session["timepage2"]= $_session["timepage1"];
b) enter code here$_session["timepage3"]=$_session["timepage1"];
3) second page:
a) enter code here$_session["timepage2"] = a php date function; time() simple to use
b) enter code here$_session["timepage3"]= $_session["timepage3"];
3) third page:
a) enter code here$_session["timepage3"] = a php date function; time() simple to use
the logic:
if timepage3 less than timepage3 on page 2
{the user has gone to page 3 before page 2 do something}
if timepage2 on page 2 less than timepage1
{the user may be trying to hack page two we want them on page 1 do something}
timepage1 should never equal timepage2 or timepage3 on any page except page1 because if it is not greater on pages two or three the user may be trying to hack "do something"
you can do complex things with simple arithmetic with the 3 timepage1-2-3 variables. you can either redirect or send a message to say please go to page 2. you can also tell if user skipped page 2. then send back to page 2 or page one, but best security feature is say nothing just redirect back to page1.
if you enter code hereecho time(); on every page, during testing, you will see the last 3 digits going up if you visit in the correct order.
I found the source of the problem #2. It is the use of session_register(foo).
I put the following to my handle_registration.php.
session_register("foo");
session_register("foo2");
$foo2 = $_POST['email'];
$foo['email'] = $_POST['email']
The problem still persists, since no variables are stored to my session cookie.
This is the logic of my login script.
Solved by Pascal Martin and The Disintegrator: Which is the right place to put the function session_write_close in generating sessions for login?
How can you get a permanent session for user "session" such that a new session is not started each time index.php is loaded?
I have the session_start() at the beginning of my index.php.
The very Beginning of my index.php
session_start();
if($_SESSION['logged_in'] == false) {
$random_number = rand(1,100000);
session_id($random_number);
session_id['email'] = '';
}
while the very end of my index.php
<?php
session_write_close(); // Session code ends here!
?>
I have right after the very beginning of the session code the validation process of user's password by
$dbconn = pg_connect("host=localhost port=5432 dbname=masi user=masi password=123");
$result = pg_prepare($dbconn, "query22", "SELECT passhash_md5 FROM users
WHERE email=$1;");
$passhash_md5 = pg_execute($dbconn, "query22", array($_REQUEST['email']));
// users from registration/login form
if ($passhash_md5 == md5($_REQUEST['password'])) {
$_SESSION['logged_in'] = true;
$_SESSION['email'] = $_REQUEST['email'];
$_SESSION['passhash_md5'] = md5($_REQUEST['password']);
}
// this may be unnecessary if the passhash_md5 cannot be changed by the user
$passhash_md5_2 = pg_execute($dbconn, "query22", array($_SESSION['email']));
// users staying in the site
if ($passhash_md5_2 == $_SESSION['passhash_md5'])) {
$_SESSION['logged_in'] = true;
}
The code generates me continuously random sessions such that no user's data is being saved for the user.
I replaced each $_REQUEST after the login/registration handlers by $_SESSION in my code, since $_REQUEST does not include $_SESSION - still the same problem and I cannot see the username in the homepage after registration/login.
You should use output buffering to prevent this
<?php
ob_start();
everything here
ob_end_flush();
?>
You can't send headers once the normal output takes place.
Your code looks like this :
-- content cut --
</html>
<?php
session_regenerate_id(true); // Session code ends here!
session_write_close();
?>
You definitly have some output (the whole content of your page, actually) before session_regenerate_id is called ; hence the error.
The problem is not with "empty lines" or spaces : it is with output ; and HTML is output ;-)
Like the call to session_start, the call to session_regenerate_id should be done at the beginning of the script, before anything is sent to the browser.
So, here, in the block at the "top" of your index.php.
EDIT : more thoughts.
BTW? I'm not sure you actually need to call session_write_close ; I've probably never used that function, I believe... And, quoting the doc :
Session data is usually stored after
your script terminated without the
need to call session_write_close()
The only case you might need to call this function yourself is if you are doing long calculations :
session data is locked to prevent
concurrent writes only one script may
operate on a session at any time. When
using framesets together with sessions
you will experience the frames loading
one by one due to this locking. You
can reduce the time needed to load all
the frames by ending the session as
soon as all changes to session
variables are done.
But this doesn't seem to be your case, as you are calling this at the end of your script.
So, you could try removing the (useless ?) call to that function...
And, about session_regenerate_id : do you really need to call this function on each page ?
I suppose never calling it would be enough for your site to work... Even if you might want to call it when the user logs in, for security precautions (If I remember correctly, it's nice to call this function whenever the privileges level of a user changes)
Same about session_id, btw : do you really need to call this function on each page ?
http://www.php.net/manual/en/function.session-regenerate-id.php#53480
http://www.php.net/manual/en/function.session-regenerate-id.php#85433
session_regenerate_id — Update the current session id with a newly generated one
If you use it the way you are, you will be generating new sessions over and over.
session_id — Get and/or set the current session id
You are setting a new session every time with a random number.
Actually, the only thing you NEED to use sessions is to put a session_start() statement at the beginning of the script.