I have a situation where I need to call session_start() in the middle of the file multiple times. Obviously, as session_start() outputs buffer, I get the following warnings:
Warning: session_start(): Cannot send session cookie - headers already sent by...
Warning: session_start(): Cannot send session cache limiter - headers already sent...
There was a lot of written on StackOverflow about header related warnings caused by session_start(). Now before you decide to mark this post as a duplicate, please continue reading - you will see, it is different.
Most of the proposed solutions in the other threads recommend putting session_start() at the beginning of the file, before any PHP output is made. This can be suitable solution if session_start() needs to be called only once per file - however, it is not my case.
I have a file download script (see the code below.) My script regularly, during the file download, updates '$_SESSION' variables with download progress status. I have then another script regularly issued through AJAX requests, which monitors download progress and informs my JavaScript code.
To avoid locking the $_SESSION variables, I therefore have to call session_start() and session_write_close() multiple times per file download, which occurs in a loop in the PHP file.
As every subsequent call to session_start() returns the warnings, which in my case are injected into the downloaded file, is there any programmatically correct way of suppressing them?
Two solutions come to my mind now, but I am not happy with none of them:
calling #session_start() instead of session_start() - this is not considered as a good practice, as it suppresses all warnings and errors returned by the function.
calling ob_clean() to empty the output buffer at the end of every file write iteration, to remove the warnings injected into the buffer to be written to the file. - in this case, the warnings are still present, I do not correctly manage the situation, I simply erase the warning and ignore it.
So my question, please, how to correctly call session_start() and session_write_close() multiple times per file and avoid getting warnings?
Code Sample:
<?php
//...
// file download in small pieces
while(!feof($file_source))
{
$chunk_data = fread($file_source, $chunk_size);
print($chunk_data);
ob_flush();
flush();
$bytes_already_transferred += strlen($chunk_data);
$percent_complete = round(($bytes_already_transferred / $file_size) * 100);
// update session variable, but how to avoid warnings?
if (session_status() == PHP_SESSION_NONE) session_start();
$_SESSION['DownloadProgress'] = $percent_complete;
session_write_close();
usleep(1000);
}
fclose($file_source);
?>
Related
I am having this error in PHP:
session_start(): Cannot send session cache limiter - headers already
sent
I know I have to put session_start() even before the html <head>, what I am doing. The issue here is that I am using id containers for ajax generated content.
For example, I have a button in the homepage.php which updates some calculate.php file in a divResults, and this calculate.php begins with session_start(). However, this warning is appearing inside divResults.
How could I solve it. Is it possible to simply ignore the warning. How?
(I don't have this problem in XAMPP, only using an external hosting provider)
Thanks
Based on your problem following errors may possible.
you write session_start(); in somewhere middle or end of the .php file so you need to put session_start();at top of .php file just after <?php.
May be some empty lines are there in your .php file at the beginning or end, because of that also this error will arise. remove those empty line.
I have written the below script (snipped) that includes the WordPress functions, however it appears one of the plugins is trying to start a session when it has already been started:
<?php
define('WP_USE_THEMES', false);
require('../../../wp-blog-header.php');
...
?>
I get the following in my php errors log:
<b>Warning</b>: session_start(): Cannot send session cookie - headers already sent in <b>/home/sp32/public_html/wp-content/plugins/woocommerce-abandon-cart-pro/woocommerce-ac.php</b> on line <b>44</b><br />
<br />
<b>Warning</b>: session_start(): Cannot send session cache limiter - headers already sent in <b>/home/sp32/public_html/wp-content/plugins/woocommerce-abandon-cart-pro/woocommerce-ac.php</b> on line <b>44</b><br />
I'm assuming this is an error in the plugin itself, however I want to prevent these warnings from showing in my log file for my specific script. How would I go about that? Ideally I don't want to hide all warnings, just this one.
Note that is not a duplicate- I am not asking how to fix the issue (because the issue lies in a 3rd party plugin), I am asking how to suppress the warning messages.
There are three options I see here:
Fix the offending code. As you have mentioned, this may not be optimal with 3rd party code.
Ask for a refund, and replace this plugin with something well written; specifically, something that abides by an accepted coding standard such as PSR-2, or pear.
Find where the offending files are included (or offending functions are called and wrap them in calls to change the error reporting level (code below). The downside to this is that your sessions will not work, since the headers have already been sent by the plugin; this prevents a session cookie from being set, making the browser unrecognized by php sessions.
$previousErrorLevel = error_reporting();
error_reporting(\E_ERROR);
//offending code inclusion or call here
error_reporting($previousErrorLevel);
I am getting pretty annoyed with an issue with my log in and register scripts that are not working. The funniest thing is that for two weeks ago I used the exact same scripts in another website in another server and it works awesome!
ISSUE
When I try to register or log in I am not redirected to the page I was supposed to be. On register.php the user gets registered (I can see it on the database) but I am not redirected to the login.php, instead the script get's crashed on the message "redirecting you to xxxx.php". Here you can read my scripts.
I took contact with my server (ipage) and asked if something was going wrong with their system. I got 3 different and crossed answers:
1st) I was able to replicate your issue. I did some preliminary troubleshooting and was not able to get to the root cause of the issue.
2nd) They answered me later that they were able to register new users and log in with no problem
3rd) Final answer was that the issue was on my scripts
I am not sure of what is happening here because the scripts are not working (on the opposite to what they say). I wonder if they are lying because they simply are no good or can't find out the cause of the problem. Anyway, the error log says the following:
*"20131014T033118: url.org/folder/login.php
PHP Warning: session_start(): Cannot send session cookie - headers already sent by (output started at /hermes/bosweb26a/b366/ipg.domainname/folder/folder/common.php:1) in /hermes/bosweb26a/b366/ipg.domainname/folder/folder/common.php on line 77 "*
Line 77 is: header('Content-Type: text/html; charset=utf-8');. If I take it out, the error just passes on to another line...
Presuming that I already debugged the scripts and found no error, could this be due to the server's quality? (PHP version f.i.?)
You can put session_start() on the first line ok common.php
You need to make sure session_start() is called before calling header(), or echoing any content. So in login.php, you need to make sure session_start() is either at the top of the page, or you need to move it so it is called much earlier in your script, at least before any header() calls.
Just switch round session_start and header('Content-Type: text/html; charset=utf-8'):
// This initializes a session. Sessions are used to store information about
// a visitor from one web page visit to the next. Unlike a cookie, the information is
// stored on the server-side and cannot be modified by the visitor. However,
// note that in most cases sessions do still use cookies and require the visitor
// to have cookies enabled. For more information about sessions:
// http://us.php.net/manual/en/book.session.php
session_start();
// This tells the web browser that your content is encoded using UTF-8
// and that it should submit content back to you using UTF-8
header('Content-Type: text/html; charset=utf-8');
Have you got a space before <?php as the top of common.php? If you do you need to remove it.
Personally i use ob_start(); after the session_start(); and ob_flush() at the end of the file;
This question already has answers here:
How to fix "Headers already sent" error in PHP
(11 answers)
Closed 9 years ago.
I have written <?php session_start(); ?> above everything in all pages. Some pages are rendering fine but I am getting this error in other pages. I have checked and matched each page code and code is fine. If I remove <?php session_start(); ?> then page renders fine but I need to use session.
Cannot send session cache limiter - headers already sent (output started at /home/) in ...
One thing to note is: It runs fine on my local server.
I would bet it's one of two things:
Make sure there is no output, including newlines, in your file before you call session_start. PHP must send HTTP headers first (before the message body, i.e. page content), so trying to send a header after you've already sent page content will give you that error.
You should only call session_start only once per page. If you're using include in a file after you've called session_start, make sure you're not calling session_start again in the included file. This would cause the "headers already sent" error.
you have some output (maybe an whitespace) in one of your included files.
maybe your <?php is not the very first of your file somewhere.
You could also try to use output buffering (http://php.net/manual/es/function.ob-start.php). I'd first check to see whether you are not sending any output by mistake (as #steven suggests), but still, it might be a good idea for you to buffer your outputs.
Since you are including multiple files, and you seem to have a session_start() in multiple files, I bet the error is thrown in the second file.
Check all files for the session_start(), and for whitespace before any of these are called.
This is a very typical BOM header problem. I suspect that your editor stored a UTF-8 BOM header with 3 bytes  at the begin of the file. The editor will hide them, so if you are not sure if your file contains these characters, you can either use a non interpreting editor (hex editor), or this wonderful online W3C checker.
I don't think it's reasonable.
Why is it actually such a rule?
In the "normal case", I don't think ob_start has to be called before session_start -- nor the other way arround.
Quoting the manual page of session_start, though :
session_start() will register internal
output handler for URL rewriting when
trans-sid is enabled. If a user uses
ob_gzhandler or like with ob_start(),
the order of output handler is
important for proper output. For
example, user must register
ob_gzhandler before session start.
But this is some kind of a special case : the thing is, here, that the order of output handlers is important : if you want one handler to modify things the other did, they have to be executed in the "right" order.
Generally, if you don't use that kind of handlers (Apache and mod_deflate do a great job when it comes to compressing output, for instance), the only thing that matters is that headers must not be sent before you call session_start (because, depending on your configuration, session_start sends cookies, which are passed as HTTP headers).
And headers are sent as soon as any piece of data has to be sent -- ie, as soon as there is any output, even one whitespace outside of <?php ?> tags :
Note: If you are using cookie-based
sessions, you must call
session_start() before anything is
outputted to the browser.
ob_start indicates that PHP has to buffer data :
This function will turn output
buffering on. While output buffering
is active no output is sent from the
script (other than headers), instead
the output is stored in an internal
buffer.
This way, output is not sent before you actually say, yourself, "send the data". This means headers are not send immediatly -- which means session_start can be called later, even if there should have been output, if ob_start had not been used.
Hope this makes things a bit more clear...
If by default your output_buffering is Off and you have been unfortunate enough to send a single byte of data back to the client then your HTTP headers have already been sent. Which effectively prevents session_start() from passing the cookie header back to the client. By calling ob_start() you enable buffering and therefore delay sending http headers.
session_start might want to modify the HTTP header if certain configuration options are set. One for example is session.use_cookies that requires to set/modify the Set-Cookie header field.
Modifying the HTTP header requires that there isn’t any output that’s already sent to the client as the HTTP header is sent right before the first output is sent.
So you either ensure that there is absolutely no output before the call of session_start. Or you use the output buffering control to buffer the output so that the HTTP header can be modified even if there already is output.
session_start() will register internal output handler for URL rewriting when trans-sid is enabled. If a user uses ob_gzhandler or like with ob_start(), the order of output handler is important for proper output.
For example, the user must register ob_gzhandler before session start.
But this is some kind of a special case. The thing is, here, that the order of output handlers is important. If you want one handler to modify things the other did, they have to be executed in the "right" order.
Generally, if you don't use that kind of handlers (Apache and mod_deflate do a great job when it comes to compressing output, for instance), the only thing that matters is that headers must not be sent before you call session_start (because, depending on your configuration, session_start sends cookies, which are passed as HTTP headers).
And headers are sent as soon as any piece of data has to be sent -- ie, as soon as there is any output, even one whitespace outside of <?php ?> tags :
Note: If you are using cookie-based sessions, you must call session_start() before anything is outputted to the browser.
ob_start indicates that PHP has to buffer data :
This function will turn output buffering on. While output buffering is active no output is sent from the script (other than headers), instead the output is stored in an internal buffer.
This way, output is not sent before you actually say, yourself, "send the data". This means headers are not send immediatly -- which means session_start can be called later, even if there should have been output, if ob_start had not been used.
session_start(); should be called before any headers are sent out. ob_start() will suppress the output for a while and you can break this rule. Usually ob_start() on the top is a quick fix in case you are debugging something unknown; everything below works as expected (not just as written ;-)). I prefer to use ob_start() later to session_start().
In PHP, ob_start() is used to start output buffering. Output buffering captures all output sent to the browser and stores it in a buffer, allowing you to manipulate it before sending it to the browser.
When using sessions in PHP, it is important to call ob_start() before starting the session, as sessions rely on cookies, which are sent to the browser as part of the HTTP headers. If any output has already been sent to the browser before the session is started, the headers will have already been sent and it will not be possible to set the session cookies.
By calling ob_start() before starting the session, any output that is generated before the session is started will be captured by the buffer and will not be sent to the browser. This allows the session cookies to be set correctly, even if some output has already been generated.
In summary, ob_start() is necessary for session in PHP because it ensures that headers can be sent correctly even if there is output generated before the session is started.