Jak naprawić błąd Nagłówki już wysłane w PHP

Podczas uruchamiania skryptu otrzymuję kilka błędów takich jak ten:

Ostrzeżenie: Nie można modyfikować informacji nagłówka - nagłówki zostały już wysłane przez (wyjście rozpoczęło się w /some/file.php:12) w /some/file.php w linii 23

Wiersze wymienione w komunikatach o błędach zawierają header() i setcookie() połączeń.

Co mogłoby być tego przyczyną? Jak to naprawić?


person Community    schedule 06.11.2011    source źródło
comment
przeczytaj: stackoverflow.com/questions/1912029/   -  person Book Of Zeus    schedule 06.11.2011
comment
Upewnij się, że nie został wyświetlony żaden tekst (tutaj mogą okazać się przydatne ob_start i ob_end_clean() ). Następnie możesz ustawić plik cookie lub sesję równą ob_get_contents(), a następnie użyć ob_end_clean() do wyczyszczenia bufora.   -  person Jack    schedule 04.04.2014
comment
Użyj funkcji safeRedirect w mojej bibliotece PHP: github.com/heinkasner/PHP -Biblioteka/blob/master/extra.php   -  person heinkasner    schedule 24.07.2014
comment
~~~~~~~~~~ Kodowanie Twojego pliku nie powinno mieć wartości UTF-8, ale UTF-8 (Without BOM)~~~~~~~~~~~   -  person T.Todua    schedule 19.09.2014


Odpowiedzi (11)


Brak danych wyjściowych przed wysłaniem nagłówków!

Funkcje wysyłające/modyfikujące nagłówki HTTP muszą zostać wywołane przed wykonaniem jakichkolwiek danych wyjściowych. podsumowanie ⇊ W przeciwnym razie połączenie nie powiedzie się:

Ostrzeżenie: nie można modyfikować informacji nagłówka — nagłówki zostały już wysłane (wyjście rozpoczęło się od script:line)

Niektóre funkcje modyfikujące nagłówek HTTP to:

Dane wyjściowe mogą być:

  • Zamierzone:

    • print, echo and other functions producing output
    • Surowe <html> sekcje przed kodem <?php.

Dlaczego tak się dzieje?

Aby zrozumieć, dlaczego nagłówki muszą zostać wysłane przed wyjściem, należy przyjrzeć się typowej odpowiedzi HTTP. Skrypty PHP generują głównie treść HTML, ale przekazują także zestaw nagłówków HTTP/CGI do serwera WWW:

HTTP/1.1 200 OK
Powered-By: PHP/5.3.7
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8

<html><head><title>PHP page output page</title></head>
<body><h1>Content</h1> <p>Some more output follows...</p>
and <a href="/"> <img src=internal-icon-delayed> </a>

Strona/wyjście zawsze podąża za nagłówkami. PHP musi najpierw przekazać nagłówki do serwera WWW. Może to zrobić tylko raz. Po podwójnym podziale linii nie można już ich zmieniać.

Kiedy PHP otrzyma pierwsze wyjście (print, echo, <html>), opróżni wszystkie zebrane nagłówki. Następnie może wysłać dowolne dane wyjściowe. Jednak wysłanie dalszych nagłówków HTTP jest wtedy niemożliwe.

Jak dowiedzieć się, gdzie wystąpiło przedwczesne wyjście?

Ostrzeżenie header() zawiera wszystkie istotne informacje umożliwiające zlokalizowanie przyczyny problemu:

Ostrzeżenie: nie można modyfikować informacji nagłówka — nagłówki zostały już wysłane przez (wyjście rozpoczęło się od /www/usr2345/htdocs/auth.php:52) w /www/usr2345/htdocs/index.php w linii 100

Tutaj linia 100 odnosi się do skryptu, w którym header() wywołanie nie powiodło się.

Wyjście rozpoczynające się od notatki w nawiasie jest bardziej znaczące. Oznacza źródło poprzedniego wyniku. W tym przykładzie jest to auth.php i linia 52. To tam trzeba było szukać przedwczesnych wyników.

