2012-03-14 24 views
77

thể trùng lặp: Headers already sent by PHPCảnh báo: Không thể sửa đổi thông tin tiêu đề - headers already sent bởi LỖI

Tôi đã đấu tranh với lỗi này trong một thời gian bây giờ.

Để bắt đầu, tôi chỉ nghĩ đó là khoảng trắng, nhưng sau khi nghiên cứu sâu hơn tôi nghĩ rằng nó có thể là một vấn đề tương tự như sau:

Look cho bất kỳ báo cáo có thể gửi kết quả cho người sử dụng trước khi điều này tuyên bố tiêu đề. Nếu bạn tìm thấy một hoặc nhiều, hãy thay đổi mã của bạn để di chuyển câu lệnh tiêu đề trước chúng. Các câu lệnh điều kiện phức tạp có thể làm phức tạp vấn đề, nhưng chúng cũng có thể giúp giải quyết vấn đề. Hãy xem xét một biểu thức có điều kiện ở đầu tập lệnh PHP để xác định giá trị tiêu đề càng sớm càng tốt và đặt nó ở đó.

Tôi đoán tiêu đề bao gồm đang gây ra sự cố cùng với tiêu đề(), nhưng tôi không biết cách sắp xếp lại mã để loại bỏ lỗi này.

Làm cách nào để xóa lỗi?

<?php 
    $username = $password = $token = $fName = ""; 

    include_once 'header.php'; 

    if (isset($_POST['username']) && isset($_POST['password'])) 
     $username = sanitizeString($_POST['username']); 

    $password = sanitizeString($_POST['password']); //Set temporary username and password variables 
    $token = md5("$password"); //Encrypt temporary password 

    if ($username != 'admin') 
    { 
     header("Location:summary.php"); 
    } 
    elseif($username == 'admin') 
    { 
     header("Location:admin.php"); 
    } 
    elseif($username == '') 
    { 
     header("Location:index.php"); 
    } 
    else 
     die ("<body><div class='container'><p class='error'>Invalid username or password.</p></div></body>"); 

    if ($username == "" || $token == "") 
    { 
     echo "<body><div class='container'><p class='error'>Please enter your username and password</p></div></body>"; 
    } 
    else 
    { 
     $query = "SELECT * FROM members WHERE username='$username'AND password = '$token'"; //Look in table for username entered 
     $result = mysql_query($query); 
     if (!$result) 
      die ("Database access failed: " . mysql_error()); 
     elseif (mysql_num_rows($result) > 0) 
     { 
      $row = mysql_fetch_row($result); 
      $_SESSION['username'] = $username; //Set session variables 
      $_SESSION['password'] = $token; 

      $fName = $row[0]; 
     } 
    } 
?> 
+1

'header.php' trông như thế nào? – jeroen

+2

Đặt 'include_once 'header.php';' sau chuỗi 'if ($ username ...' if/else để các tiêu đề chuyển hướng không được gọi sau khi đầu trang HTML là đầu ra. –

+2

Giả sử rằng không có dấu cách trước < Trong tập tin bạn liệt kê, có một số đầu ra xuất hiện trong tập tin header.php, dự định hay không.Nếu header.php thực sự phải tạo ra một số đầu ra, thì bạn nên đặt điều kiện đăng nhập trước khi bạn bao gồm header.php, nếu không bạn sẽ chỉ cần đi vào và loại bỏ bất kỳ đầu ra nào được tạo ra trong tệp header.php. Nhiều khả năng là thủ phạm, theo kinh nghiệm của tôi, là khoảng trắng thừa trước thẻ mở . Không thấy bất kỳ ký tự nào trước lỗi, bạn đang tìm kiếm khoảng trắng – Jason

Trả lời

220

Câu trả lời dài hạn là tất cả các đầu ra từ kịch bản PHP của bạn nên được đệm trong các biến. Điều này bao gồm các tiêu đề và đầu ra của cơ thể. Sau đó, ở cuối kịch bản của bạn làm bất kỳ đầu ra bạn cần.

Việc sửa chữa rất nhanh chóng cho vấn đề của bạn sẽ được thêm

ob_start(); 

là điều đầu tiên trong kịch bản của bạn nếu bạn chỉ cần nó trong một kịch bản này. Nếu bạn cần nó trong tất cả các kịch bản của bạn thêm nó như là điều đầu tiên trong tập tin header.php của bạn.

Thao tác này sẽ bật tính năng đệm đầu ra của PHP. Trong PHP khi bạn xuất một cái gì đó (làm một tiếng vang hoặc in) nếu có để gửi các tiêu đề HTTP tại thời điểm đó. Nếu bạn bật bộ đệm đầu ra, bạn có thể xuất ra trong tập lệnh nhưng PHP không phải gửi tiêu đề cho đến khi bộ đệm bị xóa. Nếu bạn bật nó lên và không tắt nó đi PHP sẽ tự động tuôn ra tất cả mọi thứ trong bộ đệm sau khi kịch bản kết thúc chạy. Có thực sự là không có hại chỉ cần bật nó trong hầu như tất cả các trường hợp và có thể cung cấp cho bạn một sự gia tăng hiệu suất nhỏ theo một số cấu hình.

Nếu bạn có quyền truy cập để thay đổi file cấu hình php.ini của bạn, bạn có thể tìm và thay đổi hoặc thêm những điều sau

output_buffering = On 

này sẽ lần lượt ra đệm ra mà không cần phải gọi ob_start().

Để tìm hiểu thêm về kiểm tra bộ đệm đầu ra, hãy xem http://php.net/manual/en/book.outcontrol.php

+0

@SamHennesy nơi nào tôi phải thêm ob_start() dưới tiêu đề hoặc ở đầu trang? – Sharif

+1

@Sharif, hãy làm càng sớm càng tốt. Nếu đó là sự khởi đầu của trang thì đó. Phần lớn thời gian không có hại trong việc gọi ob_start(). – SamHennessy

+0

Đây có phải là thực hành tốt không? Tôi có nghĩa là kể từ khi 'PHP' là ném một lỗi không có nghĩa là có thể có một cách tốt hơn để làm điều đó. – James111

10

Kiểm tra cái gì đó với echo, print() hoặc printr() trong file bao gồm, header.php.

Có thể đây là vấn đề HOẶC nếu có bất kỳ tệp MVC nào, sau đó kiểm tra số lượng khoảng trống sau ?>. Điều này cũng có thể gây ra vấn đề.

5

Có một số vấn đề với header() cuộc gọi của bạn, một trong số đó có thể gây ra vấn đề

  • Bạn nên đặt một exit() sau mỗi header("Location: cuộc gọi khác đang thực hiện sẽ tiếp tục
  • Bạn nên có một không gian sau : để nó đọc "Location: http://foo"
  • Không hợp lệ để sử dụng URL tương đối trong tiêu đề Location, bạn nên tạo một URL tuyệt đối như http://www.mysite.com/some/path.php
+0

Nhưng tất cả các url tương đối của tôi trong 'header()' đang làm việc ngoại trừ một. – Siraj

5

Bạn đang cố gửi thông tin tiêu đề sau khi xuất nội dung.

Nếu bạn muốn làm điều này, hãy tìm output buffering.

Các vấn đề liên quan