I know this question has been asked many times but I have seen so many different answers and have tried them all and none have worked for me. So let me provide you with my specific context, and see what you recommend:
I am developing on Mac OS X El Capitan. I am using PHP version 5.5.31. error message
I have output buffering turned on in my php.ini file. I have obsessively checked there is no white space before the header is sent. Here are the lines the code is referring to:
(edit_subject.php:6)
<?php require_once("../includes/session.php");?>
<?php require_once("../includes/db_connection.php");?>
<?php require_once("../includes/functions.php");?>
<?php require_once("../includes/validation_functions.php");?>
<?php find_selected_page();?>
<?php
if(!$current_subject){
**redirect_to("manage_content.php")**;
}
?>
(edit_subject.php:38)
$result = mysqli_query($connection, $query);
if ($result && mysqli_affected_rows($connection) >= 0) {
// Success
$_SESSION["message"] = "Subject edited succesfully.";
**redirect_to("Location: manage_content.php");**
} else {
// Failure
$message = "Subject update failed.";
}
(functions.php:3)
<?php
function redirect_to($new_location) {
redirect_to("Location: . $new_location");
exit;
?>
I've been pulling my hair out for the last 48 hours. I'd appreciate some guidance here.
Thanks,
Chris
The following line is triggering the warning (functions.php line 3):
redirect_to("Location: . $new_location");
It is attempting to send headers, after something has already been output (probably another error/warning considering your syntax is broken). Check your error logs.
try flushing the buffer before redirecting. the problem arises if there is already something outputted and you try changing the header in this case by redirection.
You can use ob_start() at top, and ob_end_flush() to flush before changing the header.
Note: Flushing the buffer only hides the problem, its not the solution. There's some piece of bad practice of coding, try figure that out.
Related
This question already has answers here:
How to fix "Headers already sent" error in PHP
(11 answers)
Closed 9 years ago.
I am still getting that error when I run my code. Here is my code.I removed all white spaces as well.my form on my html goes to my php (action="lib/login.php") file to check if user exists. If it exist, then redirect.
dbconnect.php just connects to my database. can anyone help?
FOLDER Layout:
lib
-dbconnect.php
-login.php (code located below)
index.html
<?php
require_once("dbconnect.php");
$loginuser = $_POST['username'];
$loginpw = $_POST['password'];
$usertable = "Users";
$users="Username";
$pw="Password";
$query = "SELECT $users, $pw FROM $usertable WHERE $users='$loginuser' AND $pw='$loginpw'";
$result = mysql_query($query);
$num_rows = mysql_num_rows($result);
if (!$result) {
die('Invalid query: ' . mysql_error());
}
if ($num_rows>0) {
header("Location:../index.html");
exit();
}
?>
This message appears if you try to send a HTTP header after you already made some output. This is because in HTTP there comes first the headers and then the body. As ouput goes to the body, it is impossible to send headers anymore after output.
As there is no echo, print or whatever output function used in your code, output can be generated by
A PHP errror message
Content before the opening <?php
To 1:
The ob_* set of functions is a good way to catch all output a script regardless if this are error messages or regular output. So you could add the line:
ob_start();
direct after the opening <?php tag.
Then before the call to header() add:
if(ob_get_size() > 0) {
// there was an error, display it and exit
ob_end_flush();
die();
}
Note that in production environment you should disable the display of error messages at all as they can contain sensitive information. You can do by settings display_errors in php.ini to 0 or per script by:
ini_set('display_errors', 0);
To 2:
Assuming that the code you have posted is the complete content of the php file (no spaces or empty lines before <?php ) it could be that you have a problem with the UTF-8 BOM char. BOM means byte order mark and is used internally by the utf-8 encoding. And it is not visible in a text editor. :)
To remove it, there are several solutions out there.. will google one for you ..... http://www.w3.org/International/questions/qa-byte-order-mark.en.php
Does any body has any idea how to find where the leak is that provokes this "Content Encoding Error" with $config['compress_output'] = true in CodeIgniter?
I've trying to debug this error for days, but I can't seem to find where the leak is. LogLevel is at debug but I see no info in the log when this error happens.
So, any ideas how to debug this?
UPDATE
I really don't want to disable the compress_output feature, I just want to see how can I trace where the error is produced
UPDATE2
I've looked over and over again to see if there is any output in the controllers... and there is none, so some where else must be the error provoked. No models/database, just controllers, libraries, helpers and views
This issue is where the output buffering starts. The check for the config variable is in system/core/Output.php in _display(). It starts the gzipped buffering after a lot of code has already run. This leaves the potential for output to have occurred before it buffering starts.
With compress_output set to false it doesn't matter because nothing is encoded. With it set to true you end up with mixed content. Some output is encoded and some is not which causes the compression error.
There are two solutions:
1) You could leave compress_output set to false and add ob_start('ob_gzhandler'); to the top of your index.php file. This will ensure that all output is always gzipped, including errors.
2) The other solution is to add ob_flush(); before ob_start('ob_gzhandler'); in system/Output.php. This will gzip output when there are no errors and serve you unencoded content when there are errors.
I think 2 is the better solution and should be implemented by the CodeIgniter team. But if you don't want to muck with the system code (changes will go away when you upgrade) then 1 is the better solution for you.
This might be a long shot, but if you echo/print database output directly from your controller instead of sending it to the model you'll likely get error messages that have to do with output buffering. Are you echoing from your controller?
Putting the following line in config.php:
$config['compress_output'] = FALSE;
Solves it. The problem in my case was that I sent the post, but it did not recognize the FILLCATEGORIAS function. Inly by changing the $ config [ 'compress_output'] = FALSE; solved it.
THIS problem occurred when we send data using a POST request:
Failed to load resource: net::ERR_CONTENT_DECODING_FAILED
<script type="text/javascript">
$(document).ready(function() {
$("#idEmpresa").change(function() {
$("#idEmpresa option:selected").each(function() {
id = $('#idEmpresa').val();
$.post("<?php echo base_url();?>Admin/fillCategorias", {
idEmpresa : id
}, function(data) {
$("#idCategoria").html(data);
});
});
});
});
</script>
Any error in PHP will break compression.
To test this, in index.php change:
error_reporting(E_ALL);
to
error_reporting(E_ALL ^ E_NOTICE);
Do not echo/print to display output from controller.
Do not use "?>" at the end of controller file.
I hope it helps.
Update:
To check if the output is empty before starting buffering, you can open core/Output.php and add
ob_flush();
before
ob_start('ob_gzhandler');
If there is even a space or an empty line, compression will fail. (check page source from browser). This happens because with $config[‘compress_output’] = true , ob_start('ob_gzhandler') (line 379 in Output.php) is executed, wich will cause a "Cannot modify header information - Headers already sent ..." warning. This warning is the cause of compression failure.
So basically, any echo outside of Output class (json output included) will send headers to client, which will cause "Cannot modify header information - Headers already sent ..." warning, which will cause the "content encoding error".
I had the same problem. After searching, I found that my controller has ?> at end of file. So I removed it and it works perfectly. Here is a link for more detail.
More compliant solution:
$this->output->set_output($data);
Some CPanel lightspeed extension updates create this problem. You can try adding this code in your .htaccess file:
php_flag zlib.output_compression ON
I have a function, 'redirect_to()' written on php script that is called after a successful update to a page on my custom CMS. It works fine on the localhost, but when I try it on my actual live domain I get the following error message:
Warning: Cannot modify header information - headers already sent by (output started at /hermes/bosweb/web119/b1192/ipg.typaldosnetcom/edit_listing.php:7) in /hermes/bosweb/web119/b1192/ipg.typaldosnetcom/includes/functions.php on line 20
Here is the code for the redirect_to() function:
function redirect_to ($location = NULL) {
if ($location != NULL) {
header("Location: {$location}");
exit;
}
}
I've made sure to call the function before I output any HTML, so I'm not sure what the problem really is.
My question: Why am I receiving this error?
It's not lying. You've output something before getting to this point. Check the locations mentioned in the error messages.
Show us the first 25 lines of each of the files mentioned.
you already sent your output to the page before you set the header. first you need to set the headers and then can the output come.
It can even be a whitespace.
It means something was already outputted on the suggested line. Try going there and see what it does.
Try pasting the surrounding code on that position for a better clarification if you can't find the problem yourself.
One common cause is to have a line after a php file you're including...
Simple solution: remove the closing php tag "?>" from all files as it's not needed..
You can test if you have a character before the opening php-script tag by removing any closing php-script tag. This way you are sure there isn't any character left (it's not needed).
Use output buffering:
<?php
ob_start();
// Test buffered output.
echo 'hello world';
function redirect_to ($location = NULL) {
if ($location != NULL) {
header('Location: ' . $location);
exit;
}
}
// rest of php file here
ob_end_flush();
?>
Docs: ob_start() and ob_end_flush()
Whenever PHP outputs an error message it disregards css and a beautifully designed page by outputting the message at the top of the page removing anything that stands in its way.
for example
some code} else {
echo "error, please do something!";
How do I get it to (or ask it nicely) to output the text inside a div that already exists inside my css so that it will obey the formatting and alignment rules that comes with that div.
You can use the following php.ini settings:
error_prepend_string = "<div class='error'>"
error_append_string = "</div>"
Or something to that effect.
EDIT
Actually, I just realized the "error" you're talking about involves an echo/print out. Here's the problem.
You're printing (echoing) the string error DIRECTLY TO the output buffer (which sends the HTML to the browser when you're finished running all your code). echo() and print() sends what you are echoing/printing straight out, unless it's in an output_buffer block (I won't confuse you with details on that).
So, you're managing your regular html/text output in such a way as to NOT print the page content out to the output buffer, but in this case you are using an echo, which sends the string data directly to the buffer AT THAT MOMENT.
For instance:
Your problem in a simple example
<?php
$mystr = "<html>";
$mystr .= "<body><h1>Hello World</h1></body></html>";
echo "<head></head>";
echo $mystr;
?>
Which would give me on output to the browser:
<head></head><html><body><h1>Hello World</h1></body></html>
I am storing the string data, but echoing the HEAD block before I echo the other html data.
What I need to do instead:
<?php
$mystr = "<html>";
$mystr .= "<head></head>";
$mystr .= "<body><h1>Hello World</h1></body></html>";
echo $mystr;
?>
Which would give me on output to the browser:
<html><head></head><body><h1>Hello World</h1></body></html>
I am storing the string output (your error, in this case) until I need to output it later. This is what you need to know, and accomplish in your code.
I would investigate error_reporting(0)/display_errors, error_get_last, and set_error_handler.
http://www.php.net/manual/en/function.error-reporting.php
http://www.php.net/manual/en/errorfunc.configuration.php#ini.display-errors
http://php.net/manual/en/function.error-get-last.php
http://www.php.net/manual/en/function.set-error-handler.php
So that you could stop sending all errors immediately to the output buffer (which is why it's at the top of the page), and then capture, store and present your errors.
error_reporting(0);
set_error_handler('phpLogError');
function phpLogError() {
$error = error_get_last();
if ($error['type'] == 1) {
//do your stuff
}
}
function phpGetLoggedErrors() {
// return your prettified html errors
}
Or, in other words...
php_error_handle.php
<?php
$GLOBAL['_logged_php_errors'] = array();
error_reporting(0);
set_error_handler('phpLogError');
function phpLogError() {
global $_logged_php_errors;
$error = error_get_last();
if ($error['type'] == 1) {
$_logged_php_errors[] = "<span>$error</span>";
}
}
function phpGetLoggedErrors() {
global $_logged_php_errors;
return "<ol><li>".implode('</li><li>',$_logged_php_errors)."</li></ol>";
}
?>
other.php
<?php
require_once 'php_error_handle.php';
// other stuff, pages included/required, etc...
Just make sure this require_once happens at the first line of code.
Extending #mario above, I've used this at the top of my php file (in dev, not production of course!) which works great. Even in Wordpress admin files!
ini_set('error_prepend_string',"<div class='error'>") ;
ini_set('error_append_string',"</div>") ;
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
Try...catch
http://php.net/manual/en/language.exceptions.php
You can make the error echo in your own css.
echo '<div class="yourerrorclass">error, please do something!</div>';
If it is in the wrong place in the output, that is because you output the error too soon. The entire HTML is outputted sequentially by PHP. If you output the error before any of the other HTML, the error will be on the top of the page and will actually make your HTML invalid.
Displaying errors to screen should be entirely suppressed when running in production, instead log them to file for checking, and fixing. There are details, and the suggested settings in the php.ini file.
After so much trouble I find out that when I use the flush function in my PHP mail script then I get garbage or dump characters on browser like below.
The code is below
if ($mail->Send()) {
echo "<br><font color=darkgreen>[$num successful send to $to]</font> ";
// flush();
return true;
}
If I comment that flush line then out is simple English but I uncomment that the whole page the text looks like garbage.
Now is that a PHP problem, browser problem or server problem?
If I use the same script from the shell, I mean execute inside the shell terminal then I can see the HTML output. But it does not work in browsers.
I found the answer to my own question. I had to turn
zlib_compression off
in my php.ini settings file.
(What does that mean and why did it work?. I had been trying this for 1 year but could not resolve the problem but now it worked.)