header('location: ..') outputs blank page on server [duplicate] - php

if (strstr($_SERVER['REQUEST_URI'],'index.php')) {
header('HTTP/1.0 404 Not Found');
}
Why wont this work? I get a blank page.

Your code is technically correct. If you looked at the headers of that blank page, you'd see a 404 header, and other computers/programs would be able to correctly identify the response as file not found.
Of course, your users are still SOL. Normally, 404s are handled by the web server.
User: Hey, do you have anything for me at this URI webserver?
Webserver: No, I don't, 404! Here's a page to display for 404s.
The problem is, once the web server starts processing the PHP page, it's already passed the point where it would handle a 404
User: Hey, do you have anything for me at this URI webserver?
Webserver: Yes, I do, it's a PHP page. It'll tell you what the response code is
PHP: Hey, OMG 404!!!!!!!
Webserver: Well crap, the 404 page people have already gone home, so I'll just send along whatever PHP gave me
In addition to providing a 404 header, PHP is now responsible for outputting the actual 404 page.

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();
}
If you look at the last two echo lines, that's where you'll see the content. You can customize it however you want.

That is correct behaviour, it's up to you to create the contents for the 404 page.
The 404 header is used by spiders and download-managers to determine if the file exists.
(A page with a 404 header won't be indexed by google or other search-engines)
Normal users however don't look at http-headers and use the page as a normal page.

For the record, this is the all-case handler:
<?php
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
header("Status: 404 Not Found");
$_SERVER['REDIRECT_STATUS'] = 404;
?> <!-- 404 contents below this line -->

Load default server 404 page, if you have one, e.g. defined for apache:
if(strstr($_SERVER['REQUEST_URI'],'index.php')){
header('HTTP/1.0 404 Not Found');
readfile('404missing.html');
exit();
}

Since php 5.4 you can now do http_response_code(404);

Another solution, based on #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);
If you are programming a website that hosted in a server you do not have control, you will not know which file is the "404missing.html". However you can still do this.
In this way, you provided exactly the same outcome of a normal 404 page on the same server. An observer will not be able to distinguish between an existing PHP page returns 404 and a non-existing page.

try with:
header("Status: 404 Not Found");
header('HTTP/1.0 404 Not Found');
Bye!

A little bit shorter version. Suppress odd 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.");
}

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;
}
never simplify the echo statements, and never forget the semi colon like above, also why run a substr on the page, we can easily just run php_self

If you want the server’s default error page to be displayed, you have to handle this in the server.

You're doing it right though it could use some refining. Looks like that's been addressed so let's talk practical application benefits:
An old website of ours that has a large collection of multilingual tech docs was executing this inside an if else conditional:
if (<no file found>){
die("NO FILE HERE");
}
The problem (besides the unhelpful message and bad user experience) being that we generally use a link crawler (in our case integrity) to check out bad links and missing documents. This means that we were getting a perfectly correct 200 no error response telling us that there was a file there. Integrity didn't know that we were expecting a PDF so we had to manually add a 404 header with php. By adding your code above the die (because nothing afterwards would execute and header should always be before any rendered html anyway), integrity (which behaves more or less like a browser) would return a 404 and we would know exactly where to look for missing files. There are more elegant ways of telling the user that there is an error, but by serving a 404 error you are not only notifying browsers and browser-like programs of the error but (I believe-correct me if I'm wrong) are also recording those errors in your server logs where you can easily grep for 404s.
header('HTTP/1.0 404 Not Found');
die("NO FILE HERE");

Try this:
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();
}

You know, in my website i created something like this:
$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>");
}
i hope it helps you.

I came up to this problem.. I think that redirecting to a non existing link on your server might do the trick ! Because the server would return his 404:
header('Redirect abbb.404.nonexist'); < that doesnt exist for sure

If you want to show the server’s default 404 page, you can load it in a frame like this:
echo '<iframe src="/something-bogus" width="100%" height="100%" frameBorder="0" border="0" scrolling="no"></iframe>';

Related

PHP Header what is the use?

