1

I have a main webpage that logs in and redirects using header() without any problems.

I also have another webpage that would need to log in, so I made another login.php page for it.

Both webpages have the same structure, in fact I just copy-pasted the main webpage into the other webpage and changed var names, etc

If I log in in the main webpage everything is allright, no warnings. But if I log in in the other webpage I get the following warning:

Warning: Cannot modify header information - headers already sent by (output started at /home/aet/platform.corporativelines.com/themes/aet/main.php:12) in /home/aet/platform.corporativelines.com/pages/login.php on line 18

This is main.php:12

<title>AET | <?php print $title ?></title>

And this is login.php line 18

header("Location: /home");

The main webpage have the same in those lines, exactly the same but no warnings... Can someone tell me why?

Both webpages are in a subdomain, but main is just temporary, I'll move it when is finished. Maybe that have something to do... (If you want to visit, "pre" is the temporary subdomain)

The framework is the same for both webpages, the custom session start function have the domain set to ".domain.com" like says here.

PHP Code:

index.php (both websites):

ini_set('display_errors', '1');
//requires and initializations
$hasExpired = $web_user::sec_session_start();
$client = $web_user->login_check(); // FALSE OR CLIENT

$isLogged = false;
$includes1 = array(
        '/pages'                        => $pages . 'pages.php'
);

if ($client != false) {
    $isLogged = true;
    $includes2 = array(
        '/morepages'                    => $pages . 'morepages.php'
    );
}
else {
    $includes2 = array(
        '/otherpages'                   => $pages . 'otherpages.php'
    );
}
$includes = array_merge($includes1, $includes2);

$url = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
//some more security checks for url
$title = $lang->getW($url);

include('themes/aet/main.php');

main.php (both websites):

<?php
    defined('_AET') or die();
?>
<!DOCTYPE html>
//html structure
<title>AET | <?php print $title ?></title>
//body
//main
<?php

    $include = '/404';

    if (array_key_exists($url, $includes)) {
        $include = $url;
    }

    include($includes[$include]);
?>

login.php (both websites):

// login post, checks and call to function
if ($login_array[0] == "OK") {
    header("Location: /home");
}
// login form html

I can say they are the same pages in both webpages.

EDIT: Sorry I have not been clear. In both websites I have ini_set('display_errors', '1'); In the main website I'm not getting any error plus the header() redirection is working fine. In the other website I'm getting the error, if I disable them, the error won't show but neither the redirection will work.

