0

I'm getting this:

Warning: Cannot modify header information - headers already sent by

(output started at /www/zxq.net/a/l/e/alexchen/htdocs/index.php:12) in /www/zxq.net/a/l/e/alexchen/htdocs/common.php on line 13

right on my h2 tag.

I have my common.php before the html code. I don't know what the problem is. Help!

index.php:

<?php
include_once 'common.php';
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
    <title>New Project</title>
    <link rel="stylesheet" type="text/css" href="styles/global.css" />
    <link rel="stylesheet" type="text/css" href="styles/slimbox2.css" />
    <script type="text/javascript" src="scripts/jquery-1.3.2.min.js"></script>
    <script type="text/javascript" src="scripts/jquery.validate.js"></script>
    <script type="text/javascript" src="scripts/slimbox2.js"></script>
    <script type="text/javascript" src="scripts/jquery.scrollTo-min.js"></script>
    <script type="text/javascript" src="scripts/jquery.localscroll-min.js"></script>
    <script type="text/javascript" src="scripts/custom.js"></script>
    <?php if(get_lang()=='en') {echo '<script type="text/javascript" src="scripts/jquery-validate/val-en.js"></script>';} ?>
    <?php if(get_lang()=='es') {echo '<script type="text/javascript" src="scripts/jquery-validate/val-es.js"></script>';} ?>
    <?php if(get_lang()=='tw') {echo '<script type="text/javascript" src="scripts/jquery-validate/val-tw.js"></script>';} ?>
    <?php if(get_lang()=='cn') {echo '<script type="text/javascript" src="scripts/jquery-validate/val-cn.js"></script>';} ?>

common.php:

<?php
session_start();
header('Cache-control: private'); // IE 6 FIX

function get_lang(){
    if(!empty($_GET['lang'])) return $_GET['lang'];
    if(!empty($_SESSION['lang'])) return $_SESSION['lang'];
    if(!empty($_COOKIE['lang'])) return $_COOKIE['lang'];
    return 'en';
}

function set_lang($lang){
    setcookie("lang", $lang, time() + (3600 * 24 * 30));
    $_SESSION['lang'] = $lang;
}

function get_lang_file($lang){
    $lang_file = "languages/lang.$lang.php";
    if(file_exists($lang_file)) return $lang_file;
    if($lang_file = get_lang_file('en')) return $lang_file;
    return false;
}

//translation helper function
function l($string){
    static $translation;

    if(!isset($translation)){
        $lang = get_lang();
        $lang_file = get_lang_file($lang);
        if($lang_file) set_lang($lang);
        $translation = include $lang_file;
    }

    return $translation[$string];
}
?>
alexchenco
  • 53,565
  • 76
  • 241
  • 413
  • Have you already read all the question about it?: http://stackoverflow.com/search?q=php+headers+sent This is very common question. – Felix Kling Feb 27 '10 at 09:32
  • takle a look at this question http://stackoverflow.com/questions/2243087/warning-cannot-modify-header-information-headers-already-sent – meouw Feb 27 '10 at 10:20
  • possible duplicate of http://stackoverflow.com/questions/1183726/headers-already-sent-in-php, http://stackoverflow.com/questions/1891969/php-headers-already-sent-error – outis May 05 '10 at 00:29

4 Answers4

2

It can happen for several reasons:

  1. You are sending HTTP headers indirecly, via setcookie() or session_start().

    Have a look at your set_lang() function. You can fix it by calling l() before output.

  2. You have whitespace before the PHP open tag or after PHP close tag.

  3. You saved the file in UTF-8, but with BOM. Save it without BOM.

You can always add ob_start(), but this will only bypass the problem.

Sagi
  • 8,009
  • 3
  • 26
  • 25
2

Your l() function is calling set_lang() the first time it is used, which sets a cookie -- and cookies are sent as HTTP-headers.

I'm guessing, from the look of it, that l() is used to get the translated version of a string -- which means it's probably used from everywhere in your HTML/PHP ; i.e. after the output has begun being sent.

You should call set_lang() at the top of your common.php file -- to make sure the cookie is sent before any HTML content.


In fact, in your case, I would modify the l() function so it only does one thing : return a translated string.

I would put the initialization of your translation system out of l() -- which means initializing it "by hand" at the beginning of your script, yes ; but also means a simpler l() function that will have less work to do.

Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
  • @Pascal MARTIN, thanks for the reply. I changed it to: – alexchenco Feb 27 '10 at 09:46
  • From the look of this, it seems you declared your functions at the beginning of `index.php`, which is one thing ;; but you didn't call `set_lang()` "by hand" ;; which means that's still the firt call to `l()` that will cause `set_lang()` to be called, and cookies to be sent ;; you should call `set_lang()` from the beginning of your `index.php` file, so the cookie is sent before any output. – Pascal MARTIN Feb 27 '10 at 09:54
  • janoChen you can call l() with empty string right after session_start(), so it will set the headers. another possibility would be to use ob_start(), as already said. Have another look at my answer. – Sagi Feb 27 '10 at 09:55
  • @Pascal MARTIN, please can you give me a code example of what you just suggested? – alexchenco Feb 27 '10 at 09:56
  • @janoChen : just after the line that contains `include_once 'common.php';` try calling something like `set_lang(get_lang());` so the cookie is sent right away -- or do as @Sagi suggested in his comment, which should get the same result. – Pascal MARTIN Feb 27 '10 at 10:00
  • @Pascal MARTIN I'm not sure it will work, because he uses static variable in l(), which means that anyway he'll set cookie in first call. – Sagi Feb 27 '10 at 10:02
  • @Sagi : well seen about that static variable ; you're right ! ;;; @janoChen : @Sagi's suggestion is what you should do, then : after `include_once 'common.php';`, call the `l()` function to get a first *(that you won't use)* translation, to initialize it and sent the cookie. – Pascal MARTIN Feb 27 '10 at 10:04
  • @Sagi, so what should I do? I deleted the $string as you suggested in the comment above and the whole code fails. How do you do that? – alexchenco Feb 27 '10 at 10:04
  • @janoChen Just call l() after session_start() (in common.php) or after include_once 'common.php' (in index.php). – Sagi Feb 27 '10 at 10:06
  • @Sagi, @Pascal Martin I did this: ...and still getting the error. – alexchenco Feb 27 '10 at 10:44
  • @Pascal Martin I also tried this: which solves the problem but now I have this: Notice: Undefined index: in /www/zxq.net/a/l/e/alexchen/htdocs/common.php on line 35 – alexchenco Feb 27 '10 at 10:52
1

Setting a cookie requires sending a header, so you cannot call set_lang() once you have output any of the page unless you use the output buffering functions.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
0

Try putting ob_start() function at the top of file where you are getting this error.

Sarfraz
  • 377,238
  • 77
  • 533
  • 578