PHP : Function Reference : Session Handling Functions : session_start
Example 2228. A session example: page1.php
<?php // page1.php
session_start();
echo 'Welcome to page #1';
$_SESSION['favcolor'] = 'green'; $_SESSION['animal'] = 'cat'; $_SESSION['time'] = time();
// Works if session cookie was accepted echo '<br /><a href="page2.php">page 2</a>';
// Or maybe pass along the session id, if needed echo '<br /><a href="page2.php?' . SID . '">page 2</a>'; ?>
Example 2229. A session example: page2.php
<?php // page2.php
session_start();
echo 'Welcome to page #2<br />';
echo $_SESSION['favcolor']; // green echo $_SESSION['animal']; // cat echo date('Y m d H:i:s', $_SESSION['time']);
// You may want to use SID here, like we did in page1.php echo '<br /><a href="page1.php">page 1</a>'; ?>
m dot kuiphuis
[Editors Note: For more information about this http://www.zvon.org/tmRFC/RFC882/Output/chapter5.html ]
I use name-based virtual hosting on Linux with Apache and PHP 4.3.2.
Every time when I refreshed (by pressing F5 in Internet Explorer) I noticed that I got a new session_id. Simultaneously browsing the same site with Netscape didn't give me that problem. First I thought this was some PHP issue (before I tested it with Netscape), but after searching a lot on the internet I found the problem.
Since I was using name based virtual hosting for my testserver and we have different webshops for different customers I used the syntax webshop_customername.servername.nl as the domain-name.
The _ in the domain name seemed to be the problem. Internet Explorer just denies setting the cookie on the client when there is a special character (like an _ ) in the domain name. For more information regarding this issue: http://support.microsoft.com/default.aspx?scid=kb;EN-US;316112
Stupidly enough, this information was related to asp (yuk :o)
zackbloom
Yes php does not automatically insert the SID in header redirects. You must use something like:
'<address>?SID='.SID
to manually insert the SID.
hbertini
workaround when using session variables in a .php file referred by a frame (.html, or other file type) at a different server than the one serving the .php:
Under these conditions IE6 or later silently refuses the session cookie that is attempted to create (either implicitly or explicitly by invoquing session_start()).
As a consequence, your session variable will return an empty value.
According to MS kb, the workaround is to add a header that says your remote .php page will not abuse from the fact that permission has been granted.
Place this header on the .php file that will create/update the session variables you want:
<?php header('P3P: CP="CAO PSA OUR"'); ?>
Regards,
Hugo
dino
With IE and FF, session_start() appears to stop form values being preserved when the user browses 'back' to a page (I'm using SBS2K3 IIS6 PHP5.1.1).
For example if you set some hidden form values from javascript in one page, then navigate to another page and come back using the browsers back button, the form values should be preserved. But this does not happen when your your form page uses session_start().
The following seems to sort this out nicely:
session_cache_limiter('public');
session_start();
core58
when you're using session trans sid ENABLED, and you perform redirect such as Header( "Location..." ), redirected client will SURELY loose his session.
to avoid this, you can use a modified version of redirect function, like this:
<?php
function Redirect302( $location )
{
$sname = session_name();
$sid = session_id();
if( strlen( $sid ) < 1 )
{
Header( $location );
return;
}
if( isset( $_COOKIE[ $sname ] ) || strpos( $location, $sname."=".$sid ) !== false )
{
Header( $location );
return;
}
else
{
if( strpos( $location, "?" ) > 0 )
$separator = "&";
else
$separator = "?";
$fixed = $location . $separator . $sname."=".$sid;
Header( $fixed );
return;
}
}
?>
expamle:
Redirect302( "Location: /YourPage/index.php" );
the function performs common redirect if no session is active, and appends session "name=sid" to query string when session is already started, like PHP parser does when outputting your page.
hope, you'll find it useful.
yours:)
saykyo mail
Watch out for using UTF-8 encoding in your php scripts!
I don't know about other enviroments, but in Windows XP, if you edit a document and set it to be UTF-8, the editor (notepad for exapmle) inserts two invisible bytes at the beginning of the file (they read FF FE in hex for me). I suppose this happens so Windows can identify the file as UTF-8.
Since these two bytes are placed before anything else in the file, including <? ?> tags, when you execute the php script, they get outputed to the browser (even tough they won't be shown in the source of the result document, they're there!) before your php code gets a chance to run anything. This effectively cripples functions like session_start() ($_COOKIE to be exact).
The solution is to save the php file in a different encoding, or to manually remove them (I prefer the former).
I hope I helped somebody.
james
To avoid the notice commited by PHP since 4.3.3 when you start a session twice, check session_id() first:
if (session_id() == "")
session_start();
info
To avoid the notice commited by PHP since 4.3.3 when you start a session twice use this function:
<?php
function start_session(){
static $started=false;
if(!$started){
session_start();
$started = true;
}
}
?>
This should help you when your error reporting is set to E_ALL
leandroico---at---gmail---dot---com
TAGS: session_start headers output errors include_once require_once php tag new line
Errors with output headers related to *session_start()* being called inside include files.
If you are starting your session inside an include file you must be aware of the presence of undesired characters after php end tag.
Let's take an example:
> page.php
<?php
include_once 'i_have_php_end_tag.inc.php';
include_once 'init_session.inc.php';
echo "Damn! Why I'm having these output header errors?";
?>
> i_have_php_end_tag.inc.php
<?php
$_JUST_A_GLOBAL_VAR = 'Yes, a global var, indeed';
?>
> init_session.inc.php
<?php
session_start();
$_SESSION['blabla'] = 123;
?>
With all this stuff we will get an error, something like:
"... Cannot send session cache limiter - headers already sent (output started at ...", right?
To solve this problem we have to ignore all output sent by include files. To ensure that we need to use the couple of functions: *ob_start()* and *ob_end_clean()* to suppress the output. So, all we have to do is changing the *page.php* to this:
<?php
ob_start();
include_once 'i_have_php_end_tag.inc.php';
include_once 'init_session.inc.php';
ob_end_clean();
echo "Woo hoo! All right! Die you undesired outputs!!!";
?>
gadgetguy03
SESSION LOST ON HEADER REDIRECT (CGI on IIS 5.0)
I realize there are numerous scattered posts on this issue, but I would like to add my 2¢ since it took me a whole day and a download of the LiveHTTPHeaders Mozilla plugin to figure it out.
On the **CGI** version of PHP on IIS 5.0/Windows 2000, the following code will not work as expected:
/***** sess1.php *****/
session_start();
$_SESSION["key1"] = "testvalue";
header("Location: sess2.php");
/***** sess2.php *****/
session_start();
echo "key1 = '".$_SESSION["key1"]."'";
PROBLEM:
All session data is lost after a header redirect from the first page on which the session is initialized. The problem is, the PHPSESSID cookie is not being sent to the browser (ANY browser, IE or Mozilla) on the initial session page with the header("Location: ...") redirect. This is unrelated to client cookie settings - the set-cookie: header just isn't sent.
SOLUTION:
I was able to remedy the problem by switching to the ISAPI DLL version. This seems to be an MS/IIS bug, NOT a PHP bug - go figure. I hope this saves you some headaches especially with your user authentication scripts!!
The closest matching "bug" report I found: http://bugs.php.net/bug.php?id=14636
zero luke zero
Regarding the posts discussing ways of checking if a session is active, I've found that this is the best way, aslong as you dont assign any variables to the $_SESSION superglobal before calling the function.
The Function:
<?php
function session_started(){
if(isset($_SESSION)){ return true; }else{ return false; }
}
?>
An Example:
<?php
function session_started(){
if(isset($_SESSION)){ return true; }else{ return false; }
}
//Start the output buffer so we dont create any errors with headers
ob_start();
//Check to see if it has been started
if(session_started()){
echo 'The session has been started.<br />';
}else{
echo 'The session has not been started.<br />';
}
//Start the session
echo 'Starting Session...<br />';
session_start();
//Check again
if(session_started()){
echo 'The session has been started.<br />';
}else{
echo 'The session has not been started.<br />';
}
//Flush the buffer to screen
ob_end_flush();
?>
Hope this helps some people.
kyzer
Recursive session usage isn't possible. By that I mean fetching (via curl or such) another page on the site which uses sessions, as part of a page which itself uses sessions.
For example:
page1.php:
<?php
session_start();
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "http://example.com/backend.php");
curl_exec($curl);
?>
backend.php:
<?php
session_start();
print $_SESSION['foo'];
?>
In this case, requesting page1.php will hang the request indefinitely. backend.php is waiting to open the session data for reading/writing, but it's still locked by page1.php, which is waiting for backend.php to finish.
Because there's no session_end(), you can't get PHP to relinquish the lock on the session data after session_start() has occured. The solution is just to include backend.php or its functionality directly, e.g.:
require './backend.php';
raphael
Quick point, since this had been going round in circles for days...
IE will not accept sessions from a domain that has an non alpha-numeric character in it. My development site was running under the vhost mos_dev and it was killing me, trying to work out why IE kept dropping my sessions.
james
One thing of note that caused me three days of trouble:
It's important to note that Firefox (for one) makes two calls to the server automatically. One for the page, and one for favicon.ico.
If you are setting session variables (as I was) to certain values when a page exists, and other values when pages don't exist, the values for non-existent pages will overwrite the values for existing pages if favicon.ico doesn't exist.
I doubt many of you are doing this, but if you are, this is a consideration you need to address or you'll be bald over the course of a three day period!
benja
Just for info, session_start() blocks if another PHP using the same session is still running in background. It seems it's waiting the other PHP to finish... and sometimes it can be a problem. Create 2 different sessions by setting 2 different names : session_name() solve the problem.
Benja.
admin
Just a note for any of you who have the same trouble as I did. $_SESSION appears to break horribly if you attempt to assign information into integer keys.
For example, a result from a MySQL query may look like:
<?php
array(
0 => 'haravikk',
'username' => 'haravikk',
1 => 'fish',
'password' => 'fish'
);
?>
Attempting to assign that to $_SESSION either as a straight array, or by placing all keys (for example using a foreach) will FAIL and the data will be unavailable when you move to another page. My solution was to do this:
<?php
function storeSessionArray($array) {
foreach($array as $k => $v)
if (is_string($k)) $_SESSION[$k] = $v;
}
?>
This worked correctly =)
ben dot morin
James at skinsupport dot com raises a good point (warning) about additional requests from the browser. The request for favicon.ico, depending on how it is handled, can have unintended results on your sessions.
For example, suppose you have ErrorDocument 404 /signin.php, no favicon.ico file and all pages in your site where the user signs in are also redirected to /signin.php if they're not already signed in.
If signin.php does any clean up or reassigning of session_id (as all good signin.php pages should) then the additional request from the browser for favicon.ico could potentially corrupt the session as set by the actual request.
Kudos to James for pointing it out and shame on me for skimming past it and not seeing how it applied to my problem. Thanks too to the Firefox Live HTTP Headers extension for showing the additional request.
Don't waste days or even hours on this if your session cookies are not being sent or if the session data isn't what you expect it to be. At a minimum, eliminate this case and see if any additional requests could be at fault.
mike
It seems that the session file is opened exclusively.
On some occasions (Windows) I have found that the file lock is not released properly for whatever reason, therefore causing session_start() to hang infinitely on any future script executions.
My way round this problem was to use session_set_save_handler() and make sure the write function used fopen($file, 'w') instead of fopen($file, 'x')
colemanc
In reference to the "Cannot send session cache limiter..." error message, I have tried a number of ways to supress the error. An If/Then block will work only if you store the flag in a session variable, cookie, or other method. Or, you can obviously supress error messages by the error level. However, the simplest way to do it is a simple:
@session_start();
This will hide all error messages resulting from that line of code. I would only recommend this method AFTER you have fully tested your code but it is very effective when that is your only error and you do not want to completely stop code exectution by means of a die() or exit() function.
roope dot luhtalanospam
If your session_start() does not set a cookie, but instead just generates a new session_id on every request, you should check if your script is echoing something before the function call. Even a line change in the code before the session_start() function prevents the cookie to be set.
jorrizza
If you open a popup window (please no commercial ones!) with javascript window.open it might happen IE blocks the session cookie.
A simple fix for that is opening the new window with the session ID in a GET value. Note I don't use SID for this, because it will not allways be available.
----page.php----
//you must have a session active here
window.open('popup.php?sid=<?php echo session_id(); ?>', '700x500', 'toolbar=no, status=no, scrollbars=yes, location=no, menubar=no, directories=no, width=700, height=500');
----popup.php----
<?php
session_id(strip_tags($_GET['sid']));
session_start();
//and go on with your session vars
?>
r dot s dot goldsmith
If you ever want to know whether a session is open or has already been closed (e.g. with session_write_close()) when you need to open one (in my case, writing a framework and, therefore, not controlling the session directly), I have been unable to find an official check. However, I did notice that session_start() has the following behaviour:
* If the session has been open before but is now closed, when you call session_start() the $_SESSION array is reset to the content of the session.
* If the session is already open, the $_SESSION array is left totally untouched.
Therefore, I came up with the following (obviously assuming you have already tested $_SESSION exists):
<?php
$_SESSION['testMe']='test';
@session_start();
if(isset($_SESSION['testMe']))
{
echo "Session was open\n";
unset($_SESSION['testMe']);
}
else
echo "Session was closed\n";
?>
Until someone can tell me the 'official' way to do it, this seems to work.
Just to save some confusion, $_SESSION, session_id() and the SID define all maintain their values after a session_write_close() so are of no use in identifying if a session is currently open or not. Hence this trick.
erm
If you are insane like me, and want to start a session from the cli so other scripts can access the same information.
I don't know how reliable this is. The most obvious use I can see is setting pids.
// temp.php
#!/usr/bin/php -q
<?php
session_id ("temp");
session_start();
if ($_SESSION) {
print_r ($_SESSION);
}
$_SESSION['test'] = "this is a test if sessions are usable inside scripts";
?>
// Temp 2
#!/usr/bin/php -q
<?php
session_id ("temp");
session_start();
print_r ($_SESSION);
?>
cppforlife
If you are getting headers sent error check what is the encoding of your file. In my case i had utf-8, so i changed it to ansi, and everything worked.
hope it helps!
devonmitton
I ran into the problem of losing the session after i redirect the user with header( location:);
I found that the problem doesn't occur in php5. Atleast for myself. I tested it on IIS as well as Apache and both times using php5 fixed the issue.
Secondly, I found a weird solution: The website i'm building required Cyrillic type, so i encode the pages using UTF-8. The problem that happens is that UTF-8 sends information before the php tags, and therefore before the session_start(); which ultimately renders the session_start(); call ineffective.
The UTF-8 encoding sends a small chunk of information before anything. This is called BOM (byte order marks).
To ensure that they don't show up, you need to save your files with a UTF-8 encoding which bypasses BOM. BBEdit for the Macintosh with allow for this under the file encoding options.
To recap: In this instance and for my situation, UTF-8, no BOM will allow sessions to pass through the header( location:); redirect, or using PHP5.
Hope this helps someone! [i will also repeat this comment under the header() function]
iam1981
I had the same "session data lost" issue. I couldn't solve it with a single session_start(). Instead I had to include session_start() in each page.
Another X File archived...
evil dot 2000
I had a problem accessing a session which is open in another frame at the same time.
I had a frame, which is displaying a live text like a chat. It has an opend and locked session. I tried to add data to this session with another frame, but this wouldn't work.
In the first frame i had a loop which is looking for fresh data in the session and prints it out like this:
<?php
session_start();
[...]
while (true) {
echo $_SESSION["input"]."\n";
sleep(1);
}
?>
But this locks the session, and no other frame can access the session data at the same time.
So i modified this loop a bit like this:
<?php
session_start();
[...]
session_commit();
while (true) {
ob_start(); session_start(); ob_end_clean();
echo $_SESSION["input"]."\n";
session_commit();
sleep(1);
}
?>
Now the second frame is able to access the session.
The ob_start() and ob_end_clean() is just for surpressing the cookie output to the browser.
devour
How many times you've seen this error when actually your code is perfect:
Warning: session_start(): The session id contains invalid characters,
valid characters are only a-z, A-Z and 0-9 in
Usually there are MANY reasons why such an error can appear into your logs, page, etc. (one way to generate it, is to send PHPSESSID='').
But it wasn't our case. We checked everything, and we even logged the entire request ($_GET, $_POST) that was generating the error.
Still no luck. Until one point, when we checked what the session cookie contains.
It seems there are few bots that are trying to buffer overflow (?) a page, using session cookies manually changed to contain something else than session id (strlen == 32 and hex number) The bot in our case was trying to mass submit spam on pages.
So we needed to check and destroy any session id that do not comply.
After adding this code:
$sn=session_name();
if(isset($_GET[$sn])) if(strlen($_GET[$sn])!=32) unset($_GET[$sn]);
if(isset($_POST[$sn])) if(strlen($_POST[$sn])!=32) unset($_POST[$sn]);
if(isset($_COOKIE[$sn])) if(strlen($_COOKIE[$sn])!=32) unset($_COOKIE[$sn]);
if(isset($PHPSESSID)) if(strlen($PHPSESSID)!=32) unset($PHPSESSID);
session_start();
we got rid of that.
( Note: The code is before session_start() )
Strange, kinda paranoid, but effective.
chris brown
Here's another session tip for you, relevant to IE6:
If you find that your session is unexpectedly lost when your application opens a page in a pop-up window, try closing down any other copies of IE running on your machine.
The problem is that IE doesn't always use the same IE process to host a new pop-up window - it chooses one (using some mysterious strategy) from the pool of running IE processes! Since session information (cookies) is not preserved across processes, the pop-up may loose the session (and probably redirect the user to your log-in page.)
I don't know a work-around for this, except for close all other IE windows. Microsoft state that they do not guarantee that sessions will be preserved across multiple windows: http://support.microsoft.com/default.aspx/kb/196383
corey
Here is a crazy feature -- you get one concurrent database connection per session, transparent to the programmer!
I am running php 5.0.4 on iis 6 (yeah, I know...). I noticed under stress testing that database connections were my bottleneck. I spent like 5 hours turning this on, that off, etc because I could not get php to create more than one database connection at a time, regardless of how many requests it was servicing. I tried running php as fastcgi, cgi, and isapi module. I tried using mysql and mysqli extensions. Same thing every time. Then I happened to turn off auto-start sessions and commented out my session_start() calls, and all of the sudden I get multiple connections like I expected!
Don't let this happen to you -- don't freak out! Apparently something somewhere tries to make sure your visitors don't get more than their share of your resources, so they get one db connection per session. I can't say it is what I would like to happen, but now that I know, it doesn't bother me much :) Hope this saves someone some time and headache!
design
For those encoding their pages in UTF-8 but running into problems with BOM data (Byte Order Marks) being outputted before anything else - such as $_SESSION data - but wish to use UTF-8 encoding, and who do NOT wish to use UTF-8 No BOM encoding because the latter produces weird results when using foreign language accented characters, try the following :
- Save your document with UTF-8 No BOM encoding (on a mac, using BBEdit, this is normally found on the very bottom left corner of the window). This will produce a document that will not output BOM data.
- then, in your scripts, include the following:
header('Content-Type: text/html; charset=UTF-8');
before your call to session_start()
hope that helps someone.
jose cavieres
For the problem of session lost after of redirect with header location...
Try with this:
<?
session_start();
$_SESSION['mySession'] = "hello";
header ("Location: xpage.php");
exit(); //This sentence do the magic
?>
mjr-php
For some reason, MSIE gets confused when session_start() is called and the Content-disposition has been set to "attachment". The only solution I've found is this:
if(strpos($_SERVER['HTTP_USER_AGENT'],"MSIE")) {
session_cache_limiter('public');
}
session_start();
See also: http://joseph.randomnetworks.com/archives/2004/10/01/
making-ie-accept-file-downloads
jeremygiberson
foltscane at yahoo dot com wrote about people losing session information on page redirects.
The problem is some times the redirect may kick you off to the next page before all the session variables have been saved. The true solution to lost session vars on redirect is to simply call session_write_close(); before setting the redirect header. This will insure that php finishes writing the session info before page redirect gets underway.
ie:
<?
session_start();
$_SESSION['forward'] = "This session data will not be lost!";
session_write_close();
header('Location: nextpage.php');
?>
bulk
Don't *ever* use /dev/random as a session entropy file, because session_handler will hang for a *long* time after open(). This configuration will be *the* overkill:
<?php
ini_set("session.entropy_file", "/dev/random");
ini_set("session.entropy_length", "512");
?>
Use /dev/urandom instead. The reason for this is (from Wikipedia):
A counterpart to /dev/random is /dev/urandom ("unlimited" random source) which reuses the internal pool to produce more pseudo-random bits. This means that the call will not block, but the output may contain less entropy than the corresponding read from /dev/random.
We spent 2 days on figuring this out. You have been warned.
steffen dot pietsch
Beware to use $_SESSION as parameter to a function.
(here: php5 5.1.2)
Use:
$s=array(); foreach($_SESSION as $k => $v) $s[$k]=$v;
$result = VeranstaltungTermin::search($s, $quellen, $KatCount);
otherwise the garbage-collection of php5 will destroy at end of script Your $_SESSION array before writing to disk
ehassler
At work we had an odd warning, "Cannot send session cache limiter - headers already sent". In the following:
header('meta:1');
session_start();
the first header went across fine, but the session_start died with the warning.
What was happening was that the session contained an object which fired __autoload() when it was unserialized. The __autoload() then included the file with the class definition, but that file also output non-header text. This caused session_start() to be unable to add the session_id to the headers.
This was difficult to find because we weren't able to see the text that was output from the file that was __autoload()ed, only the warning.
crs
As the previous note said, the session_start() function needs a directory to write to.
You can get Apache plus PHP running in a normal user account. Apache will then of course have to listen to an other port than 80 (for instance, 8080).
Be sure to do the following things:
- create a temporary directory PREFIX/tmp
- put php.ini in PREFIX/lib
- edit php.ini and set session.save_path to the directory you just created
Otherwise, your scripts will seem to 'hang' on session_start().
truthhunter
Another one bitten by the "a different domain name gives you a new session" in IE...
My site uses interactive PDF documents. A user saves data from them into FDF documents, and when this happens, the site also includes the URL of the PDF in the FDF data (using the FDF "/F" tag).
This URL is generated using the $_SERVER["HTTP_HOST"] value from PHP. For some as-yet-undetermined reason, when my hosting provider updated PHP (I believe to 4.4.1), for a time the $_SERVER["HTTP_HOST"] value apparently dropped the "www." from my domain name. So, some FDF files were saved with this different URL value. Needless to say, when one of these FDFs loaded the corresponding PDF, although the load and display of the PDF worked, any subsequent save operation (which relies on current session information for validating the user, etc.) initiated from within the PDF failed. The original session had been established for the "www.domain.com", but because the PDF URL lacked the "www.", PHP/IE had established a new, essentially empty, session.
I scratched my head over this problem for months and only recently happened upon this fix. In my case, manually patching the failing (binary) FDF files to include the "www." in the URL for the PDF did fix it.
Hopefully someone else finds this helpful...!
lukasl
About the Session not getting saved on a header("Location:") redirect.
Make sure to call session_write_close() before doing the redirect. This will make sure that the session values get written to the disk.
me
A note on Windows installations with an NTFS file structure:
Make sure you give your Internet user account (usually IUSR_MACHINENAME) "Modify" access to the session.save_path directory. Otherwise session_start() will silently - and oh, so slowly - fail.
("Modify" is a Win2k term, but the concept translates to older IIS installs).
mickey
A note on Windows installations with an NTFS file structure:
Make sure you give your Internet user account (usually IUSR_MACHINENAME) "Modify" access to the session.save_path directory. Otherwise session_start() will silently - and oh, so slowly - fail.
("Modify" is a Win2k term, but the concept translates to older IIS installs).
double
A bedder way to check wether the session is started including ip logging, so it will be a little saver. in 4 small lines.
<?php
if( !isset( $_SESSION ) ) { session_start(); }
if( isset( $_SESSION['REMOTE_ADDR'] ) && $_SESSION['REMOTE_ADDR'] != $_SERVER['REMOTE_ADDR'] )
{ session_regenerate_id(); $_SESSION['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR']; }
if( !isset( $_SESSION['REMOTE_ADDR'] ) ) { $_SESSION['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR']; }
?>
Yes, the code is a little bit self-willed ;)
phpguru
"SESSION FUNCTION IS DOMAIN SPECIFIC.
So, to savage the situation. be domain specific."
Umm. No, it isn't. It is however only domain specific when the domains are hosted on the same server.
You can still share session data between domain2.com and domain3.com just with that caveat.
|
|