Chazy Chaz
  • 1,781
  • 3
  • 29
  • 48
  • Is it possible that one has error reporting turned off? So the error exists, but is not being displayed? – sharf Jun 02 '15 at 17:14
  • No, sorry, I forgot to add: in index I have ini_set('display_errors', '1'); In both index.php – Chazy Chaz Jun 02 '15 at 17:16
  • 1
    ^^ if that is the difference, then it would explain why you see the error there though it definitely occurs in both. [This is the reason for the errors](http://stackoverflow.com/questions/8028957/how-to-fix-headers-already-sent-error-in-php) -- you cannot have _any output of any kind_ before a `header()/session_start()/setcookie()` call, but you have `AET | <?php print $title ?>` other HTML, and probably some whitespace before them. – Michael Berkowski Jun 02 '15 at 17:17
  • But it's only giving the error in the other page. In the main webpage I don't see the error. – Chazy Chaz Jun 02 '15 at 17:18
  • The reasons for this error are already well explained on stackoverflow. To determine which is the case here we would need to know how main.php is invoked from login.php but according to the code you posted they are unrelated. – symcbean Jun 02 '15 at 17:25
  • @MichaelBerkowski I commented all prints in the main.php of the other webpage and nothing the error is still happening. But in the main website I have that print working and no error, how can you explain that? – Chazy Chaz Jun 02 '15 at 17:27
  • @ChazyChaz It isn't only `echo/print` causing problems. All the HTML code which precedes the PHP and `header()` counts as output sent to the output buffer and down to the client browser. There can be no output of any kind generated before sending headers. All of what you have in ` //html structure` etc... interferes with subsequent `header()` calls – Michael Berkowski Jun 02 '15 at 17:35
  • But why is only giving the error in the other page? Because in the main website I'm not getting any error... – Chazy Chaz Jun 02 '15 at 17:40
  • @MichaelBerkowski And yes, there are differences between the two websites, but both includes the login page in the middle of the main.php which is mainly html code. Why is giving the error only in one of the two websites? – Chazy Chaz Jun 02 '15 at 17:45
  • @ChazyChaz Because you have `display_errors` enabled on only one of them, correct? I can assure you that it _does_ produce the error on both, but may not display it on screen. If you watch your web server's error log and have `error_reporting` set to `E_ALL` or at least showing warnings, you will see the same error for `main.php`. – Michael Berkowski Jun 02 '15 at 17:47
  • I have ini_set('display_errors', '1'); in the second line of index.php for both websites. That's why I'm getting paranoid... :( And I just tested it, I disabled it ini_set('display_errors', '0'); and yes the error is not shown but the redirect isn't working. In the main website the redirection is working perfectly! I'll get crazy :P – Chazy Chaz Jun 02 '15 at 17:49
  • @MichaelBerkowski You can try the login in both websites (pre.corporativelines.com and platform.corp...) using test@test.com and test. I can even give you ftp access if you don't believe me... I know every error/problem have an explanation, but in this case it's something weird... – Chazy Chaz Jun 02 '15 at 18:13
  • It's possible that the main domain has output buffering enabled whereas the other domain doesn't ... in any case, you shouldn't have a `header()` statement after HTML mode has started. – Ja͢ck Jun 03 '15 at 04:29
  • So if you enable the output buffering you don't get that error? What is the problem then in using header after dom output? But I'd like to find an alternative to that redirection, because using javascript reloads the whole webpage instead of just including the desired page. Is there any alternative that can just do that? – Chazy Chaz Jun 03 '15 at 15:32

2 Answers2

0

In main.php it looks like you are outputting php comments - check carefully if anything (including white space) is output from PHP before your DOCTYPE (i.e. the first line of HTML output).

If you have a PHP script that does this:

<?php
print "before headers: will cause a problem";
?>
// this will also cause text to be output 
<!DOCTYPE html>
<html> ...

you will have a problem. If that is not the case, can you post the entire beginning of main.php.

  • I just added the firsts 4 lines of main.php. It's odd because in the main website I'm not getting the error... And both are copy pasted, must be some change I made... Well I don't have the if $hasExpired check in the main website, but that can't be the problem... So in the main main.php I only have 1 print before the include but in the other main.php I have 3 prints... I'm going to check it out. – Chazy Chaz Jun 02 '15 at 17:21
  • defined() returns true or false - I think you need to wrap that in a if() statement? If you want to use die() - then put in an error message. Look up try/catch and Exceptions for better error control, remove the //php style comments from the HTML header part, and retry. – Nicholas Alexander Jun 02 '15 at 17:26
  • Sorry, I don't have any php/html comments in main.php (I just deleted the commented code) and I'm still seeing the error but not in the main webpage. I don't know why... – Chazy Chaz Jun 02 '15 at 17:30
  • Sorry again, in the main website I have more than 1 print in main.php before I include pages. I'd like to know why in one website I'm not getting the error but in the other site I'm getting it... – Chazy Chaz Jun 02 '15 at 17:37
  • Any output before the DOCTYPE should give a warning, even if it is just an unintended piece of whitespace. Perhaps there are instances when the message is not seen (does not mean it is not happening). The full text of the warning is: Warning: Cannot modify header information - headers already sent by (output started at main.php:12) in login.php on line 18 - so what is on main.php:12? – Nicholas Alexander Jun 02 '15 at 22:18
0

The "problem" was (first) calling header() after output and (second) having output_buffering enabled.

To solve this, I just moved the login post script (and any other script that calls header()) to another file and include it in index.php before including the main.php (before the HTML/Dom output starts).

if ($url == '/login') {
    include('pages/headers/login_post.php');
}

// now we can safely start the DOM output
include('themes/main.php');
Chazy Chaz
  • 1,781
  • 3
  • 29
  • 48
  • 1
    It's not really a mystery; the output buffer keeps the output form being sent to the client until it reaches a certain size, or when the script exits (whichever comes first); therefore, a header can still be sent before that size is reached. It's still a bad practice, though. – Ja͢ck Jun 03 '15 at 04:33
  • Yes, a bit hacky. I'll find another way then. And I'll post it. – Chazy Chaz Jun 03 '15 at 15:33