Typowe przyczyny:

  1. Drukuj, echo

    Zamierzone wyjście z instrukcji print i echo zakończy możliwość wysyłania nagłówków HTTP. Aby tego uniknąć, należy zrestrukturyzować przepływ aplikacji. Używaj funkcji i schematów szablonów. Upewnij się, że header() wywołania mają miejsce zanim wiadomości zostaną zapisane.

    Funkcje generujące dane wyjściowe obejmują

    • print, echo, printf, vprintf
    • trigger_error, ob_flush, ob_end_flush, var_dump, print_r
    • readfile, passthru, flush, imagepng, imagejpeg


    i funkcje zdefiniowane przez użytkownika.

  2. Surowe obszary HTML

    Nieprzeanalizowane sekcje HTML w pliku .php również są bezpośrednim wyjściem. Warunki skryptu, które wyzwolą wywołanie header(), muszą zostać zapisane przed jakimkolwiek nieprzetworzonym <html> blokiem.

    <!DOCTYPE html>
    <?php
        // Too late for headers already.
    

    Użyj schematu szablonów, aby oddzielić przetwarzanie od logiki wyjściowej.

    • Place form processing code atop scripts.
    • Użyj tymczasowych zmiennych łańcuchowych, aby odroczyć wiadomości.
    • Rzeczywista logika wyjściowa i zmieszane wyjście HTML powinny znajdować się na końcu.

  3. Białe znaki przed <?php dla ostrzeżeń linia 1 script.php

    Jeśli ostrzeżenie odnosi się do wbudowanego wyjścia 1, wówczas przed otwierającym tokenem <?php jest to głównie biała spacja, tekst lub kod HTML.

     <?php
    # There's a SINGLE space/newline before <? - Which already seals it.
    

    Podobnie może się to zdarzyć w przypadku dołączonych skryptów lub sekcji skryptów:

    ?>
    
    <?php
    

    PHP faktycznie zjada pojedynczy podział linii po zamykających tagach. Ale nie zrekompensuje to wielu znaków nowej linii, tabulatorów lub spacji przesuniętych w takie luki.

  4. #P64# #P23# #P24# edytor joes pokazujący BOM w formacie UTF-8  symbol zastępczy, a edytor MC kropkę #P25# beav hexeditor pokazujący utf  -8 bom #P26# #P65# #P27#
    phptags  --whitespace  *.php
    
    #P28#
  5. Białe znaki po ?>

    Jeśli źródło błędu jest wymienione jako znajdujące się za zamykaniem ?>, to w tym miejscu pojawiły się białe znaki lub nieprzetworzony tekst wypisane. Znacznik końca PHP nie kończy w tym momencie wykonywania skryptu. Wszelkie znaki tekstowe/spacje po nim zostaną zapisane jako treść strony.

    Powszechnie zaleca się, zwłaszcza nowicjuszom, aby pomijać końcowe znaczniki zamykające ?> PHP. To pomija niewielką część tych przypadków. (Często winowajcą są include()d skrypty.)

  6. Źródło błędu wymienione jako Nieznane w linii 0

    Zwykle jest to rozszerzenie PHP lub ustawienie php.ini, jeśli nie jest określone żadne źródło błędu.

    • It's occasionally the gzip stream encoding setting or the ob_gzhandler.
    • Ale może to być również dowolny podwójnie załadowany moduł extension= generujący ukryty komunikat ostrzegawczy/ostrzegawczy PHP.

  7. Poprzednie komunikaty o błędach

    Jeśli inna instrukcja lub wyrażenie PHP powoduje wydrukowanie komunikatu ostrzegawczego lub powiadomienia, liczy się to również jako przedwczesne wyjście.

    W takim przypadku należy uniknąć błędu, opóźnić wykonanie instrukcji lub ukryć komunikat za pomocą np. isset() lub @()< /a> - gdy którykolwiek z nich nie utrudnia późniejszego debugowania.

Brak komunikatu o błędzie

