I have asked this question thousands times, and yet can not even understand the basic and fundamental cause of the problem. What does it mean, by " check if any data is outputted before calling a header ?" That is all I am receiving lately. Take the below sentences as a code for a moment. ( Just imagine if it were a code and tell me the problem ) I am doing this to simplify the question. if(user is logged in) {echo you are logged in} echo "This is login form "; if(submit button is pressed) { $pass is sanitize(pass) and $user = sanitize(user) all sanitation goes here ' if all is good { set session and redirect user by heder("to index page"); } } Now, what is wrong behind this idea that is causing me header already sent errors? please tell. It's killing me
if you using header redirect function on php, that mean your code need to output nothing before the line. Header redirect actually send http response to the browser with 403 http code to redirect to specific location, so it can't be preceded by anything else before.
Ok. But what if I have a log in function, and after user enters username + password. I will need to re-direct that user. So, in principle, the header can only be placed after authentication has been done, and this usually means after the sql queries, after wrong username/password errors, after wrong mails, after so many things. So, how can I place header at the top ?
if you want to do that on one file, that you need to check what kind of request it is... here the snipet ------------------------------------------------------------------- if(it is post request) { // means that user has submited the form... sanitize input... do credential check... if(user authorized) { redirect to dashboard... } set some error code... } show the form here... you can also check if there is some error, then show error message according to it.. -------------------------------------------------------------------------------- see we only redirect before anything outputed by our code.
When you and other say " before anything outputted" are you referring to anything specifically echoed before the header function? or any dorman code even pure html is placed before the header(); code? Because you are saying it should be before all, and yet in your snippet above, you have placed if(it is post request) { // means that user has submited the form... sanitize input... do credential check... if(user authorized) { those above lines before redirect? Thanks btw, I am getting close to knowing the answer now, since yesterday. I was gonna give up on my site.
one thing you should aware is, php are parsed on the server, than it will output html (actually not usually html) and send them to the browser via http response. what i mean by outputing something is, before your code outputed something that will be parsed by the server as an output... it can be something that echoed or printed by the code, or something outside your php tag (something outside your <?php ?>) my code above will check if is the post request and do the authorization check, if it found that user authorized than it will send redirect header to user and quit. My code doesn't output anything untill reach the redirect line.
To be specific, you can't use header() if your code has already sent any output to the user. This means your PHP code where the header() function resides must be processed before any HTML is output and before the PHP scripts have processed an echo() or print() functions. And all PHP files (including any included files) must begin with the "<?php" tag and end with the "?>" tag, and the ending ">" must be the last character in the file with no trailing \n or \r characters.
a little recommendation from PHP guys: if your php file is contain only php script, the closing tag "?>" should be omitted to prevent extra character placed accidentally after the closing tag to be parsed as output.
This is the code and the header that is giving me a headache. what should I do? should I place the header at the top?
here the line that make the problem: echo "<p class=\"blue\"> Login Form </p>"; Code (markup): this line will always executed on every request. just place it below the if that check the request, and make anything inside the if not echoed directly, but rather to store it on some variable: rather than: echo " <span class=\"error\" > Please, fill in both fields to continue </span> "; Code (markup): used something like: $output = " <span class=\"error\" > Please, fill in both fields to continue </span> "; Code (markup): do that for all echo on the if section. after that you can check if the variable is set than output it. here my quick fix: <?php if(isset($_POST['login'])){ $password = mysql_real_escape_string($_POST['password']); $username = mysql_real_escape_string($_POST['username']); $password_md = md5($password); if(empty($username) or empty($password)){ $error = " <span class=\"error\" > Please, fill in both fields to continue </span> "; } #()# else { $query = "SELECT * FROM el_users WHERE el_username = '$username' AND el_password = '$password_md'"; $result = mysql_query($query); if(mysql_num_rows($result)==0) // <-- If NO rows are returned { $error = " <span class=\"error\" > Invalid login details! Please try again or get your password here </span> " ; } #()# else if(mysql_num_rows($result)==1) // <-- If ONE row is returned { $my_session = mysql_result ($result, 0, 'u_id'); // <-- If user is Authentic, Start session $_SESSION['clans'] = $my_session; header('location:index.php') ; die; } } } if(logged_inn()) { echo "Your are logged in"; } echo "<p class=\"blue\"> Login Form </p>"; if(isset($error) && !empty($error)) { echo $error; } Code (markup):
A php file starts with <?php If there's anything before that, even a blank line or a space, it causes that error. PHP sends headers before it sends anything else. [table="width: 10"][tr][td] [/td][td]<?php[/td][/tr][/table] sends a space, so it sends headers, then a space. Then you can't send any headers. A redirect is a header, so you get the error. If you use the output buffer, it won't happen. Everything is put into the buffer then, at the end of the page you send the entire buffer, so PHP sends headers, then the entire buffer, all at once, including your headers. <?php ob_start(); //all your code here ob_flush(); ?> PHP:
Thank you, guys. Specially, tkcoding I understand the problem now. So, the answer is: No! echo or printf or white spaces before the <?php tags But, ob_start(); seems a good idea too. Is it recommeded as a good practice to use ob_start(); or is it just a hack?
It's specifically there to use if you must send headers after you output. (It's pretty mandatory if you're using headers to debug.) It's considered good practice and it's not considered a hack. <?php ob_start(); at the beginning of every file (my PHP template included that as the first 2 lines) ensures that you won't throw the error regardless of where you output a header. (Don't forget to flush the buffer at the end of the file, or some of your output may never be sent.)