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

4

2

Typical scenario:

  1. DB items are displaied in page http://...?item_id=467
  2. User one day deletes the item
  3. Google or a user attempts to access http://...?item_id=467
  4. 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,

Knp answered 20/11, 2010 at 11:3 Comment(0)
S
4

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.

Spraddle answered 20/11, 2010 at 11:7 Comment(6)
2nd solution is great! +1 thanks! True that another request is made to the server, but at the end of the day it's a 404 page so it won't frequently happen that final user ends up on these type of missing pages, even if they take a bit more to show I think it's acceptable.Knp
@Marco yup, I think so too. Also, the request should be dealt with locally so it will be very fast. One afterthought, for optimum security use file_get_contents() instead of include() so there can't be PHP code in the shtml file, I'll edit that in.Spraddle
@Pekka, I thought to use file_get_contents, I didn't know I could use include for this, so thanks also for that hint even if yiu say is lees secure.Knp
@Marco both methods are fine, but include() would execute any PHP code inside the SHTML file which is good to avoid if it's not needed.Spraddle
@Pekka: maybe readfile in this case is even better as suggested by Gumbo: https://mcmap.net/q/753213/-php-navigate-to-error-page/…Knp
@Pekka: it works because I call readfile on the full http url ("http://...") so the server calls the page that is parsed 1st by Apache and it's the Apache output that is retrieved by my script. It's the same of file_get_contents, but I don't need to output the buffer.Knp
I
2

IF you are using apache mod_php, use virtual('/404.shtml'); to display the parsed shtml page to your user.

Inventive answered 20/11, 2010 at 12:0 Comment(2)
uh, what are you trying to say?Inventive
I didn't understand what you mean. Now I did and +1, Let me check this out.Knp
C
0

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.

Cindicindie answered 20/11, 2010 at 11:55 Comment(2)
No, file_get_contents does not send the 404. You have to do that manually as you show.Spraddle
The soluiton is in my question in the part where I say "According to this answer I undertstood..." just follow the link.Knp
J
0

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.

Jennettejenni answered 5/12, 2015 at 10:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.