Jeśli masz wyłączone error_reporting lub display_errors na php.ini, nie pojawi się żadne ostrzeżenie. Ale ignorowanie błędów nie sprawi, że problem zniknie. Nagłówków nadal nie można wysłać po przedwczesnym wyjściu.

Zatem gdy przekierowania header("Location: ...") po cichu zawodzą, bardzo wskazane jest sprawdzenie ostrzeżeń. Włącz je ponownie za pomocą dwóch prostych poleceń znajdujących się na skrypcie wywołania:

error_reporting(E_ALL);
ini_set("display_errors", 1);

Lub set_error_handler("var_dump");, jeśli wszystko inne zawiedzie.

Mówiąc o nagłówkach przekierowań, często powinieneś używać takiego idiomu dla końcowych ścieżek kodu:

exit(header("Location: /finished.html"));

Najlepiej nawet funkcja narzędziowa, która wypisuje komunikat użytkownika w przypadku header() awarii.

Buforowanie wyjścia jako obejście

buforowanie danych wyjściowych w PHP jest obejściem tego problemu. Często działa niezawodnie, ale nie powinno zastępować odpowiedniego strukturyzacji aplikacji i oddzielania danych wyjściowych od logiki sterującej. Jego rzeczywistym celem jest minimalizacja fragmentarycznych transferów do serwera WWW.

  1. Niemniej jednak ustawienie output_buffering= może być pomocne. Skonfiguruj go w php.ini lub przez .htaccess lub nawet .user.ini w nowoczesnych konfiguracjach FPM/FastCGI.
    Włączenie tej opcji pozwoli PHP buforować dane wyjściowe zamiast przekazywać je do serwera WWW natychmiast. PHP może w ten sposób agregować nagłówki HTTP.

  2. Można go również wywołać poprzez wywołanie ob_start(); na górze skryptu wywołania. Który jednak jest mniej niezawodny z wielu powodów:

    • Nawet jeśli <?php ob_start(); ?> uruchomi pierwszy skrypt, białe znaki lub BOM mogą zostać wcześniej przetasowane, co czyni go nieskutecznym.

    • Może ukrywać białe znaki w wynikach HTML. Jednak gdy tylko logika aplikacji spróbuje wysłać zawartość binarną (na przykład wygenerowany obraz), buforowane zewnętrzne wyjście staje się problemem. (Wymagane jest dalsze obejście problemu ob_clean().)

    • Bufor ma ograniczony rozmiar i może łatwo zostać przepełniony, jeśli pozostawi się go do ustawień domyślnych. I to też nie jest rzadkie zjawisko, trudne do wyśledzenia kiedy to się stanie.

Dlatego oba podejścia mogą stać się zawodne - w szczególności podczas przełączania między konfiguracjami programistycznymi i/lub serwerami produkcyjnymi. Dlatego buforowanie wyjścia jest powszechnie uważane za pomocną/ściśle obejście.

Zobacz także podstawowy przykład użycia w podręczniku i więcej plusy i minusy:

Ale zadziałało na innym serwerze!?

Jeśli wcześniej nie pojawiło się ostrzeżenie dotyczące nagłówków, skorzystaj z ustawienia buforowania danych wyjściowych w pliku php.ini uległo zmianie. Prawdopodobnie nie jest skonfigurowany na bieżącym/nowym serwerze.

Sprawdzanie za pomocą headers_sent()

Zawsze możesz użyć headers_sent(), aby sprawdzić, czy nadal możliwe jest... wysyłanie nagłówków. Co jest przydatne do warunkowego drukowania informacji lub stosowania innej logiki awaryjnej.

if (headers_sent()) {
    die("Redirect failed. Please click on this link: <a href=...>");
}
else{
    exit(header("Location: /user.php"));
}

