PHP Redirect Headers Best Practices - php

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...
}

Related

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();

Redirect to 404 page or display 404 message?

I am using a cms, and file-not-found errors can be handled in different ways:
The page will not be redirected, but an error-msg will be displayed as content (using the default layout with menu/footer).
The page will be redirected to error.php (the page looks the same like 1. but the address changed)
The page will be redirected to an existing page, e.g. sitemap.php
Is there a method to be preferred in regards to search engines, or does this make no difference?
If it's not found, then you should issue a 404 page. Doing a redirect causes a 302 code, followed by a '200 OK', implying that there IS some content. A 404 flat out says "there is no file. stop bugging me".
Something like this would present a 404 page with proper header code:
<?php
if ($page_not_found) {
header('This is not the page you are looking for', true, 404);
include('your_404_page.php');
exit();
}
Don't redirect.
Forget about search engines. If I type a URL in and make a small typo and you redirect me away, then I have to type the whole thing in again.
The page will not be redirected, but an error-msg will be displayed as content (using the default layout with menu/footer).
Try to make it clear it is an error page. It shouldn't look too much like a normal page.
The page will be redirected to error.php (the page looks the same like 1. but the address changed)
No. Really, really no.
The page will be redirected to an existing page, e.g. sitemap.php
There are a few redirect status codes in HTTP, none of them are "Not Found, but you might like this instead".

PHP or htaccess make dynamic url page to go 404 when item is missing in DB

Typical scenario:
DB items are displaied in page http://...?item_id=467
User one day deletes
the item
Google or a user
attempts to access http://...?item_id=467
PHP diggs into DB and sees items does not exist anymore, so now PHP must tell
Google/user that item is not existing via a 404 header and page.
According to this answer I undertstood there is no way to redirect to 404 Apache page via PHP unless sending in code the 404 header + reading and sending down to client all the contents of your default 404 page.
The probelm: I already have an Apache parsed custom 404.shtml page, so obvioulsy I would like to simply use that page.
But if i read an shtml page via PHP it won't be parsed by Apache anymore.
So what do you suggest me to do?
Is there maybe some trick I could use palying with htaccess too?
Thanks,
Hmm. Two ideas come to mind:
Redirect to the 404 page using header("Location:...") - this is not standards-compliant behaviour though. I would use that only as a last straw
Fetch and output the Apache-parsed SHTML file using file_get_contents("http://mydomain.com/404.shtml"); - also not really optimal because a request is made to the web server but, I think, acceptable in most cases.
I doubt there is anything you can do in .htaccess because the PHP script runs after any rewrite rules have already been parsed.
IF you are using apache mod_php, use virtual('/404.shtml'); to display the parsed shtml page to your user.
I was trying to do this exact same thing yesterday.
Does Pekka's file_get_contents/include result in a 404 status header being sent? Perhaps you need to do this before including the custom error page?
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
You can test using this Firefox extension.
I was looking exactly for something like you needed, so you have a page:
http://example.com/page?item_id=456
and if later you want that if item is missing you are redirected to:
http://example.com/page_not_found?item_id=456
In reality I found it is much more maintainable solution to just use the original page as 404 page.
<?php
$item = findItem( $_GET['item_id']);
if($item === false){
//show 404 page sending correct header and then include 404 message
header( $_ENV['SERVER_PROTOCOL'].' 404 Not Found', true );
// you can still use $_GET['item_id'] to customize error message
// "maybe you were looking for XXX item"
include('somepath/missingpage.php');
return;
}
//continue as usual with normal page
?>
So if item is no longer in the DB, the 404 page is showed but you can provide custom items in replace or error messages.

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.

Redirecting to frontpage after 404 error in PHP

I have a php web page that now uses custom error pages when a page is not found. The custom error pages are included in PHP.
So when somebody types in an URL that does not exists I just include an error page, and the error page starts with:
<?php header("HTTP/1.1 404 Not> Found"); ?>
This also tells crawlers that the page does not exist.
Now I have set up a new system. When a user types a wrong url, the user is sent back to the frontpage and a message is displayed on the frontpage. I redirect to the frontpage like this:
header('Location:' . __TINY_URL . '/');
Now the problem is PHP just sends back a 200 code, page found.
How can I mix these two to create a 404 code on the frontpage.
And is this overall a nice way of presenting and error page.
It's giving you a 200 code because you are redirecting to a page that returns a 200 code. The way ive done this before is to send the 404 header then load the 404 view.
header("HTTP/1.0 404 Not Found");
include("four_o_four.php");
Redirecting after an error is not a very good idea. It's especially annoying for people who like to type in/edit URLs, because if you make a typo, you'll get redirected to some arbitrary page and have to start over.
I suggest you don't do this at all. If you want to, you can have your error page look like your front page though, albeit I think that'd be somewhat confusing.
You can add this into your htaccess
ErrorDocument 404 http://www.yourdomain.com/404.php
or
ErrorDocument 404 http://www.yourdomain.com/index.php #Your homepage
This will send the intials 404 header

Categories