Dlaczego moja aplikacja PHP nie wysyła błędu 404?

140
if (strstr($_SERVER['REQUEST_URI'],'index.php')) {
    header('HTTP/1.0 404 Not Found');
}

Dlaczego to nie zadziała? Otrzymuję pustą stronę.

danorton
źródło
1
Lepszym rozwiązaniem byłoby wysłanie statusu 404 i natychmiastowe dołączenie niestandardowej strony 404. To właśnie robiłem.
Rocky,
Na moim serwerze PHP działa idealnie. Powyższa linia zwraca domyślną stronę 404 serwera. Przypuszczam, że można to skonfigurować na serwerze.
Elmue,

Odpowiedzi:

306

Twój kod jest poprawny technicznie. Jeśli spojrzysz na nagłówki tej pustej strony, zobaczysz nagłówek 404, a inne komputery / programy będą w stanie poprawnie zidentyfikować odpowiedź jako nie znaleziono pliku.

Oczywiście Twoi użytkownicy nadal są SOL. Normalnie 404 są obsługiwane przez serwer WWW.

  • User: Hej, czy masz coś dla mnie na tym serwerze sieciowym URI?
  • Serwer WWW: Nie, nie, 404! Oto strona do wyświetlenia dla błędów 404.

Problem polega na tym, że gdy serwer WWW zacznie przetwarzać stronę PHP, minął już punkt, w którym mógłby obsłużyć 404

  • User: Hej, czy masz coś dla mnie na tym serwerze sieciowym URI?
  • Serwer WWW: tak, to strona PHP. Powie Ci, jaki jest kod odpowiedzi
  • PHP: Hej, OMG 404 !!!!!!!
  • Serwer WWW: Cóż, ludzie ze strony 404 już wrócili do domu, więc wyślę wszystko, co dał mi PHP

Oprócz dostarczania nagłówka 404, PHP jest teraz odpowiedzialny za wyświetlenie rzeczywistej strony 404.

Alan Storm
źródło
49
Czternastoletnia dziewczynka czy nie, ten mały tandetny dialog naprawdę miał dla mnie sens.
rbwhitaker
20
PHP miał wtedy 14 lat
Adam Lynch
1
Stack Overflow musi dodać funkcję +1 dla stylu. To dałoby wszystkie + 1-ki.
Jay Querido
30
Tak należy pisać dokumentację! Szczególnie dokumentacja Apache, której naprawdę nienawidzę :)
Harry
4
cholernie wspaniale wyjaśnione! sprawił, że mój dzień!
Andrei Cristian Prodan
78
if (strstr($_SERVER['REQUEST_URI'],'index.php')){
    header('HTTP/1.0 404 Not Found');
    echo "<h1>404 Not Found</h1>";
    echo "The page that you have requested could not be found.";
    exit();
}

Jeśli spojrzysz na ostatnie dwie linie echa, zobaczysz tam zawartość. Możesz go dostosować, jak chcesz.

Evan Fosmark
źródło
74

To jest poprawne zachowanie , to do Ciebie należy tworzenie treści dla strony 404.
Nagłówek 404 jest używany przez roboty i menedżery pobierania do określenia, czy plik istnieje.
(Strona z nagłówkiem 404 nie będzie indeksowana przez Google ani inne wyszukiwarki)

Jednak zwykli użytkownicy nie patrzą na nagłówki http i używają strony jako normalnej strony.

Bob Fanger
źródło
20
FWIW, w przypadku 404, IE zwraca swoją standardową stronę „nie znaleziono”, jeśli zawartość jest krótka (zakłada, że ​​serwer po prostu mówi „nie znaleziono” i decyduje się wyświetlić ładniejszą stronę dla użytkownika).
Serge Wautier
16

Dla przypomnienia, oto obsługa wszystkich spraw:

<?php
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
header("Status: 404 Not Found");

$_SERVER['REDIRECT_STATUS'] = 404;
?> <!-- 404 contents below this line -->
Silviu-Marian
źródło
jest die()wymagane?
Daniel mówi Przywróć Monikę
Nie, po prostu umieść te rzeczy na górze pliku, a następnie przejdź do niestandardowej strony 404.
Silviu-Marian
14

Załaduj domyślną stronę 404 serwera, jeśli taką masz, np. Zdefiniowaną dla Apache:

if(strstr($_SERVER['REQUEST_URI'],'index.php')){
  header('HTTP/1.0 404 Not Found');
  readfile('404missing.html');
  exit();
}
Kitet
źródło
nie działa, pokazuje Ostrzeżenie: readfile (404missing.html): nie udało się otworzyć strumienia: Brak takiego pliku lub katalogu w /var/www/.com/public_html/index1.php on line 61
2
@AMB To dlatego, że musisz sam utworzyć ten plik.
Super Cat
@SuperCat dzięki, teraz ponownie przeczytałem błąd i wszystko jest jasne.,
4

Kolejne rozwiązanie oparte na @ Kitet's.

header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
header("Status: 404 Not Found");

$_SERVER['REDIRECT_STATUS'] = 404;
//If you don't know which web page is in use, use any page that doesn't exists
$handle = curl_init('http://'. $_SERVER["HTTP_HOST"] .'/404missing.html');
curl_exec($handle);