I have read a tutorial, and in that tutorial they make a error function.
When the function was called it runs:
<?php
header('HTTP/1.0 404 Not Found');
include('errorpage.php');
exit();
?>
But what is the use of that? Why can't you use header('Location: errorpage.php') or skip the part header('HTTP/1.0 404 Not Found')?
If you use header('Location: errorpage.php') then you are saying "The document you want can be found here". This is a lie.
If you don't include header('HTTP/1.0 404 Not Found') then you are saying "OK, here is the document you asked for" and then displaying an error message. This is a lie.
If the error page is for an attempt from a browser to run a JavaScript, it will try to execute the HTML as JS and throw an error.
If the client is a search engine, it will index the error page as content instead of treating the link as broken. This will give you bad results in searches.
If the client is a downloading tool, it will download the document as a file. If it is going recursively, it could end up following vast numbers of links to error pages on your server and fill up the user's hard disk while eating lots of your bandwidth.
And so on.
In short, if you don't tell the client it is an error then it will treat it as content.

Generate a 404 header that shows the browser default 404 page

I am trying to generate a 404 header, and I want the browser to display the browser default page for the error, but no matter what I have tried I always end up displaying an "empty" html document which is not what I want.
This is my code:
if (strlen($buffer) == 0)
{
ob_clean();
header('HTTP/1.1 404 Not Found');
ob_flush();
die();
}
Can anybody help?
There is no "browser default" 404 page. The 4xx or 5xx error pages are generated on the server. You could possibly look at e.g. Apache's default 404 page for reference.
Why don't you use http_response_code(404); instead?
There are no such thing. Quoting from https://en.wikipedia.org/wiki/HTTP_404
The web site hosting server will typically generate a "404 Not Found"
web page when a user attempts to follow a broken or dead link
That said, as #Petter mentioned, most webservers have a default 404 page if you don't provide a custom one.
Trigger a 404 header:
header("HTTP/1.0 404 Not Found");
Kill the rest of the script:
die();
Just triggering the 404 header will not will the browser, but die will

Throwing a 401 header with php without redirect

I have a php function which adds bad IP's to a MySQL table.
Each page on my site then checks the table and throws a HTTP 401 header if a match is found.
if(badCrawler()){
header("HTTP/1.1 401 Unauthorized");
header("Location: error401.php");
}
Is it possible to do this without changing the url?
Thanks
Sure. Just exit after your 401 header. No need for the header("Location...") at all.
if(badCrawler()){
header("HTTP/1.1 401 Unauthorized");
exit;
}
Side note: 401 typically is used in conjunction with an authentication request.
From the specs:
The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource.
It might be better to use 403 Forbidden to deny access, or even 404 Not Found if you want the bad crawler to think the page doesn't exist any longer:
header("HTTP/1.0 404 Not Found");
exit;
Sending content
Note that your 404 response might result in a blank page in some browsers, see the top answer in this thread for a full explanation of why that is happening. Basically the header is working but it's just up to you to display any HTML content).
The solutions is simple, echo your content (or include a separate file) right before the exit statement.
Aware this is a little old, but it popped up on a google search of "php, 401s".
Is the issue here that when the page redirects to error401.php that page will return a 200 OK, as error401.php loaded fine. If you really want the 401 page to show, how about this?
if(badCrawler()){
header("HTTP/1.1 401 Unauthorized");
include("error401.php");
exit;
}

Redirecting with 404 doesnt work

I havea code that should redirect in case it doesnt have some request parameter set correctly.
if(!is_numeric($_GET['id'])){
header("HTTP/1.0 404 Not Found");
header('Location: '.$url);
exit();
}
Problem is that whenever I check with Firefoxes plugin, live HTTP headers, I see 302 temporary redirect. why is that? why no 404 response is given?
It doesn't make sense to send a Location header with a 404 status code.
Location means "What you asked for is over here"
404 means "I don't have what you asked for"
The two statements are incompatible.
If you want to send a particular human readable explanation of the error, then just output it as you would for any other kind of document. You could include() it if you like. Don't try to redirect to it.
Problem is that whenever I check with Firefoxes plugin, live HTTP
headers, I see 302 temporary redirect. why is that? why no 404
response is given?
Not sure what you want to do here but following will provide your purpose.
if (! is_numeric($_GET['id'])) {
header('Location: ' . $url, true, 404);
exit();
}
You can only send ONE of the headers you are attempting as stated above.
In case of 404 - this will display the error relevant error pages as defined by you're web server config.
To do what you want... you will need to modify the server's 404 from a plain html to a php page and work out what to display from there (you can base on referrer etc).
From within the 'dynamic' 404 page, you can then do you're redirect if required.