Przydatne rozwiązania awaryjne to:

  • Znacznik HTML <meta>

    Jeśli struktura Twojej aplikacji jest trudna do naprawienia, prostym (ale nieco nieprofesjonalnym) sposobem zezwolenia na przekierowania jest wstrzyknięcie tagu HTML <meta>. Przekierowanie można osiągnąć za pomocą:

     <meta http-equiv="Location" content="http://example.com/">
    

    Lub z krótkim opóźnieniem:

     <meta http-equiv="Refresh" content="2; url=../target.html">
    

    Prowadzi to do nieprawidłowego kodu HTML, jeśli jest używany poza sekcją <head>. Większość przeglądarek nadal to akceptuje.

  • Przekierowanie JavaScript

    Alternatywnie można zastosować przekierowanie JavaScript w przypadku przekierowań stron:

     <script> location.replace("target.html"); </script>
    

    Chociaż jest to często bardziej zgodne z HTML niż obejście <meta>, wiąże się z koniecznością polegania na klientach obsługujących JavaScript.

Obydwa podejścia zapewniają jednak akceptowalne rozwiązania awaryjne, gdy oryginalne wywołania nagłówka HTTP nie powiodą się. Idealnie byłoby, gdybyś w ostateczności zawsze łączył to z przyjazną dla użytkownika wiadomością i klikalnym linkiem. (Co na przykład robi rozszerzenie http://php.net/http_redirect PECL.)

Dlaczego dotyczy to również setcookie() i session_start()

Zarówno setcookie(), jak i session_start() muszą wysłać Set-Cookie: nagłówek HTTP. Obowiązują zatem te same warunki i podobne komunikaty o błędach będą generowane w przypadku przedwczesnych sytuacji wyjściowych.

(Oczywiście mają na nie wpływ także wyłączone pliki cookie w przeglądarce lub nawet problemy z serwerem proxy. Funkcjonalność sesji zależy oczywiście również od wolnego miejsca na dysku i innych ustawień php.ini itp.)

Dalsze linki

person mario    schedule 06.11.2011
comment
Również zwykły plik notepad.exe jest trudny. Zwykle używam NetBeans, który nie dodaje BOM, nawet jeśli plik jest tak zakodowany. Późniejsza edycja pliku w notatniku psuje sytuację, szczególnie w przypadku IIS jako serwera WWW. Wygląda na to, że Apache odrzuca (nieumyślnie dodany) BOM. - person Teson; 03.12.2015
comment
Usunięcie zamykającego ?> z końca plików php jest zwykle dobrą praktyką, która pomaga również zminimalizować te błędy. Na końcu plików nie będą pojawiać się niechciane białe znaki, a nagłówki odpowiedzi nadal będzie można później dodać. Jest to również przydatne, jeśli używasz buforowania danych wyjściowych i nie chcesz, aby na końcu części generowanych przez dołączone pliki dodano niechciane białe znaki. - person Nikita 웃; 08.02.2016
comment
Dziwna rzecz, przeniosłem mój plik z cPanel Linux Hosting na VPS. Wcześniej działało poprawnie, ale tutaj pokazywało ten błąd. (Przed nagłówkiem miałem kod HTML). Dlaczego? - person Pablo Escobar; 30.04.2017
comment
@Purushotamrawat Czy przeczytałeś część o Ale zadziałała na innym serwerze!? - person mario; 30.04.2017
comment
@mario, ale nie zmieniłem buforowania wyjściowego - person Pablo Escobar; 30.04.2017
comment
@TheCrazyProfessor, ponieważ czeka przed wysłaniem czegokolwiek do klienta, dopóki całe dane wyjściowe nie zostaną wyrenderowane/buforowane po stronie serwera. Bez buforowania danych wyjściowych serwer rozpoczyna wysyłanie danych w miarę ich generowania (strumieniowanie). W takim przypadku musi najpierw wysłać nagłówki, którymi nie można później manipulować. - person huysentruitw; 16.05.2017
comment
a czasami jest to tylko wersja php! bardzo trudno jest edytować wszystkie skomplikowane kody i lepiej zmienić wersję php serwera na najbardziej zgodną z twoimi kodami - person Solivan; 12.07.2017
comment
Kiedy strona się ładuje, mam już załadowany i wysłany nagłówek Content-Type:. Jakie ustawienie spowodowało taką sytuację? - person Peter S McIntyre; 01.08.2017
comment
@PeterSMcIntyre Prawdopodobnie BOM UTF8 (napraw to)/brak włączonego buforowania wyjściowego (nie polegaj na tym). - person mario; 02.08.2017
comment
Chcę tylko wspomnieć, że użycie curl i nie ustawienie CURLOPT_RETURNTRANSFER na TRUE może również wygenerować dane wyjściowe i dlatego wywołać błąd „nagłówki już wysłane” - person kask; 19.03.2018
comment
Dziękuję za dodanie niezamierzonych przyczyn na początku. Miałem jedno, maleńkie, małe miejsce przed tagiem <?php w jednym z moich dołączonych plików. - person AnalogWeapon; 20.05.2018
comment
Jeśli naprawdę potrzebujesz wyświetlić treść przed przekazaniem dalej. Możesz użyć zamiany w JavaScript: window.location.replace(newUrl.com);. Możesz skonfigurować rekursywną funkcję JS za pomocą setTimeout(), która wyszukuje na stronie informacje sygnalizujące, że nadszedł czas na przekazanie, a następnie wywołanie zamiany. - person Bob Ray; 05.06.2018
comment
Dla Ale to zadziałało na innym serwerze!? część - tak było w moim przypadku, w przypadku uruchamiania własnego lokalnego serwera spróbuj edytować plik php.ini i ustaw Output_buffering na Output_buffering=4096. JEŚLI TO WCIĄŻ NIE DZIAŁA - spróbuj je zwiększyć. To był mój problem. Musiałem zwiększyć bufor do 64kb, ponieważ niektóre strony były po prostu tak duże. Aha i nie zapomnij także zrestartować serwera, na wszelki wypadek. - person hocikto; 24.06.2018
comment
Jeśli używasz UltraEdit, Zapisz jako (wybierz opcję kodowania w prawym dolnym rogu) UTF-8 Brak boM (to naprawiło to dla mnie) - person hamish; 14.07.2019
comment
U mnie nic nie zadziałało, z wyjątkiem tego, że ob_start(); rozwiązało problem. Dzięki - person Jodyshop; 16.08.2019
comment
Białe znaki przed ‹?php dla ostrzeżeń z linii 1 script.php zadziałały w moim przypadku. Dziękuję za to niesamowite wyjaśnienie - person Immran Mohammed; 16.03.2020
comment
Pięknie opracowana odpowiedź. - person Hillel; 19.04.2021
comment
Pominąłem tylko jeden szczegół, który warto dodać. $file = $line = null; headers_sent($file, $line); die("$file:$line"); powie Ci dokładnie, co wysłało nagłówki, jeśli komunikat o błędzie pominie tę informację. Nie jestem pewien dlaczego, ale czasami wydaje się, że tak jest. - person kmuenkel; 16.06.2021

Ten komunikat o błędzie jest wyświetlany, gdy cokolwiek zostanie wysłane przed wysłaniem nagłówków HTTP (z setcookie lub header). Typowe powody wypisywania czegoś przed nagłówkami HTTP to:

  • Przypadkowe białe znaki, często na początku lub na końcu plików, takie jak to:

     <?php
    // Note the space before "<?php"
    ?>
    

Aby tego uniknąć, po prostu pomiń zamknięcie ?> - i tak nie jest to wymagane.

  • Znaczniki kolejności bajtów na początku pliku php. Sprawdź swoje pliki php za pomocą edytora szesnastkowego, aby dowiedzieć się, czy tak jest. Powinny zaczynać się od bajtów 3F 3C. Możesz bezpiecznie usunąć BOM EF BB BF z początku plików.
  • Jawne dane wyjściowe, takie jak wywołania echo, printf, readfile, passthru, kod przed <? itp.
  • Ostrzeżenie wyświetlane przez php, jeśli ustawiona jest właściwość display_errors php.ini. Zamiast zawieszać się z powodu błędu programisty, php po cichu naprawia błąd i emituje ostrzeżenie. Chociaż możesz modyfikować display_errors lub error_reporting, powinieneś raczej naprawić problem.
    Najczęstszymi przyczynami są dostęp do niezdefiniowanych elementów tablicy (takich jak $_POST['input'] bez użycia empty lub isset, aby sprawdzić, czy dane wejściowe są set) lub użycie niezdefiniowanej stałej zamiast literału łańcuchowego (jak w $_POST[input], zwróć uwagę na brakujące cudzysłowy).

Włączenie buforowanie danych wyjściowych powinno sprawić, że problem zniknie; wszystkie dane wyjściowe po wywołaniu ob_start są buforowane w pamięci do czasu zwolnienia bufora, np. z ob_end_flush.

Jednakże, chociaż buforowanie danych wyjściowych pozwala uniknąć problemów, tak naprawdę powinieneś określić, dlaczego aplikacja wysyła treść HTTP przed nagłówkiem HTTP. To jakby odebrać telefon i omówić swój dzień i pogodę, zanim powiesz rozmówcy, że pomylił numer.

person phihag    schedule 06.11.2011

Zamiast poniższej linii

//header("Location:".ADMIN_URL."/index.php");

pisać

echo("<script>location.href = '".ADMIN_URL."/index.php?msg=$msg';</script>");

or

?><script><?php echo("location.href = '".ADMIN_URL."/index.php?msg=$msg';");?></script><?php

To na pewno rozwiąże Twój problem. Napotkałem ten sam problem, ale rozwiązałem go, pisząc lokalizację nagłówka w powyższy sposób.

person Ipsita Rout    schedule 24.03.2013

Ty robisz

printf ("Hi %s,</br />", $name);

przed ustawieniem plików cookies, co jest niedozwolone. Nie możesz wysłać żadnego wyniku przed nagłówkami, nawet pustej linii.

person Seth Carnegie    schedule 06.11.2011

CZĘSTE PROBLEMY:

(skopiowano z: źródło)

====================

1) przed poleceniem header(.......); nie powinno być żadnych danych wyjściowych (tj. echo.. lub kodów HTML).

