©
Dokumen ini menggunakan Manual laman web PHP Cina Lepaskan
(PHP 4, PHP 5)
session_start — 启动新会话或者重用现有会话
$options
= []
] )session_start() 会创建新会话或者重用现有会话。 如果通过 GET 或者 POST 方式,或者使用 cookie 提交了会话 ID, 则会重用现有会话。
当会话自动开始或者通过 session_start() 手动开始的时候, PHP 内部会调用会话管理器的 open 和 read 回调函数。 会话管理器可能是 PHP 默认的, 也可能是扩展提供的(SQLite 或者 Memcached 扩展), 也可能是通过 session_set_save_handler() 设定的用户自定义会话管理器。 通过 read 回调函数返回的现有会话数据(使用特殊的序列化格式存储), PHP 会自动反序列化数据并且填充 $_SESSION 超级全局变量。
要想使用命名会话,请在调用 session_start() 函数 之前调用 session_name() 函数。
如果启用了 session.use_trans_sid 选项, session_start() 函数会注册一个内部输出管理器, 该输出管理器完成 URL 重写的工作。
如果用户联合使用 ob_start() 和 ob_gzhandler 函数, 那么函数的调用顺序会影响输出结果。 例如,必须在开始会话之前调用 ob_gzhandler 函数完成注册。
options
此参数是一个关联数组,如果提供,那么会用其中的项目覆盖 会话配置指示 中的配置项。此数组中的键无需包含 session. 前缀。
除了常规的会话配置指示项,
还可以在此数组中包含 read_and_close
选项。如果将此选项的值设置为 TRUE
,
那么会话文件会在读取完毕之后马上关闭,
因此,可以在会话数据没有变动的时候,避免不必要的文件锁。
成功开始会话返回 TRUE
,反之返回 FALSE
版本 | 说明 |
---|---|
7.0.0 |
新加 options 参数。
|
5.3.0 |
如果函数调用失败返回 FALSE ,
之前版本返回了 TRUE 。
|
4.3.3 |
在 PHP 4.3.3 中,
会话开始之后调用 session_start() 函数
会引发 E_NOTICE 级别的错误,
并且第二次请求开始会话的调用会被忽略。
|
Example #1 page1.php
<?php
// page1.php
session_start ();
echo 'Welcome to page #1' ;
$_SESSION [ 'favcolor' ] = 'green' ;
$_SESSION [ 'animal' ] = 'cat' ;
$_SESSION [ 'time' ] = time ();
// 如果使用 cookie 方式传送会话 ID
echo '<br /><a href="page2.php">page 2</a>' ;
// 如果不是使用 cookie 方式传送会话 ID,则使用 URL 改写的方式传送会话 ID
echo '<br /><a href="page2.php?' . SID . '">page 2</a>' ;
?>
请求 page1.php 页面之后,
第二个页面 page2.php
会包含会话数据。
请查阅 会话参考
获取更多关于 会话 ID 传送的信息,
在该参考页面中有关于常量 SID
的详细说明。
Example #2 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' ]);
// 类似 page1.php 中的代码,你可能需要在这里处理使用 SID 的场景
echo '<br /><a href="page1.php">page 1</a>' ;
?>
Example #3 覆盖 Cookie 超时时间设定
<?php
// 设置 cookie 的有效时间为 1 天
session_start ([
'cookie_lifetime' => 86400 ,
]);
?>
Example #4 读取会话之后立即关闭会话存储文件
<?php
// 如果确定不修改会话中的数据,
// 我们可以在会话文件读取完毕之后立即关闭它
// 来避免由于给会话文件加锁导致其他页面阻塞
session_start ([
'cookie_lifetime' => 86400 ,
'read_and_close' => true ,
]);
Note:
要使用基于 cookie 的会话, 必须在输出开始之前调用 session_start() 函数。
Note:
建议使用 zlib.output_compression 来替代 ob_gzhandler() 。
Note:
根据配置不同,本函数会发送几个 HTTP 响应头。 参考 session_cache_limiter() 来自定义 HTTP 响应头。
[#1] jeferson dot a30g at gmail dot com [2015-10-25 02:18:10]
Para resolver o erro:
warning session start function session start cannot send session cache limiter headers already sent output started at...
Basta usar o comando "session_start()" antes de qualquer c??digo html, pois ao mostrar algum html antes de iniciar a sess?o j?? estar?? inicializando o header.
Resumindo: ?? preciso iniciar a sess?o antes de inicializar o header html.
Exemplo:
<?php
session_start();
?>
<html>
<head>
....
Dica:
Ao usar: echo "Ol??!";
J?? estar?? inicializando o header tamb??m, por isso ?? preciso tomar cuidado.
[#2] aaronw at catalyst dot net dot nz [2015-04-23 06:56:48]
As others have noted, PHP's session handler is blocking. When one of your scripts calls session_start(), any other script that also calls session_start() with the same session ID will sleep until the first script closes the session.
A common workaround to this is call session_start() and session_write_close() each time you want to update the session.
The problem with this, is that each time you call session_start(), PHP prints a duplicate copy of the session cookie to the HTTP response header. Do this enough times (as you might do in a long-running script), and the response header can get so large that it causes web servers & browsers to crash or reject your response as malformed.
This error has been reported to PHP HQ, but they've marked it "Won't fix" because they say you're not supposed to open and close the session during a single script like this. https://bugs.php.net/bug.php?id=31455
As a workaround, I've written a function that uses headers_list() and header_remove() to clear out the duplicate cookies. It's interesting to note that even on requests when PHP sends duplicate session cookies, headers_list() still only lists one copy of the session cookie. Nonetheless, calling header_remove() removes all the duplicate copies.
<?php
function clear_duplicate_cookies() {
// If headers have already been sent, there's nothing we can do
if (headers_sent()) {
return;
}
$cookies = array();
foreach (headers_list() as $header) {
// Identify cookie headers
if (strpos($header, 'Set-Cookie:') === 0) {
$cookies[] = $header;
}
}
// Removes all cookie headers, including duplicates
header_remove('Set-Cookie');
// Restore one copy of each cookie
foreach(array_unique($cookies) as $cookie) {
header($cookie, false);
}
}
?>
[#3] elitescripts2000 at yahoo dot com [2014-01-25 03:56:08]
3 easy but vital things about Sessions in AJAX Apps.
<?php
// session start
// It is VERY important to include a Period if using
// a whole domain. (.yourdomain.com)
// It is VERY important to set the root path your session will always
// operate in... (/members) will ensure sessions will NOT be interfered
// with a session with a path of say (/admin) ... so you can log in
// as /admin and as /members... NEVER do unset($_SESSION)
// $_SESSION=array(); is preferred, session_unset(); session_destroy();
session_set_cookie_params(0, '/members', '.yourdomain.com', 0, 1);
session_start();
$_SESSION = array();
session_unset();
session_destroy();
session_set_cookie_params(0, '/members', '.yourdomain.com', 0, 1);
session_start();
$_SESSION['whatever'] = 'youwhat';
// session destroying
// To be safe, clear out your $_SESSION array
// Next, what most people do NOT do is delete the session cookie!
// It is easy to delete a cookie by expiring it long before the current time.
// The ONLY WAY to delete a cookie, is to make sure ALL parameters match the
// cookie to be deleted...which is easy to get those params with
// session_get_cookie_params()...
// FInally, use session_unset(); and session_destroy(); in this order to ensure
// Chrome, IE, Firefox and others, are properly destroying the session.
$_SESSION = array();
if (ini_get('session.use_cookies'))
{
$p = session_get_cookie_params();
setcookie(session_name(), '', time() - 31536000, $p['path'], $p['domain'], $p['secure'], $p['httponly']);
}
session_unset();
session_destroy();
// AJAX and SESSIONS.
// Example... you start a session based PHP page, which then calls an Ajax (XMLHTTP) authenticated
// using the SAME SESSION to Poll and output the data, for example. But, you notice when you
// try to start the Polling AJAX call always HANGS and seems to hang at the session_start().
// This is because the session is opened in the first page, calls the AJAX polling example, and
// tries to open the same session (for authentication) and do the AJAX call, you MUST call
// session_write_close(); meaning you are done writing to the $_SESSION variable, which really
// represents a file that must be CLOSED with session_write_close();....
// THAN you can call your AJAX Polling code to reopen the same session and do its polling...
// Normally, the $_SESSION is closed automatically when the script is closed or finished executing
// So, if you need to keep a PHP page running after opening a SESSION, simply close it when finished
// writing to $_SESSION so the AJAX polling page can authenticate and use the same session in a
// seperate web page...
session_write_close();
?>
Hope this helps someone with their sessions...
Thanks.
[#4] web at metelab dot com [2014-01-12 15:18:10]
IMPORTAN NOTE for all newby!!!
Before session_start() !
you must set session_cache_limiter()
in the value public, private_no_expire or private,
otherwise the standard session will be send headers 1981year (nocache)
and you will be very long to find someone sends headers!
Maybe this will help, because not find the headers are sent in the browser
[#5] ohcc at 163 dot com [2013-12-25 16:00:37]
The constant SID would always be '' (an empty string) if directive session.use_trans_sid in php ini file is set to 0.
So remember to set session.use_trans_sid to 1 and restart your server before you use SID in your php script.
[#6] Anonymous [2013-08-21 17:56:12]
In the Classes and Objects docs, there is this: In order to be able to unserialize() an object, the class of that object needs to be defined.
An object made by SimpleXML_Load_String() cannot be serialized. An attempt to do so will result in a run-time failure, throwing an exception. If you store such an object in $_SESSION, you will get a post-execution error that says this:
Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'SimpleXMLElement' is not allowed' in [no active file]:0 Stack trace: #0 {main} thrown in [no active file] on line 0
The entire contents of the session will be lost. This script demonstrates the failure. Hope this saves someone some time!
<?php // RAY_temp_ser.php
error_reporting(E_ALL);
session_start();
var_dump($_SESSION);
$_SESSION['hello'] = 'World';
var_dump($_SESSION);
// AN XML STRING FOR TEST DATA
$xml = '<?xml version="1.0"?>
<families>
<parent>
<child index="1" value="Category 1">Child One</child>
</parent>
</families>';
// MAKE AN OBJECT (GIVES SimpleXMLElement)
$obj = SimpleXML_Load_String($xml);
// STORE THE OBJECT IN THE SESSION
$_SESSION['obj'] = $obj;
[#7] ilnomedellaccount at gmail dot com [2013-08-13 15:53:46]
A note about session_start(), custom handlers and database foreign key constraints, which I think may be of some use...
We know that if we want our sessions into a database table (rather than the default storage), we can refer to session_set_save_handler(...) to get them there. Note that session_set_save_handler must (obviously) be called before session_start(), but let me get to the point...
Upon calling session_start() the "first time", when the session does not already exist, php will spawn a new session but will not call the write handler until script execution finishes.
Thus, the session at this point exists in the server process memory, but won't be visible as a row in the DB before the script ends.
This seems reasonable, because this avoids some unnecessary database access and resource usage before we even populate our session with meaningfull and definitive data, but this also has side-effects.
In my case, the script called session_start() to make sure a session was initiated, then used session_id() to populate another table in the DB, which had foreign_key constraint to the "sessions" table. This failed because no session was in the db at that point, yet!
I know I could simply force the creation of the row in the DB by manually calling the write handler after session_start(), when necessary, but I am not sure if this is the best possible approach.
As soon as I find an "elegant" solution, or a completely different approach, I will post some working sample code.
In the meanwhile... have fun!
[#8] AlexW [2013-02-07 12:22:37]
Please note:
If your session contains a class, include the class definition *before* calling session_start() otherwise you will get an error!
[#9] someOne_01 at somewhere dot com [2012-11-17 14:30:44]
When you have an import script that takes long to execute, the browser seem to lock up and you cannot access the website anymore. this is because a request is reading and locking the session file to prevent corruption.
you can either
- use a different session handler with session_set_save_handler()
- use session_write_close() in the import script as soon you don't need session anymore (best moment is just before the long during part takes place), you can session_start when ever you want and as many times you like if your import script requires session variables changed.
example
<?php
session_start(); //initiate / open session
$_SESSION['count'] = 0; // store something in the session
session_write_close(); //now close it,
# from here every other script can be run (and makes it seem like multitasking)
for($i=0; $i<=100; $i++){ //do 100 cycles
session_start(); //open the session again for editing a variable
$_SESSION['count'] += 1; //change variable
session_write_close(); //now close the session again!
sleep(2); //every cycle sleep two seconds, or do a heavy task
}
?>
[#10] foxz [2012-07-23 14:34:27]
Cannot send session cache limiter...
if you use UTF-8 charactere format
*** dont use BOM ! ***
(convert to UTF-8 without BOM)
config your FTP client to transfert *.php in BINARY format
BOM is an mark in start of file.
"hey, I'm UTF-8 encoded"
<?php session_start() ?>
^--- something before !
Syl
[#11] henrik at raketten dot net [2012-05-28 22:59:16]
I have found, like many others, that sometimes IE looses SESSION variables. In my case, this was caused due to a CNAME foirwarded IP address and it went away, when I changed it to a A node in my DNS settings.
I hope this will help somebody....
[#12] LaKing at D250 dot hu [2012-03-02 15:13:32]
I had a warning complaining about session_start() after adding an include file.
- It broke the functionality of my php code in a very strange manner.
- The included tree did not contain any additional session_start calls.
- it produced this warning only with with php -l from my development environment, and didn't produce any errors in the error_log.
- the warning pointed into a non-existing line, 1 line after last line of the file.
I use gedit on CentOS 6.1 with UTF-8 as current locale.
- Switching encoding back and forth didn't help.
- Commented out all the included content, only the php tags left, the error wa still there. ..
The solution was to clear out everything, and re-writing the php tags and posting back the content.
As it seems "hidden" unsupported characters produce errors and warnings falsely pointing to this function.
[#13] max_bilyk at yahoo dot com [2011-11-04 06:53:12]
An interesting bug/misfunction was discovered when using Flash-based file uploader (in my case jQuery plugin Uploadify, but also found similar problem reports about SWFupload).
Problem occurs with PHP 5.2 (and probably later as well) when it is compiled with Suhosin patch.
The problem is that session_start() does not load session data into $_SESSION variable when it gets request from Flash, and in this case $_SESSION variable becomes empty and at the end of script execution erases session data when script execution ends (PHP saves this empty $_SESSION to file).
The fact that Flash is using its own session management is solved by passing via POST/GET correct session ID, but erasing session data is definitely a problem.
The reason for the problem is method of session data encryption - Suhosin uses user-agent data as a part of encryption key.
And in case client machine makes requests from two different user-agents (browser + flash) Suhosin generates different session decryption key which is unable to decrypt session data (and notice that there's no message about this fact in any log-file).
So the solution for such case may be either by disabling encryption of session data by putting such directive in php.ini:
suhosin.session.encrypt=Off
or, alternatively, still keep session data encrypted but exclude user-agent data from encryption key by using this directive in php.ini:
suhosin.session.cryptua=Off
[#14] Dark Angel [2011-10-16 07:49:33]
I had script which should under CLI restore session set by web interface.
Spent like few hours understanding why script with session_id($sid) and session_start() is not restoring session, but generating new one. No any notices or anything helping to resolve.
$sid was read from STDIN. Issue was that value from STDIN contained '\n' character at the end, which is invalid for session identifier. Discovered by stracing CLI script.
Hope this will save you a lot of time.
[#15] sanjuro at 1up-games dot com [2011-08-18 11:56:55]
The problem with SID is that if on occasions you don't start a session, instead of outputting an empty string for transparent integration it will return the regular undefined constant notice. So you might want to test the constant with defined() beforehand.
[#16] egonrp [2011-07-19 06:59:24]
SOLVED: Session data lost
My session data lost problem was resolved by using a short name for session key.
This error happens with PHP version 5.2.6 (Debian Lenny), others versions works fine without any modification.
Before:
$_SESSION['current_user_search_filter'] = serialize($myArray);
$value = unserialize($_SESSION['current_user_search_filter']);
After (short key name):
$_SESSION['usearchfilter'] = serialize($myArray);
$value = unserialize($_SESSION['usearchfilter']);
Good Luck! :)
[#17] gkemaldag at gmail dot com [2011-04-20 00:37:07]
For the error:
Warning: session_start(): Cannot send session cache limiter - headers already sent ...
this kind of errors would occur, when the encoding of your script file needs to send some headers just after your script starts to execute,
this happens mostly with the scripts using normal utf8 encoding.
To overcome the issue, use utf8(without BOM) encoding provided by notepad++ and most modern editors. Using utf8 encoding and cookie based sessions, will result in headers already sent by error.
[#18] alakys [2011-03-03 08:26:19]
Sorry for the noob comment but for those having the error :
Warning: session_start(): Cannot send session cache limiter - headers already sent ...
And before trying all the solutions added by the experts, simply ensure to have your php code before even the DOCTYPE tag like this (and not between the doctype and html tags as I was doing):
<?php session_start(); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Test Page</title>
</head>
<body>
etc ....
It might sound funny but I am sure this post will save time to some others noobs like me ... !
[#19] linblow at hotmail dot fr [2011-02-16 05:06:33]
If you want to handle sessions with a class, I wrote this little class:
<?php
class Session
{
const SESSION_STARTED = TRUE;
const SESSION_NOT_STARTED = FALSE;
// The state of the session
private $sessionState = self::SESSION_NOT_STARTED;
// THE only instance of the class
private static $instance;
private function __construct() {}
public static function getInstance()
{
if ( !isset(self::$instance))
{
self::$instance = new self;
}
self::$instance->startSession();
return self::$instance;
}
public function startSession()
{
if ( $this->sessionState == self::SESSION_NOT_STARTED )
{
$this->sessionState = session_start();
}
return $this->sessionState;
}
public function __set( $name , $value )
{
$_SESSION[$name] = $value;
}
public function __get( $name )
{
if ( isset($_SESSION[$name]))
{
return $_SESSION[$name];
}
}
public function __isset( $name )
{
return isset($_SESSION[$name]);
}
public function __unset( $name )
{
unset( $_SESSION[$name] );
}
public function destroy()
{
if ( $this->sessionState == self::SESSION_STARTED )
{
$this->sessionState = !session_destroy();
unset( $_SESSION );
return !$this->sessionState;
}
return FALSE;
}
}
// We get the instance
$data = Session::getInstance();
// Let's store datas in the session
$data->nickname = 'Someone';
$data->age = 18;
// Let's display datas
printf( '<p>My name is %s and I\'m %d years old.</p>' , $data->nickname , $data->age );
printf( '<pre>%s</pre>' , print_r( $_SESSION , TRUE ));
// TRUE
var_dump( isset( $data->nickname ));
// We destroy the session
$data->destroy();
// FALSE
var_dump( isset( $data->nickname ));
?>
I prefer using this class instead of using directly the array $_SESSION.
[#20] math[dot]lechat[at-at]gmail[dot]com [2011-02-14 01:08:25]
"Cannot send session cookie - headers already sent" comes most often when the file is encoded in UTF-8 WITH BOM under Windows.
When transfered on an UNIX server the BOM is considered as text and sent before any header you can define.
[#21] anon at ymous dot com [2011-02-04 01:51:04]
I am trying to get a session created by a browser call to be used by a command line cli->curl php call (in this case, both calls to the same server and php.ini), for a set of flexible media import routines,
but the cli->curl call always starts a new session despite me putting PHPSESSID=validID as the first parameter for the url called by curl.
I was able to fix it by calling session_id($_GET['PHPSESSID']) before calling session_start() in the script called via curl.
[#22] nizamgok at gmail dot com [2011-01-16 23:59:00]
Be aware that when you deliver your flash file through php, you cannot access the session vars that are set from the parent page in Opera, Safari and IE9. I didn't test it with IE6-8. Chrome and Firefox are OK. I don't know the real reason but guessing some of the header data are missing.
swf.php:
<?php
session_start();
//$_SESSION['test'] --> doesn't exist!
//session_id() --> != 'hey123'
header('Content-type: application/x-shockwave-flash');
readfile('/path/to/flash.swf');
?>
index.php"
<?php
session_id('hey123');
session_start();
$_SESSION['test'] = 'test';
?>
<object width="550" height="400">
<param name="movie" value="http://example.com/swf/">
</object>
* swf directory has an .htaccess file which points to swf.php
[#23] dave1010 at gmail dot com [2010-12-17 01:35:59]
PHP locks the session file until it is closed. If you have 2 scripts using the same session (i.e. from the same user) then the 2nd script will not finish its call to session_start() until the first script finishes execution.
If you have scripts that run for more than a second and users may be making more than 1 request at a time then it is worth calling session_write_close() as soon as you've finished writing session data.
<?php
// a lock is places on the session, so other scripts will have to wait
session_start();
// do all your writing to $_SESSION
$_SESSION['a'] = 1;
// $_SESSION can still be read, but writing will not update the session.
// the lock is removed and other scripts can now read the session
session_write_close();
do_something_slow();
?>
Found this out from http://konrness.com/php5/how-to-prevent-blocking-php-requests/
[#24] chong at completemr dot com [2010-12-08 19:11:02]
We are facing a problem and getting an error when loading a php page
Warning: session_start() [<a href='function.session-start'>function.session-start</a>]: Cannot send session cookie - headers already sent by (output started at /www/http/example/zh_CN/unsubscribe.php:1) in /www/http/example/inc/common.php on line 4
We had google and browse through some helps file and found some suggestion as below.
1. Use ob_start to cache any output before session_start function.
2. Make sure the session.save_path in php.ini is set and point to a valid path
We had tried the above but still having some the same problem.
We are using notepad ++ for the coding.
And we notice that this file is somehow being encoded to UTF-8 by one of my colleague because he though that this will help to display the result in the correct languages.
Solution:
Change the encode to use ANSI and make sure the EOL conversion is set to UNIX.
Bingo. Things are back to normal as expected.
Note:
The encode might cause this problem in certain machine but not others. So i had no clue on this. We had no problem running the php code with UTF-8 encode in a 64bits Linux Enterprise but hit the problem running in a 32 bits Linux slackware.
Hope this helps.
[#25] user at annon dot org [2010-08-08 16:48:02]
I recently stumbled upon a problem in my download script where a download link would be clicked but then no other links would work until that download had finished. Other instances/windows would not work either.
This is because session_start() locks the session data until the script finishes. In my case, until the script had finished sending the file data (which in a throttling script can take a while).
The solution is to use session_write_close();
This writes the current session data back to the session and closes the session so that other instances/windows can access the script using the same session.
Since adding it to my script my site can now have several files downloading at once from the same session and still serve pages.
[#26] milanzivanovic at gmail dot com [2010-08-05 13:48:11]
Resolve for:
Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at
is in changing text editor encoding to ANSI or UTF-8 without BOM.
Thanks God I found the answer!
[#27] aladinfajr at gmail dot com [2010-05-31 21:18:06]
my problem was in
session_start();
when i include this term in my first code it show me Warning Message: Cannot Modfie cache limiter
i had tryed many solves and dosn't work
finally
i write my code in other encode
and it sccussfully worked
i hope that help
[#28] info.at.merchandisinginteractive.sk [2010-03-01 18:46:22]
A handy script that checks fot the presence of uft-8 byte order mark (BOM) in all files in all directories starting on current dir. Combined from the work of other people here...
<?php
function fopen_utf8 ($filename) {
$file = @fopen($filename, "r");
$bom = fread($file, 3);
if ($bom != b"\xEF\xBB\xBF")
{
return false;
}
else
{
return true;
}
}
function file_array($path, $exclude = ".|..|design", $recursive = true) {
$path = rtrim($path, "/") . "/";
$folder_handle = opendir($path);
$exclude_array = explode("|", $exclude);
$result = array();
while(false !== ($filename = readdir($folder_handle))) {
if(!in_array(strtolower($filename), $exclude_array)) {
if(is_dir($path . $filename . "/")) {
// Need to include full "path" or it's an infinite loop
if($recursive) $result[] = file_array($path . $filename . "/", $exclude, true);
} else {
if ( fopen_utf8($path . $filename) )
{
//$result[] = $filename;
echo ($path . $filename . "<br>");
}
}
}
}
return $result;
}
$files = file_array(".");
?>
[#29] info at nospam dot mmfilm dot sk [2009-12-29 19:58:54]
For those of you running in problems with UTF-8 encoded files:
I was getting an error because of the BOM, although i set Dreamweaver to "save as" the without the BOM. It appears that DW will not change this setting in already existing files. After creating a new file withou the BOM, everything worked well.
I also recommend http://people.w3.org/rishida/utils/bomtester/index.php - a utility that remote checks for the presence of BOM.
[#30] jamestrowbridge at gmail dot com [2009-12-29 09:57:23]
Unfortunately, after pulling my hair out trying to figure out why my application was working fine in every browser other than IE ( Internet Explorer) (Opera, Chrome, Firefox, Safari are what I've tested this in) - when using a DNS CNAME record (like a vanity name that is different from the DNS A record, which is the hostname of the server) sessions do not work correctly.
If you store a session var while on the CNAME:
vanity.example.com and the hostname of the server is hosname.example.com
Then try to call the variable from a different page, it will not find it because of the CNAME (I guess it store the variable under the hostname, then when trying to read it it's still looking under the CNAME) the same application works fine when accessing it under the hostname directly. Keep in mind that I was testing this on an internal network.
[#31] eugene at ultimatecms dot co dot za [2009-11-24 10:39:50]
Ever get an error like this:
Warning: Unknown: open(/tmp/sess_lLFJ,tk9eFs5PGtWKKf559oKFM3, O_RDWR) failed: Permission denied (13) ?
Don't ask me how, but I managed to fix it by calling
session_id() before session_start(), at the top of the page.
Try it. Hopefully it'll help someone else.
[#32] myemail gerolf at pictureparking dot com [2009-10-08 04:12:01]
please note that at least in php 5.3.0 the setting session.use_only_cookies (in php.ini) defaults to "on". This means that using trans_id, and passing the PHPSESSID via the url does not work untill you change that setting.
[#33] Charlie at NOSPAM dot example dot com [2009-09-22 07:04:44]
Be warned that depending on end of script to close the session will effectively serialize concurrent session requests. Concurrent background "data retrieval" (e.g. applications such as AJAX or amfphp/Flex) expecting to retrieve data in parallel can fall into this trap easily.
Holding the session_write_close until after an expensive operation is likewise problematic.
To minimize effects, call session_write_close (aka session_commit) as early as practical (e.g. without introducing race conditions) or otherwise avoid the serialization bottleneck.
[#34] schlang [2009-07-26 22:44:40]
if you store your sessions in a database, always ensure that the type of the database column is large enough for your session values
[#35] emre@yazici [2009-07-23 14:46:08]
PHP Manual specifically denotes this common mistake:
Depending on the session handler, not all characters are allowed within the session id. For example, the file session handler only allows characters in the range a-z A-Z 0-9 , (comma) and - (minus)!
See session_id() manual page for more details.
[#36] dstuff at brainsware dot org [2009-07-21 05:53:06]
It seems like spaces in the name don't work either - got a new session id generated each time
[#37] abiusx at gmail dot com [2009-07-12 03:03:46]
Working with Comet, or any other parallel or simultaneous requests from a single browser (a single session) would lock the application if it uses a centralized session management.
To fix this, you should add session_commit() (Alias of session_write_close() ) after ALL session management, i.e using any session_* functions except session_start() is forbidden after that an causes an error.
[#38] hperrin at gmail dot com [2009-06-24 13:41:16]
When using session_start() multiple times in one script, it seems to only maintain $_SESSION variables with string keys.
<?php
session_start();
$_SESSION[0] = 'this is a test';
$_SESSION[1] = 'this is also a test';
$_SESSION['test0'] = 'this is a test';
$_SESSION['test1'] = 'this is also a test';
session_write_close();
session_start();
echo "Session var 0 = ".$_SESSION[0]."<br />";
echo "Session var 1 = ".$_SESSION[1]."<br />";
echo "Session var 'test0' = ".$_SESSION['test0']."<br />";
echo "Session var 'test1' = ".$_SESSION['test1'];
?>
Outputs:
Session var 0 =
Session var 1 =
Session var 'test0' = this is a test
Session var 'test1' = this is also a test
[#39] gilthans NOSPAN at gmail dot com [2009-06-04 05:55:09]
If two different files don't access the same session, it can only mean one thing: they aren't on the same directory level.
Examples:
a) One is under https, and one is under http. (very common and annoying error)
b) One is under /, another is under /dir1, and /dir1 was first to run. The cookie created by the session is for /dir1 and deeper only, so the other script can't read it; it sees no session so it starts a new one.
Solutions:
1) Session start should always happen at root dir. If one of your scripts discovers user is not logged in, for example, use session_destroy() and send him to the login in the root dir. Scripts that use session without requiring login needs more creative solutions, like redirecting to the root dir, setting the session, and redirecting back.
2) Use SID from page to page, instead of cookies. The upside is that this also works with http/https. The downside is very ugly URL codes and more difficult maintainability ('which pages links to gallery.php without using SID?!').
[#40] kavih7 at yahoo dot com [2009-05-18 16:52:36]
I ran into a problem that has a solution that may not be quite intuitive to people (well, atleast it wasn't for me). I had one script that called session_start() and that script would run for an indefinite amount of time. I had a second script that would also call session_start(), but would only run for a few seconds each time it is called.
Here is where the problem occurs: Once session_start is called from the long living script, no other script can call session_start until that long running script calls session_commit() (session_write_close()) or ends.
In any case, this may have seem very intuitive to others, but having an abstracted system in place, I never see the session management at the script level, so it was hard to figure out what was locking any other requests.
Hope this helps others.
[#41] Gravis [2009-04-01 11:04:48]
If you want to check if a session has already been activated, you can check $_COOKIE["PHPSESSID"] for a value before reactivating that session.
Example code:
== login.php ==
<?php
session_start();
$_SESSION["data"] = "you have an active session!";
echo "<a href=\"page.php\">go</a>";
?>
== page.php ==
<?php
if(isset($_COOKIE["PHPSESSID"]))
{
session_start();
echo $_SESSION["data"];
}
else
{
echo "no cookies required!";
}
?>
This can prevent forcing a cookie on someone (very annoying in lynx) that doesnt intend to login on your site.
[#42] LaurenceJ44 at Hotmail dot com [2009-04-01 00:36:29]
I kept getting:
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at myfile.php:2)
Only when I had uploaded my pages from my home development server to my hosted website. the same page worked fine in development, so there must be a difference in the php setup, but since this is a site that hosts many different clients web sites, I can't get them to change thier config.
After a little bit of research and trial and error, I found the cure was to move the line:
<?php session_start(); ?>
to be the very 1st line in any .php file.
orginally I had:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?php session_start(); ?>
<html>
<head>
...etc
so I changed it to :
<?php session_start(); ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
...etc
and all is well...
The clue is in the warning message, it ends :2) which means the session_start() call is not on line 1 of the file!
Hope this helps & good Luck
Loz
[#43] microvalen at NOSPAM dot microvalen dot com [2009-03-22 22:09:46]
I have tried many times a lot of login scripts but sometimes when you have a lot of traffic you can note the "overloading" of the server tring to deal with all sessions specialy with the long, long scripts and classes ... checking all stuffs (ids, ips, usernames, etc) the loading page increase ...specialy when you have a "home" server with a small blog..
if you open the folder "/tmp" you will thousands of files that do nothing else that increasing the size of the folder.
Sessions are good and I just offer an alternative.
.. and for that I just created in about 20 min a simple script that can handle a simple login.
<b>(Be aware !! this is just an example .. it not make use of any check of xss atacks or other scripts !!!</b>
and make use of cookies [today all moderns browsers use cookies])
<?php
$mysqli = new mysqli('localhost', 'root', 'pass', 'nameofDB');
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit(); }
$cookie = (isset($_COOKIE['vuid'])) ? $_COOKIE['vuid'] : '';
if(!$cookie) {
$user_level = 0;
setcookie('vuid', '0.' . md5('anonymous')); }
else {
$part = explode('.', $cookie);
$user_level = (int) $part[0];
$user_name = (string) $part[1];
if($user_level != 0) {
$is_logged = check_login($user_level, $user_name); }
else {
$is_logged = false; } }
if(isset($_GET['login'])) {
// here you MUST make a form and a function that realy check the login ...
if($YourFunctionCheckIsOk) {
setcookie('vuid', '9.' . md5('PutTheUserNameHere'));
echo '<meta http-equiv="refresh" content="1;URL=index.php">
Correct Login<br>
You will be redirected to the main page'; } }
elseif(isset($_GET['logout'])) {
setcookie('vuid', '0.' . md5('anonymous'));
echo '<meta http-equiv="refresh" content="1;URL=index.php">
You are out now ... see you soon<br>
You will be redirected to the main page'; }
else {
if($is_logged) {
echo 'Welcome ' . USERNAME . ' <a href="?logout">LOGOUT</a>'; }
else {
echo 'You are a Anonymous. LOGIN <a href="?login">HERE</a>'; } }
function check_login($user_level, $user_name) {
global $mysqli;
$is_logged = false;
$result = $mysqli->query('SELECT nick FROM accounts WHERE user_level = ' . $user_level);
$row = $result->fetch_array();
$result->close();
if($user_name === md5($row['nick'])) {
define('USERNAME', $row['nick']);
return $is_logged = true; }
return $is_logged = false; }
$mysqli->close();
?>
PS: you can change the nick with the ip or better use both !
like:
"level.md5(sha1(nick)).sha1(md5(ip)) etc ...
"0.4aea7c7d495676.4aea7c7d495676"
and check them separetly by <a href="http://php.net/explode">"exploding"</a> them ..
play arround ...
[#44] tchalvakspam at gmail dot com [2009-02-23 13:25:33]
Be aware that if a browser isn't accepting cookies, it can cause the session to invisibly not save between two pages.
So for example, in Firefox 3.0.6 there is a bug where "localhost" addresses are currently not saving cookies. This will kill any attempts to use session code in development where localhost is used.
One workaround for this is to use a different synonym for the localhost address, i.e. http://127.0.0.1/, or set up a virtualhost, e.g. http://localdevelopment/
Overall, pay close attention if you see to different, unexpected session behavior in two different browsers, it may be a result of the cookies being handled differently or being dropped.
[#45] yesmarklapointe at hotmail dot com [2009-02-04 16:32:51]
Here is some info about how to use SID with session_start().
Experiment run on WAMPserver, PHP version 5.2.6.
Using FireFox 3.0.
The definition found at http://www.php.net/manual/en/session.constants.php
describes SID is a ??pre-defined constant?? containing either:
1). the session name and session ID in the form of "name=ID" .
This is the same name as would be returned by session_name(), and the same id as would be returned
by session_id().
2). Or an empty string, if the session ID was set in an appropriate session cookie.
Example code:
<?php
session_start();
echo '<a href="page2.php?' . SID . '">page2</a>';
?>
This code will yield in the browser one of the following:
a). ??page 2?? (as a hyperlink, but mouseover shows the link is to something in the form of
http://www.example.com/page2.php?PHPSESSID=e2bd7072.... )
b). ??page 2?? (as a hyperlink, but mouseover shows http://www.example.com/page2.php? )
Which result is determined by whether or not the browser is sending a matching session cookie back to the script. Result ??a?? above always appears at least initially since the script hasn??t yet set a cookie and neither has it been done automatically yet by the php.ini setting session.use_cookies. However, after refreshing or using the back button, the form in "b" will appear because then the cookie exists (either you set it or session.use_cookies did it automatically).
[#46] info at vanylla dot it [2009-01-30 04:06:12]
If while testing locally on your Windows machine you get many warnigns like:
Warning: session_start()... failed: No such file or directory
Warning: session_start()...: Cannot send session cache limiter - headers already sent
etc.
you need to configure properly the session.save_path in your php.ini file.
Set session.save_path to an existing folder on your PC.
For example: session.save_path="C:\Temp";
[#47] philippe dot latulippe at xxxxgmail dot com [2009-01-11 18:12:21]
When using session_start() with cookies over an encrypted connection (like HTTPS) it is important to set php_ini('session.cookie_secure',true). This sets a flag in the cookie which will stop browsers from sending this cookie over an unsecured connection. If this is not done, a Man-In-The-Middle could easily cause the victim's browser to send his session ID in plaintext, gaining access to the account and defeating the goal of the secure connection.
http://fscked.org/blog/fully-automated-active-https-cookie-hijacking
[#48] zidaine_38 at yahoo dot com [2008-12-05 20:31:25]
<?php
class SESSION
{
public function __construct ()
{
self :: commence ();
}
public function commence ()
{
if ( !isset( $_SESSION ['ready'] ) )
{
session_start ();
$_SESSION ['ready'] = TRUE;
}
}
public function set ( $fld , $val )
{
self :: commence ();
$_SESSION [ $fld] = $val;
}
public function un_set ( $fld )
{
self :: commence ();
unset( $_SESSION [$fld] );
}
public function destroy ()
{
self :: commence ();
unset ( $_SESSION );
session_destroy ();
}
public function get ( $fld )
{
self :: commence ();
return $_SESSION [$fld];
}
public function is_set ( $fld ) {
self :: commence ();
return isset( $_SESSION [$fld] );
}
}
?>
This Class is handy to all who want easy session handling.
Just include () or require () this to pages where you will have to use session.
example:
<?php
include ( "/path/to/sess.inc.php" );
if( !SESSION :: is_set ( "number" ) )
{
SESSION :: set ( "number" , 1 );
}
else
{
$_SESSION ["number"] ++;
}
echo SESSION :: get ( "number" );
?>
[#49] andy_isherwood at hotmail dot com [2008-11-18 06:54:59]
A session created with session_start will only be available to pages within the directory tree of the page that first created it.
i.e. If the page that first creates the session is /dir1/dir2/index.php and the user then goes to any page above dir2 (e.g. /dir1/index.php), session_start will create a new session rather than use the existing one.
[#50] aban at datahouselibya dot com [2008-07-17 08:11:22]
for resolve the problem with session_start()
Cannot send session cache limiter - headers already sent (output started at ..."
write it at first line of the page like
<?php session_start(); ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<body>
<?php $_SESSION['name']='mohamed'; ?>
</body>
<html>
[#51] michael at pythontech dot net dot au [2008-07-13 20:17:15]
@ash
Whilst this may prevent session hijacking attempts, it also ruins the user experience, pressing back and forward will result in the 'security' token being out of sync. Also opening new tabs/ windows will also cause issues.
A better method would be to simply check the ip address or ip block of the user. But this is not without problems either.
To access highly sensitive information, the user should be required to enter his/her password again, even tho they are logged in. This ensures that session hijackers can not access this information.
All this goes hand-in-hand with regenerating session ids on login, and good use of https.
[#52] ash at atomic-network dot co dot uk [2008-05-28 09:33:23]
@My last post...
the function will generate the session "token" you just need to do a check and regenerate it on each page load...
[#53] ash at atomic-network dot co dot uk [2008-05-28 09:29:22]
When developing applications or just creating a general website with the use of sessions, many developers do not think about securing session hijacking attacks. For further information I recommend searching google, however I have produced a small function to be called immediately after session_start().
your_page.php:
<?php
session_start();
include_once 'session_secure.inc.php';
session_secure();
# Your content here.
?>
session_secure.inc.php :
<?php
function session_secure(){
// wrapped for the php entry....
$alph =array('A','a','B','b','C','c','D','d','E',
'e','F','f','G','g','H','h','I','i','J','K','k',
'L','l','M','m','N','n','O','o','P','p','Q','q',
'R','r','S','s','T','t','U','u','V','v','W','w',
'X','x','Y','y','Z','z');
for($i=0;$i<rand(10,20);$i++){
$tmp[] =$alph[rand(0,count($alph))];
$tmp[] =rand(0,9);
}
return implode("",shuffle($tmp));
}
?>
There are quicker ways like md5(time()*rand()), however the function above is completely random, and will render an attackers hijacking task almost impossible.
[#54] vladimir at pixeltomorrow dot com [2008-05-14 07:31:28]
Kind of ankward it's not mentioned here, but you should also trigger the session_write_close() function as soon as possible so you'll release the lock over the session files.
Cheers,
Vladimir Ghetau
[#55] chrismckeeuk at gmail dot com [2008-05-10 12:51:44]
If your sessions are failing to hold the stored data ensure that session.use_only_cookies is set to 1 in your PHP.ini config.
Also using the session auto start saves on a lot of issues and removes the issue of people setting the session_start after the html begins.
[#56] Anthony Catel p at NOSPAM dot rabol dot fr [2008-05-03 08:02:37]
session_start() generate a warning if PHPSESSID contains illegal characters
Warning: session_start() [function.session-start]: The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in /home/para/dev/mon_site/header.php on line 17
To avoid i wrote this :
<?php
function my_session_start()
{
if (isset($_COOKIE['PHPSESSID'])) {
$sessid = $_COOKIE['PHPSESSID'];
} else if (isset($_GET['PHPSESSID'])) {
$sessid = $_GET['PHPSESSID'];
} else {
session_start();
return false;
}
if (!preg_match('/^[a-z0-9]{32}$/', $sessid)) {
return false;
}
session_start();
return true;
}
?>
[#57] php at hogerheijde dot net [2008-02-29 11:53:43]
That's why you shouldn't use register_globals and refer to
$_GET['id']
for the page.php?id=1
or if you don't care if it is GET or POST you can use
$_REQUEST['id']
Those will not be cleared by session_start().
To complete: you should use $_SESSION['id'] to get the content of the session.
[#58] jphansen at uga dot edu [2008-02-25 11:12:11]
I just wrote that session_start() will erase your querystring variable(s) once called. I want to clarify that it will only do this if a variable by the same subscript is defined in $_SESSION[].
[#59] jphansen at uga dot edu [2008-02-25 10:55:00]
Warning, calling session_start() will reset your querystring values.
Navigating to page.php?id=1
<?php
echo "id = $id"; // 1
session_start();
echo "id = $id"; // ""
?>
[#60] fixis at nexus dot com [2008-02-16 06:42:17]
I also found using session_write_close(); after you send your custom headers sometimes helps on some servers. This protects any data from being cleared out by some of these errors mentioned.
[#61] cbake6807 at comcast dot net [2008-02-05 08:20:57]
Having a problem in IE causing your getFile.php script to be pushed to the browser as an empty text file, instead of the intended attachment?
If your php config causes session_start() to output a cookie, or anything funky, IE will not like the filename and will also try and read the file contents inline into the browser window.
Don't use session_start() or USE Output Buffering after the session is started.
<?php //session_start();
function force_download($file)
{
if ((isset($file))&&(file_exists($file))) {
$fileArray = explode("/", $file);
header("Content-type: application/force-download");
header("Content-Disposition: attachment; filename=".$fileArray[sizeof($fileArray)-1]);
header("Content-Transfer-Encoding: Binary");
header("Content-length: ".filesize($file));
header('Content-Type: application/octet-stream');
header("Content-Disposition: attachment; filename=".$fileArray[sizeof($fileArray)-1]);
readfile("$file");
} else {
echo "No file selected";
} //end if
}//end function
?>
[#62] rudylattae at gmail dot com [2008-01-27 17:58:01]
File Encoding was causing my session_start() statement to generate an unexpected warning.
Environment:
OS: Windows XP Pro (32bit)
PHP: v5.2.5
Apache: v2.0.61
I was having this warning:
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at ...
I was rather pissed off because I know of this issue and I know how to fix it:
1) Just make sure the session_start() directive is processed before any other statements that modify the content headers.
2) Failing #1 above, you should also make sure that your script files do not have any beginning/trailing space or carriage return characters.
3) As a last stand, you could use output buffering to hold your stuff in memory and then spit it out at the very end. This would essentially allow you to manipulate the headers to your heart's content without getting any crap from php.
Note: with regards to #2 above, I know some devels use the interesting construct of no closing php braces e.g.:
> info.php
<?php
(they omit this)
phpinfo();
?>
It seems the tag is not required by php (at least php does not puke) so the parser does not treat any trailing spaces as output to be sent to the user agent. I'm not using this loop-hole at the moment.
Anyway the above resolutions *did not* work for me (yer even #3) and I was about to give up and just gag php with good ol "@".
It was then that I thought to check the encoding of my php file. Turns out I had left my editor in UTF-8 encode mode from some previous (i18n) work I had done. I switched to ANSI and that fixed the problem. Suddenly the same file that had caused php to scream in pain was being processed without any issues.
I also noted that I could set the editor to "Encode in UTF-8 without BOM" and that also works. The BOM is the byte order mark which php probably glosses over (or does not understand). I didn't look too far into it.
I hope this helps someone else.
Cheers!
[#63] omnibus at omnibus dot edu dot pl [2008-01-07 03:29:00]
You probably know it but in case somebody did not:
session_start() must be called BEFORE any explicit operations on the $_SESSION variable; otherwise $_SESSION will be treated as an ordinary variable and not stored for future use.
[#64] k dot dafalias at ist dot eduhi dot at [2007-11-14 04:25:31]
If you encounter "The session id contains illegal characters" error, find out, if you get an empty session id.
If so, the problem ist fixed easily:
if(!session_id()) session_regenerate_id();
[#65] ehassler at synapsestudios dot com [2007-09-19 16:32:04]
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.
[#66] (zero)luke(zero)(at)gmail(dot)com [2007-07-06 15:55:00]
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.
[#67] Steffen dot Pietsch at berlinonline dot de [2007-05-15 03:05:33]
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
[#68] Chris Brown [2007-04-24 04:17:31]
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
[#69] leandroico---at---gmail---dot---com [2007-03-17 04:21:44]
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!!!";
?>
[#70] iam1981 [2007-02-26 05:45:45]
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...
[#71] design at ericcorriel dot com [2007-02-15 08:08:34]
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.
[#72] r dot s dot goldsmith at far-blue dot co dot uk [2007-01-24 15:22:41]
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.
[#73] Devour [2007-01-18 14:51:46]
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.
[#74] cppforlife at yahoo dot com [2006-12-18 10:12:09]
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!
[#75] mike at mikebird dot co dot uk [2006-12-10 14:34:40]
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')
[#76] evil dot 2000 at web dot de [2006-10-07 16:06:08]
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.
[#77] Dino [2006-09-30 06:36:42]
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();
[#78] double at dumpit dot de [2006-09-29 19:35:15]
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 ;)
[#79] ben dot morin at spaboom dot com [2006-09-29 09:49:14]
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.
[#80] truthhunter [2006-09-25 17:57:08]
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.example.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...!
[#81] mjr-php at ranney dot com [2006-09-14 09:55:28]
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:
<?php
if(strpos($_SERVER['HTTP_USER_AGENT'],"MSIE")) {
session_cache_limiter('public');
}
session_start();
?>
[#82] roope dot luhtalaNOSPAM at iki dot fi [2006-09-07 10:36:08]
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.
[#83] colemanc at colemanesolutions dot com [2006-08-28 15:30:27]
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.
[#84] core58 at mail dot ru [2006-08-08 06:36:52]
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:)
[#85] devonmitton at gmail dot com [2006-07-26 01:35:49]
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]
[#86] James [2006-07-13 16:22:25]
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();
[#87] saykyo (mail at gmail dot com) [2006-07-12 08:23:23]
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
<?php ?>
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.
[#88] admin at haravikk dot com [2006-05-10 06:00:00]
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 =)
[#89] james at skinsupport dot com [2005-12-22 18:17:33]
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!
[#90] zackbloom at gmail dot com [2005-12-03 23:16:22]
Yes php does not automatically insert the SID in header redirects. You must use something like:
'<address>?SID='.SID
to manually insert the SID.
[#91] jeremygiberson at gmail dot com [2005-10-17 11:13:20]
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:
<?php
session_start();
$_SESSION['forward'] = "This session data will not be lost!";
session_write_close();
header('Location: nextpage.php');
?>
[#92] erm[at]the[dash]erm[dot]com [2005-05-27 13:04:42]
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);
?>
[#93] corey at eyewantmedia dot com [2005-05-19 19:19:40]
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!
[#94] jorrizza at gmail dot com [2005-04-02 05:33:28]
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
?>
[#95] hbertini at sapo dot pt [2005-03-13 12:29:42]
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
[#96] raphael at cynage dot com [2005-02-22 08:35:51]
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.
[#97] m dot kuiphuis at hccnet dot nl [2003-06-24 03:37:29]
[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)
[#98] gadgetguy03 at lycos dot com [2003-06-20 19:18:18]