Why won't my PHP app send a 404 error?

if (strstr($_SERVER['REQUEST_URI'],'index.php')) {
header('HTTP/1.0 404 Not Found');
}
Why wont this work? I get a blank page.
Your code is technically correct. If you looked at the headers of that blank page, you'd see a 404 header, and other computers/programs would be able to correctly identify the response as file not found.
Of course, your users are still SOL. Normally, 404s are handled by the web server.
User: Hey, do you have anything for me at this URI webserver?
Webserver: No, I don't, 404! Here's a page to display for 404s.
The problem is, once the web server starts processing the PHP page, it's already passed the point where it would handle a 404
User: Hey, do you have anything for me at this URI webserver?
Webserver: Yes, I do, it's a PHP page. It'll tell you what the response code is
PHP: Hey, OMG 404!!!!!!!
Webserver: Well crap, the 404 page people have already gone home, so I'll just send along whatever PHP gave me
In addition to providing a 404 header, PHP is now responsible for outputting the actual 404 page.
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();
}
If you look at the last two echo lines, that's where you'll see the content. You can customize it however you want.
That is correct behaviour, it's up to you to create the contents for the 404 page.
The 404 header is used by spiders and download-managers to determine if the file exists.
(A page with a 404 header won't be indexed by google or other search-engines)
Normal users however don't look at http-headers and use the page as a normal page.
For the record, this is the all-case handler:
<?php
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
header("Status: 404 Not Found");
$_SERVER['REDIRECT_STATUS'] = 404;
?> <!-- 404 contents below this line -->
Load default server 404 page, if you have one, e.g. defined for apache:
if(strstr($_SERVER['REQUEST_URI'],'index.php')){
header('HTTP/1.0 404 Not Found');
readfile('404missing.html');
exit();
}
Since php 5.4 you can now do http_response_code(404);
Another solution, based on #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);
If you are programming a website that hosted in a server you do not have control, you will not know which file is the "404missing.html". However you can still do this.
In this way, you provided exactly the same outcome of a normal 404 page on the same server. An observer will not be able to distinguish between an existing PHP page returns 404 and a non-existing page.
try with:
header("Status: 404 Not Found");
header('HTTP/1.0 404 Not Found');
Bye!
A little bit shorter version. Suppress odd 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.");
}
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;
}
never simplify the echo statements, and never forget the semi colon like above, also why run a substr on the page, we can easily just run php_self
If you want the server’s default error page to be displayed, you have to handle this in the server.
You're doing it right though it could use some refining. Looks like that's been addressed so let's talk practical application benefits:
An old website of ours that has a large collection of multilingual tech docs was executing this inside an if else conditional:
if (<no file found>){
die("NO FILE HERE");
}
The problem (besides the unhelpful message and bad user experience) being that we generally use a link crawler (in our case integrity) to check out bad links and missing documents. This means that we were getting a perfectly correct 200 no error response telling us that there was a file there. Integrity didn't know that we were expecting a PDF so we had to manually add a 404 header with php. By adding your code above the die (because nothing afterwards would execute and header should always be before any rendered html anyway), integrity (which behaves more or less like a browser) would return a 404 and we would know exactly where to look for missing files. There are more elegant ways of telling the user that there is an error, but by serving a 404 error you are not only notifying browsers and browser-like programs of the error but (I believe-correct me if I'm wrong) are also recording those errors in your server logs where you can easily grep for 404s.
header('HTTP/1.0 404 Not Found');
die("NO FILE HERE");
Try this:
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();
}
You know, in my website i created something like this:
$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>");
}
i hope it helps you.
I came up to this problem.. I think that redirecting to a non existing link on your server might do the trick ! Because the server would return his 404:
header('Redirect abbb.404.nonexist'); < that doesnt exist for sure
If you want to show the server’s default 404 page, you can load it in a frame like this:
echo '<iframe src="/something-bogus" width="100%" height="100%" frameBorder="0" border="0" scrolling="no"></iframe>';

Categories