2) usuń wszelkie białe znaki (lub nową linię) przed tagami <?php i po ?>.

3) ZŁOTA ZASADA! - sprawdź, czy ten plik php (a także, jeśli masz include inne pliki) mają kodowanie UTF8 bez BOM (a nie po prostu UTF-8). W wielu przypadkach jest to problem (ponieważ plik zakodowany w formacie UTF8 ma na początku pliku php jakiś specjalny znak, czego twój edytor tekstu nie pokazuje)!!!!!!!!!!!

4) Po header(...); musisz użyć exit;

5) zawsze używaj odniesienia 301 lub 302:

header("location: http://example.com",  true,  301 );  exit;

6) Włącz raportowanie błędów i znajdź błąd. Twój błąd może być spowodowany niedziałającą funkcją. Po włączeniu raportowania błędów należy zawsze najpierw naprawić błąd znajdujący się na pierwszym miejscu. Może to być na przykład „Ostrzeżenie: date_default_timezone_get(): Nie jest bezpiecznie polegać na ustawieniach strefy czasowej systemu”. - dalej w dół może pojawić się błąd „nagłówki nie zostały wysłane”. Po naprawieniu najwyższego (pierwszego) błędu załaduj ponownie stronę. Jeśli nadal występują błędy, ponownie napraw najwyższy błąd.