Jeśli programujesz witrynę internetową hostowaną na serwerze, nad którym nie masz kontroli, nie będziesz wiedzieć, który plik to „404missing.html”. Jednak nadal możesz to zrobić.

W ten sposób zapewniłeś dokładnie taki sam wynik jak normalna strona 404 na tym samym serwerze. Obserwator nie będzie w stanie odróżnić istniejącej strony PHP zwracającej 404 od nieistniejącej strony.

Earth Engine
źródło
4

Spróbuj z:

header("Status: 404 Not Found");
header('HTTP/1.0 404 Not Found');

PA!

Olaf
źródło
2

Nieco krótsza wersja. Tłumić dziwne echo.

if (strstr($_SERVER['REQUEST_URI'],'index.php')){
  header('HTTP/1.0 404 Not Found');
  exit("<h1>404 Not Found</h1>\nThe page that you have requested could not be found.");
}

źródło
2
if($_SERVER['PHP_SELF'] == '/index.php'){ 
   header('HTTP/1.0 404 Not Found');
   echo "<h1>404 Not Found</h1>";
   echo "The page that you have requested could not be found.";
   die;
}

nigdy nie upraszczaj instrukcji echo i nigdy nie zapominaj średnika jak powyżej, także po co uruchamiać substrat na stronie, możemy łatwo uruchomić php_self

Jesse
źródło
2
ponieważ REQUEST_URI to nie to samo co PHP_SELF. Zwłaszcza jeśli masz przepisywanie adresów URL.
Timo Huovinen,
1

Jeśli chcesz, aby była wyświetlana domyślna strona błędu serwera, musisz to zrobić na serwerze.

Gumbo
źródło
1

Robisz to dobrze, chociaż przydałoby się trochę rafinacji. Wygląda na to, że zostało to rozwiązane, więc porozmawiajmy o praktycznych zaletach aplikacji:

Nasza stara strona internetowa, która ma dużą kolekcję wielojęzycznej dokumentacji technicznej, wykonywała to wewnątrz warunku, jeśli inaczej:

    if (<no file found>){
        die("NO FILE HERE");
    }

Problem (poza nieprzydatną wiadomością i złym doświadczeniem użytkownika) polega na tym, że zazwyczaj używamy robota indeksującego linki (w naszym przypadku integralności) do sprawdzania złych linków i brakujących dokumentów. Oznacza to, że otrzymywaliśmy idealnie poprawną odpowiedź 200 bez błędu, informującą nas, że jest tam plik. Integralność nie wiedziała, że ​​spodziewamy się pliku PDF, więc musieliśmy ręcznie dodać nagłówek 404 za pomocą php. Dodając swój kod nad kostką (ponieważ nic później nie zostanie wykonane, a nagłówek i tak powinien zawsze znajdować się przed renderowanym kodem HTML), integralność (która zachowuje się mniej więcej jak przeglądarka) zwróciłaby 404 i wiedzielibyśmy dokładnie, gdzie szukać brakujących pliki. Są bardziej eleganckie sposoby poinformowania użytkownika o błędzie,

    header('HTTP/1.0 404 Not Found');
    die("NO FILE HERE");
Jacob Stazewski
źródło
1

Spróbuj tego:

if (strstr($_SERVER['REQUEST_URI'],'index.php')) {
    header('HTTP/1.0 404 Not Found');
    echo "<head><title>404 Not Found</title></head>";
    echo "<h1>Not Found</h1>";
    $uri   = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
    echo "<p>The requested URL ".$uri." was not found on this server.</p>";
    exit();
}
Mohammad Farhoudi
źródło
0

Wiesz, na mojej stronie stworzyłem coś takiego:

        $uri=$_SERVER['REQUEST_URI'];
        $strpos=strpos($uri, '.php');
        if ($strpos!==false){
        $e404="The page requested by you: &quot".$_SERVER['REQUEST_URI']."&quot, doesn't exists on this server.";
        $maybe=str_replace('.php','',$uri);
        $maybe=str_replace('/','',$maybe);
        die("<center><h1>404</h1><hr><h3>$e404</h3><h3>Maybe try <a href=$maybe>www.leaveyortexthere.p.ht/$maybe</a>?</center>");

}

Mam nadzieję, że Ci to pomoże.

GGG
źródło
-4

Wpadłem na ten problem .. Myślę, że przekierowanie do nieistniejącego linku na twoim serwerze może załatwić sprawę! Ponieważ serwer zwróciłby jego 404:
header('Redirect abbb.404.nonexist');<to na pewno nie istnieje

GorillaApe
źródło
7
To również zwróci 302, jeśli to zrobisz. Lepiej nie przekierowuj swoich 404. zamiast tego użyj kodu stanu 404 i wyświetl komunikat o nieznalezieniu.
Rocky,
-17

Jeśli chcesz wyświetlić domyślną stronę 404 serwera, możesz załadować ją w ramce takiej jak ta:

echo '<iframe src="/something-bogus" width="100%" height="100%" frameBorder="0" border="0" scrolling="no"></iframe>';
cykada
źródło
4
To powinno otrzymać jakąś odznakę za najgorszą odpowiedź, jaką widziałem na tej stronie.
MadTurki
1
@MadTurki Jest dużo gorzej.
bjb568