doubledee Posted August 10, 2011 Share Posted August 10, 2011 I am getting a strange "Header already sent" error message. This is happening when I go from my "articles_index.php" page - which lists a summary of each article - to my article template file "article.php" which is where I swap in and out the relevant article from my database. Here is my abridged code from "article.php" if (isset($_GET['category']) && isset($_GET['title'])){ // Category and Title exist. $category = $_GET['category']; $title = $_GET['title']; // Build query. // Prepare statement. }else{ // No Title exists. // Take user to Home Page. header("Location: " . WEB_ROOT . "index.php"); } Below is what happens when you click on different article pictures and different article links. (Admittedly, some of these links are from when I was just using an "id" to identify articles, but the point is that I do not believe that an invalid query string or an old-style link to a physical file should cause the error I'm getting?!) Scenarios: Scenario #1: <a href="<?php echo WEB_ROOT ?>article.php?category=articles&title=all-about-creating-dynamic-content"> Outcome: Works. Article is displayed. Scenario #2: <a href="point_to_some_file.php">(Read Full Story)</a> Outcome: File Not Fund Scenario #3: <a href="<?php echo WEB_ROOT ?>article.php?category=articles&title=some_other_name"> Outcome: Works. "Sorry! The article you were looking for could not be found." Scenario #4: <a href="some_other_file_name.php">(Read Full Story)</a> Outcome: File Not Found Scenario #5: <a href="<?php echo WEB_ROOT ?>article.php?category=articles&title=guide-to-quickbooks"> Outcome: Works. Article is displayed Scenario #6: <a href="<?php echo WEB_ROOT ?>article.php?id=1">(Read Full Story)</a> Outcome: Warning: Cannot modify header information - headers already sent by (output started at /Users/user1/Documents/DEV/++htdocs/01_MyProject/article.php:14) in /Users/user1/Documents/DEV/++htdocs/01_MyProject/article.php on line 68 If I add this code at the beginning of my file... // Start Output Buffering. ob_start(); ...and this code in my ELSE branch... // Send and turn off output buffering. ob_end_flush(); // End script. exit(); ...then the error goes away, but I have no clue what is causing this error?! I thought this error was caused when you send characters to the screen before you try to send Header data? How is sending an improperly formatted query string or an invalid file or path related?! Thanks, Debbie Quote Link to comment https://forums.phpfreaks.com/topic/244369-strangeinconsistent-header-already-sent-message/ Share on other sites More sharing options...
gizmola Posted August 10, 2011 Share Posted August 10, 2011 If an error is being generated, output will be sent because you have display errors on. You would not have this setting turned on for a production server. Don't turn on output buffering unless you completely understand what it is for, and have a good reason to use it. Quote Link to comment https://forums.phpfreaks.com/topic/244369-strangeinconsistent-header-already-sent-message/#findComment-1255129 Share on other sites More sharing options...
doubledee Posted August 10, 2011 Author Share Posted August 10, 2011 If an error is being generated, output will be sent because you have display errors on. You would not have this setting turned on for a production server. Isn't an error also being sent with a "Page Not Found"? Since I don't plan on having incorrectly formatted query strings, can I just ignore this error? Don't turn on output buffering unless you completely understand what it is for, and have a good reason to use it. Can you elaborate? I read a book that says to turn it on when you are doing things that could send output to the screen and thus cause such an error. Debbie Quote Link to comment https://forums.phpfreaks.com/topic/244369-strangeinconsistent-header-already-sent-message/#findComment-1255131 Share on other sites More sharing options...
trq Posted August 10, 2011 Share Posted August 10, 2011 The book was describing a hack that should not be used IMO. The simple answer is, don't try and send content before sending headers. Quote Link to comment https://forums.phpfreaks.com/topic/244369-strangeinconsistent-header-already-sent-message/#findComment-1255161 Share on other sites More sharing options...
Morg. Posted August 10, 2011 Share Posted August 10, 2011 As thorpe said, there isn't any real reason to do that anyway -- and the page not found error does not come from PHP, it's apache that sent it because the referred URL did not match anything. Quote Link to comment https://forums.phpfreaks.com/topic/244369-strangeinconsistent-header-already-sent-message/#findComment-1255330 Share on other sites More sharing options...
doubledee Posted August 10, 2011 Author Share Posted August 10, 2011 The book was describing a hack that should not be used IMO. The simple answer is, don't try and send content before sending headers. I understand this, however, it really doesn't answer my question... Why is it that Scenario #6 behaves the way it does? I don't see why that scenario with that particular invalid query string sends data and blows things up? (Sorry for not getting this.) Also, since I will presumably have the *correct* query string, do I need to worry about error-handling in case this did happen, or is it assumed if it works it will always work?! Debbie Quote Link to comment https://forums.phpfreaks.com/topic/244369-strangeinconsistent-header-already-sent-message/#findComment-1255382 Share on other sites More sharing options...
DavidAM Posted August 10, 2011 Share Posted August 10, 2011 output started at /Users/user1/Documents/DEV/++htdocs/01_MyProject/article.php:14 Read the error message, it tells you exactly what file and what line in that file sent output to the screen. You need to look at line 14 (and the surrounding lines) of article.php. It is sending some output to the browser. If there are other error messages, they are likely causing this error. Fix the other errors first. I would suspect that you are referencing the "category" or "title" element of $_GET without first checking to see if they exist. Never assume it will always work. If a user types your query string into the address bar, and spells "category" wrong, you will get the same error. Always check to see if the query string contains what you are expecting and act accordingly if it does not. Quote Link to comment https://forums.phpfreaks.com/topic/244369-strangeinconsistent-header-already-sent-message/#findComment-1255390 Share on other sites More sharing options...
doubledee Posted August 10, 2011 Author Share Posted August 10, 2011 output started at /Users/user1/Documents/DEV/++htdocs/01_MyProject/article.php:14 Read the error message, it tells you exactly what file and what line in that file sent output to the screen. You need to look at line 14 (and the surrounding lines) of article.php. It is sending some output to the browser. If there are other error messages, they are likely causing this error. Fix the other errors first. I would suspect that you are referencing the "category" or "title" element of $_GET without first checking to see if they exist. Never assume it will always work. If a user types your query string into the address bar, and spells "category" wrong, you will get the same error. Always check to see if the query string contains what you are expecting and act accordingly if it does not. Here is my code starting at Line 14... <?php // Access Constants require_once('config/config.inc.php'); // Connect to the database. require_once('private/mysqli_connect.php'); // Initialize variables. $articleExists = FALSE; $id = $metaDescription = $metaKeywords = $title = ''; $pageTitle = $pageSubtitle = $writtenOn = $author = $body = $endNotes = ''; // $id = 1; if (isset($_GET['title'])){ // Title exists. $title = $_GET['title']; // Build query. $q = 'SELECT meta_description, meta_keywords, page_title, page_subtitle, written_on, author, body, end_notes FROM article WHERE title=?'; // Prepare statement. $stmt = mysqli_prepare($dbc, $q); Last night I took out "Category" for other reasons, but the logic of the code above is the same. And you'll see I am using ISSET() so that should take care of the one issue you mentioned above. Any ideas? Thanks, Debbie Quote Link to comment https://forums.phpfreaks.com/topic/244369-strangeinconsistent-header-already-sent-message/#findComment-1255412 Share on other sites More sharing options...
DavidAM Posted August 10, 2011 Share Posted August 10, 2011 Here is my code starting at Line 14... Are you saying that line 14 is <?php? If so, what are the 13 lines above that? Anything outside of the opening tag is sent to the browser as content. Post everything from the beginning of the file through line 20 or so (preferably through the header() call that is producing the error). Is this "line 14" from the code that produced the error message that said the output started at line 14? In other words, you said you changed the code, is the error message still indicating line 14 as the start of output? If you use View Source in your browser, what do you see? Anything before the error message is output you need to eliminate. If the header error is the only thing you see, then something might be sending whitespace (a space, tab, or newline) to the browser. Quote Link to comment https://forums.phpfreaks.com/topic/244369-strangeinconsistent-header-already-sent-message/#findComment-1255439 Share on other sites More sharing options...
doubledee Posted August 10, 2011 Author Share Posted August 10, 2011 Here is my code starting at Line 14... Are you saying that line 14 is <?php? Yes, I gave you lines 14 onward... If so, what are the 13 lines above that? Anything outside of the opening tag is sent to the browser as content. Post everything from the beginning of the file through line 20 or so (preferably through the header() call that is producing the error). Is this "line 14" from the code that produced the error message that said the output started at line 14? In other words, you said you changed the code, is the error message still indicating line 14 as the start of output? If you use View Source in your browser, what do you see? Anything before the error message is output you need to eliminate. If the header error is the only thing you see, then something might be sending whitespace (a space, tab, or newline) to the browser. Here are lines 1 - 14... <?php // // Start Output Buffering. // ob_start(); // Initialize a session. session_start(); // From article at: http://shiflett.org/articles/the-truth-about-sessions $fingerprint = 'SHIFLETT' . $_SERVER['HTTP_USER_AGENT']; $_SESSION['fingerprint'] = md5($fingerprint . session_id()); ?> <?php Could the blank line on Line 13 cause an issue? Debbie Quote Link to comment https://forums.phpfreaks.com/topic/244369-strangeinconsistent-header-already-sent-message/#findComment-1255450 Share on other sites More sharing options...
PFMaBiSmAd Posted August 10, 2011 Share Posted August 10, 2011 Could the blank line on Line 13 cause an issue? Yes, that line is outside of php any tags and is sent as is to the browser. FYI - The php tokens generated (which must all be executed when your code runs) by putting a closing php tag, some in-line html (a new-line) and an opening php tag is - T_CLOSE_TAG T_INLINE_HTML T_OPEN_TAG Quote Link to comment https://forums.phpfreaks.com/topic/244369-strangeinconsistent-header-already-sent-message/#findComment-1255471 Share on other sites More sharing options...
DavidAM Posted August 10, 2011 Share Posted August 10, 2011 Yes, it will. That blank line is being sent to the browser. The documentation indicates that the newline "immediately following" the closing tag will not be sent. But the blank line has another newline, and I'm sure that one will be sent. There really is no reason to break out of PHP there, you could just remove the closing tag and the following opening tag; PHP loves blank lines, it will just eat them up! <?php // // Start Output Buffering. // ob_start(); // Initialize a session. session_start(); // From article at: http://shiflett.org/articles/the-truth-about-sessions $fingerprint = 'SHIFLETT' . $_SERVER['HTTP_USER_AGENT']; $_SESSION['fingerprint'] = md5($fingerprint . session_id()); // Access Constants require_once('config/config.inc.php'); // Connect to the database. You may also want to watch out for HTTP_USER_AGENT. There is no guarantee that every user agent will send this value. And if it is not there, that line of code will produce a notice, which, if display_errors is on, will be sent to the browser and will cause the header call to fail again. You might try: $fingerprint = 'SHIFLETT' . (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''); Quote Link to comment https://forums.phpfreaks.com/topic/244369-strangeinconsistent-header-already-sent-message/#findComment-1255474 Share on other sites More sharing options...
doubledee Posted August 10, 2011 Author Share Posted August 10, 2011 FYI - The php tokens generated (which must all be executed when your code runs) by putting a closing php tag, some in-line html (a new-line) and an opening php tag is - T_CLOSE_TAG T_INLINE_HTML T_OPEN_TAG That went over my head. Two things... 1.) People keep talking to me about "tokens" lately and I totally don't understand what they mean?! 2.) I have no clue of what you are giving me above... Debbie Quote Link to comment https://forums.phpfreaks.com/topic/244369-strangeinconsistent-header-already-sent-message/#findComment-1255489 Share on other sites More sharing options...
doubledee Posted August 10, 2011 Author Share Posted August 10, 2011 You may also want to watch out for HTTP_USER_AGENT. There is no guarantee that every user agent will send this value. And if it is not there, that line of code will produce a notice, which, if display_errors is on, will be sent to the browser and will cause the header call to fail again. You might try: $fingerprint = 'SHIFLETT' . (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''); Thanks for the suggestion. (I know I'm bad sanitizing my data when it comes to ISSET.) If I do that will that handle any and all issues? I got that code offline to help with my Comments module. (Honestly, I forgot what that even does?!) Debbie Quote Link to comment https://forums.phpfreaks.com/topic/244369-strangeinconsistent-header-already-sent-message/#findComment-1255495 Share on other sites More sharing options...
DavidAM Posted August 10, 2011 Share Posted August 10, 2011 That will handle cases where the user-agent string is not provided. I don't know what the "fingerprint" is used for, so I can't say it is the perfect solution; but it will prevent that line of code from throwing an error. And since user-agent strings are not unique, it will probably provide the same functionality. As for tokens: computer languages have to be executed by a computer. So there is usually a parsing process that converts the source code we write into "tokens" that the computer can process. Usually, tokens are represented (internally) as integers. This makes it much easier for the computer to read and execute the code -- since all integers are the same size, they can use jump tables and offsets to determine what the instruction is. Otherwise, they would have to determine the length of the string (i.e. "print") and then determine the address of the (internal) function to call, and then figure out where the parameters are, and so forth. Yes, the computer still has to do this, but it does it in the parsing phase. If it did not do it up front, whenever it executed a loop, it would have to interpret the same source code over and over -- source code that DOES NOT CHANGE during the loop -- that is a waste of time. How it all works is advanced, internals stuff, and in general programmers rarely need to worry about tokens and jump tables. In this case, PFMaBiSmAd was showing the tokens that were generated by your code (actually, the human representation of the tokens, not the actual integers). As you can see, there is HTML in there, which is what was being sent to the browser and causing your error. I had never considered using the tokenizer as a debugging tool, ... but, there ya go. Quote Link to comment https://forums.phpfreaks.com/topic/244369-strangeinconsistent-header-already-sent-message/#findComment-1255519 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.