7) Jeśli żadne z powyższych nie pomoże, użyj przekierowania JAVSCRIPT (jednak zdecydowanie niezalecana metoda), może to być ostatnia szansa w niestandardowych przypadkach...:

echo "<script type='text/javascript'>window.top.location='http://website.com/';</script>"; exit;
person Community    schedule 09.04.2015
comment
Dlaczego wyraźne ustawienie 301 lub 302 jest ważne? - person Jānis Elmeris; 15.04.2019
comment
Możesz mieć dane wyjściowe, jeśli ustawiono buforowanie_wyjściowe w pliku php.ini. Mój w moim domowym systemie Debian jest ustawiony na 4096. Ten na serwerze, którego używam, stwierdza, że ​​nie ma żadnych ustawień. - person Programming Padawan; 09.07.2020

Dzieje się tak z powodu tej linii:

printf ("Hi %s,</br />", $name);

Nie należy drukować/echa niczego przed wysłaniem nagłówków.

person Sarfraz    schedule 06.11.2011

Prosta wskazówka: zwykła spacja (lub niewidoczny znak specjalny) w skrypcie, tuż przed pierwszym znacznikiem <?php, może to spowodować! Zwłaszcza gdy pracujesz w zespole i ktoś używa „słabego” IDE lub grzebał w plikach dziwnymi edytorami tekstu.

