Redirecting with 404 doesnt work - php

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.

Related

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

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>';

HTTP 302 error because of a header()

if I validate html or register web in any serch engine, I get 302 error.
The reason is a header() function. If I take it away, everything is fine with 200 OK status.
So the main problem is that I need this redirection for web to be multilingual.
The logic is next. When user enters the web page for the first time index.php - require_once a file with a function:
function cookies() {
if (!isset($_COOKIE["lang"])){
setcookie('lang','ukr', time()+(60*60*24*31));
header('Location: index.php');
}}
cookies();
so the user sees a page already filed with a deafault language.
If there would be no redirection from require_once file the data from mysql won't be downloaded and user won't see any text.
The question: should I leave this with HTTP 302 or rebuild the whole site/logic not to have any redirects at index page???
302 is not an error. It is the status code for "Found" (aka "The document you asked for is over here"). PHP will insert this for you automatically if you add a Location header (unless insert a status manually, but you don't want a 301 here)
This is the expected response if you are telling people to go and get a different document based on their language preferences.
It is odd to redirect from index.php to index.php though. Presumably you should just return the appropriate document directly instead of redirecting.
I got it. It's actually pretty simple.
The validators don't accept cookies. So they get stuck in a an infinite loop.
You can test this:
delete all your cookies from your computer.
Disable cookies in your browser and try loading your website.
Whenever You use header("location: .... you will get a 302, it's a status and not an error, it's telling the browser that the site has redirected the page:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Read those validators and engines and see if having the 302 is a problem for whatever you are trying to do, normally it shouldn't be.
A dirty way would be to force the header, personally I don't encourage this and don't know what side-effects could it have really, but it could be a quick workaround to trick those engines:
function cookies() {
if (!isset($_COOKIE["lang"])){
setcookie('lang','ukr', time()+(60*60*24*31));
header('Location: index.php');
header('HTTP/1.1 200 OK'); // <--- Forcing the header status
}}
cookies();

PHP redirect page with status code problem

I am trying to redirect a page using HTTP 410 status using php header function as
header("HTTP/1.1 410 Gone");
header('Location: http://domain.com/down.php');
exit;
The problem is that even if I set a 410 status code...the status code will automatically change to 302
I have also tried with
header('Location: domain.com/down.php', true, 410);
exit;
It shows 410 redirection but the redirected page does not show anything. It shows a blank page.
Does anybody know if there is a solution for this?
The 410 error indicates that the Web server has no forwarding address for the URL, so can provide no redirection to the new Web server. So the blank page you got using the second snippet is correct.
The first code snippet also gives the correct result - Location creates a redirect to a given address.
So there is no errors in your code or in PHP. I'm not sure you do what you realy need =)
header('Location: http://domain.com/down.php', true, 410);
exit;
Should works. You forgot about protocol in URL.
Besides, AFAIU, Yo can use
header('Location: 'http://domain.com/'down.php');
header("HTTP/1.1 410 Gone");
exit;
But Are you sure you need Redirect and 4xx HTTP status?
The last header line is a correct way to set the status code:
header('Location: domain.com/down.php', true, 410);
However, the Location header name requires a fully qualified URL, your URL looks incomplete. That's not valid.
Next to that you don't send any HTTP response body, so the browser can only display a blank page. To display a non-blank page, provide a response body:
header('Location: http://domain.com/down.php', true, 410);
echo '<h1>Gone.</h1>here.';
exit;
Providing a response body is useful, because user-agents do not need to follow Location headers automatically, especially as with the 410 response code RFC 2616, no response header named Location is expected by a HTTP client.
Maybe you're looking for 301 Moved Permanently.
Try to use some proper quotes?
header("HTTP/1.1 410 Gone");
header("Location: http://domain.com/down.php");
exit;
You have to include the error page :
header("HTTP/1.0 410 Gone"); include_once("410.html"); exit();

Return 404 if non existant page # PHP

I have a dynamic review system in place that displays 30 reviews per page, and upon reaching 30 reviews it is paginated. So I have pages such as
/reviews/city/Boston/
/reviews/city/Boston/Page/2/
/reviews/city/Boston/Page/3/
and so on and so forth
Unfortunately, Google seems to be indexing pages through what seems like inference - such as
/reviews/city/Boston/Page/65/
This page absolutely does not exist, and I would like to inform Google of that. Currently it displays a review page but with no reviews. I can't imagine this being very good for SEO. So, what I am trying to do if first check the # of results from my MySQL query, and if there are no results return a 404 and forward them to the home page or another page.
Currently, this is what I have.
if (!$validRevQuery) {
header("HTTP/1.0 404 Not Found");
header("Location: /index.php");
exit;
}
Am I on the right track?
You need to output the 404 status, and show a response body (= an error page) at the same time.
if (!$validRevQuery) {
http_response_code(404);
// output full HTML right here, like include '404.html'; or whatever
exit;
}
Note that you cannot use a redirect here. A redirect is a status code just as the 404 is. You can't have two status codes.
You cannot do both send a 404 status code and do a redirection (usually 3xx status code). You can only do one of them: Either send a 404 status code and an error document or respond with a redirection.
As Pekka suggests, the best option is to do a 404 status, and then put your 404 page code after that.
It is bad practice for SEO if you just 301 (redirect) the page because then the search engines will continue to visit the page in order to see if the redirect is still there.

PHP Redirect Headers Best Practices

I'm creating a PHP CMS and have some system pages like a 404 page, a maintenance page, and an unauthorized access page. When Page A isn't found, the CMS will redirect to the 404 page; if the user doesn't have access to Page B, it will redirect to the unauthorized access page, etc.
I'd like to use the proper status code in the header of each page, but I need clarification on how to handle the header/redirect. Do I put the 404 header on Page A and then redirect to the 404 page or do I put the 404 status on the 404 page itself? Also, if the latter is the correct answer, what kind of redirect should I use to get there, a 301 or a 302?
If a user arrives on page A and that page doesn't exist, then do not redirect : just send a 404 error code from page A -- and, to be nice for your user, an HTML content indicating that the page doesn't exist.
This way, the browser (and it's even more true for crawlers ! ) will know that the page that is not found is page A, and not anything else you'd have tried to redirect to.
Same for other kind of errors, btw : if a specific URL corresponds to an error, then, the error code should be sent from that URL.
Basically, something as simple as this should be enough :
if (page not found) {
header("404 Not Found");
echo "some nice message that says the page doesn't exist";
die;
}
(Well, you could output something nicer, of course ; but you get the idea ;-) )
I'm not sure if the redirecting is the best way for doing this. Id rather use some built in functionality that is included into the project.
If the data is not found, do not redirect the user to another page, just send him an error message, like Hey, this site does not exists! Try an other one and so.
And not at the end, you should build into the code, the code-part from the answer of Pascal Martin.
I would do this into a function, and call it from a bootstrap or something with a similar behavior.
function show_error($type="404", $header = true, $die = false)
{
if($header)
header("404 Not Found");
echo file_get_contents($type.'.php');
if($die) die; //
// and so on...
}

Categories