Widziałem takie rzeczy ;)

person Sliq    schedule 16.05.2012

Inna zła praktyka może powodować ten problem, który nie został jeszcze stwierdzony.

Zobacz ten fragment kodu:

<?php
include('a_important_file.php'); //really really really bad practise
header("Location:A location");
?>

Wszystko w porządku, prawda?

A co jeśli „a_important_file.php” to:

<?php
//some php code 
//another line of php code
//no line above is generating any output
?>

 ----------This is the end of the an_important_file-------------------

To nie zadziała? Dlaczego? Ponieważ jest już generowana nowa linia.

Chociaż nie jest to częsty scenariusz, co się stanie, jeśli używasz frameworka MVC, który ładuje dużo plików przed przekazaniem rzeczy do kontrolera? To nie jest rzadki scenariusz. Bądź na to przygotowany.

Z PSR-2 2.2:


  • Wszystkie pliki PHP MUSZĄ używać Unix LF (linefeed) line ending.
  • Wszystkie pliki PHP MUSZĄ kończyć się znakiem single blank line.
  • Zamykający znacznik ?> MUSI być omitted z plików zawierających only php

Uwierz mi, przestrzeganie tych standardów może zaoszczędzić mnóstwo godzin życia :)

person MD. Sahib Bin Mahboob    schedule 08.11.2013
comment
Według kilku standardów (np. Zend) w żadnym wypadku nie należy umieszczać znacznika zamykającego ?> w żadnym pliku - person Daniel W.; 04.04.2014
comment
Nie mogę tego odtworzyć w środowisku Windows, ponieważ działa to przy użyciu dowolnej kombinacji (dodawanie znaczników zamykających, spacji, naciśnięcie klawisza Enter itp.). Wygląda na to, że ten problem występuje głównie w środowiskach Linux. - person Junior Mayhé; 10.06.2015
comment
@JuniorM Powinno być powtarzalne. Czy możesz podzielić się kodem, z którym eksperymentowałeś, w skrócie lub czymś podobnym? - person MD. Sahib Bin Mahboob; 11.06.2015
comment
Mam system Windows 7 i zainstalowaną najnowszą wersję Wampa. Myślę, że ten błąd jest związany z ukrytymi znakami na końcu linii. Przyczyną problemu był plik shortcodes.php mojego Wordpressa. Dodałem do tego pliku prostą funkcję i zaczęła wystrzeliwać błąd „Wysłane nagłówki”. Porównałem mój plik shortcodes.php z wordpressem i wszystko było w porządku, z wyjątkiem CR LF (typowy koniec linii w systemie Windows). Rozwiązuję ten problem, pobierając oryginalny plik z repozytorium Wordpress, który ma LF (koniec linii w Linuksie) zamiast CR LF, a także przeniosłem moją funkcję do plikufunctions.php motywu. Na podstawie: bit.ly/1Gh6mzN - person Junior Mayhé; 11.06.2015
comment
@Sahib, zauważ, że nadal nie mogę odtworzyć tego, co podano w tej odpowiedzi. Odpowiedź jest całkowicie dobra dla środowiska Linux. Testowałem takie rzeczy, jak odstęp między ?> <?php, usuwając i dodając pojedynczą pustą linię, dodając i pomijając znacznik zamykający ?>. W Windows+ Wamp wszystkie te kombinacje działają dobrze. Dziwne... - person Junior Mayhé; 11.06.2015
comment
:+1: Miałem ten sam problem, ale odwrotnie: ważny plik, który załączyłem, zawierał polecenie header(), a główny skrypt (o bardzo podobnej nazwie) wygenerował dane wyjściowe przed dołączeniem. - person rubo77; 26.03.2021

Czasami, gdy proces deweloperski obejmuje zarówno stacje robocze WIN, jak i systemy LINUX (hosting), a w kodzie nie widać żadnych danych wyjściowych przed odpowiednią linią, może to być spowodowane formatowaniem pliku i brakiem Unix LF (linefeed ) zakończenie linii.

Aby szybko to naprawić, zwykle zmieniamy nazwę pliku i w systemie LINUX tworzymy nowy plik zamiast pliku o zmienionej nazwie, a następnie kopiujemy do niego zawartość. Wiele razy rozwiązuje to problem, ponieważ niektóre pliki utworzone w WIN po przeniesieniu na hosting powodują ten problem.

Ta poprawka jest łatwa w przypadku witryn zarządzanych przez FTP i czasami może zaoszczędzić trochę czasu naszym nowym członkom zespołu.

person Community    schedule 21.05.2015

Zwykle ten błąd pojawia się, gdy wysyłamy nagłówek po wywołaniu echa lub wydrukowaniu. Jeśli ten błąd pojawi się na konkretnej stronie, przed wywołaniem start_session() upewnij się, że strona nie powtarza niczego.

Przykład nieprzewidywalnego błędu:

 <?php //a white-space before <?php also send for output and arise error
session_start();
session_regenerate_id();

//your page content

Jeszcze jeden przykład:

<?php
includes 'functions.php';
?> <!-- This new line will also arise error -->
<?php
session_start();
session_regenerate_id();

//your page content

Wniosek: Nie wyprowadzaj żadnych znaków przed wywołaniem funkcji session_start() lub header(), nawet jeśli jest to spacja lub nowa linia

person Community    schedule 03.02.2015

person    schedule
comment
ob_start() po prostu ukrywa problem; nie używaj go do rozwiązania tego konkretnego problemu. - person Ja͢ck; 15.05.2013
comment
@Ja͢ck Jeśli nie używam ob_start(), to co powinienem zrobić, aby rozwiązać ten problem: Headers already sent - person Shafizadeh; 14.07.2015
comment
@Sajad, jeśli otrzymujesz błąd konkretnie z powodu używanego edytora, powinieneś majstrować przy ustawieniach, aby przestał powodować problem, lub zmień edytory. Jeśli otrzymujesz błąd z innego powodu, powinieneś przeczytać odpowiedzi na to pytanie (w szczególności zaakceptowaną odpowiedź), aby dowiedzieć się, na czym właściwie polega problem i go rozwiązać. - person Samsquanch; 14.07.2015
comment
ob_start() nie ukrywa problemu, on rozwiązuje problem. - person Tomas; 22.10.2015
comment
Miałem taki problem, gdy przesyłałem pliki na serwer, który obsługiwał nawet PHP 5.3. Użyj serwera z PHP 5.6 lub nowszym - person GGSoft; 09.12.2015
comment
@jack prawda, zgadzam się z Tobą. Idealnym sposobem jest usunięcie spacji przed uruchomieniem tagu php <? - person Manish Shrivastava; 06.05.2017
comment
Wiele osób pyta, gdzie dodać ob_start();. ponieważ po dodaniu ob_start(); nadal pojawia się błąd. Musisz dodać do strony, która uruchomiła bieżącą stronę. Np.: strona 1 (kliknięcie przycisku) -› strona 2. (przekierowanie nagłówka) -› strona 0 (strona główna). Musisz dodać go do strony 1. Wiele osób było zdezorientowanych i dodało na stronie 2. - person Dexter; 07.08.2018
comment
Rozwiązałem mój problem. - person NickDimou; 26.01.2021