www.webdeveloper.com
Results 1 to 5 of 5

Thread: [RESOLVED] Rewriting URLs – how to get 404 for non-existent content?

Hybrid View

  1. #1
    Join Date
    Dec 2002
    Location
    Gφteborg, Sweden
    Posts
    93

    resolved [RESOLVED] Rewriting URLs – how to get 404 for non-existent content?

    I use .htaccess to rewrite urls from site.com/persons/firstname-lastname/ to persons.php?person=firstname-lastname
    If you type the url-friendly name of a person that exists in the database, then everything works fine. The problem with the way I've done it is that you can type anything in the address bar as long as it matches the rewrite rule even if there's no such record in the database. So if you go to /persons/rubbish/, you just get a blank page. I checked the response headers, and it says 200 OK. What should I do in order to get a 404 Not Found in such cases?

    This is what my .htaccess looks like:
    Code:
    RewriteEngine on
    
    RewriteRule ^(people)$ /$1/ [R]
    RewriteRule ^(people)/$ $1.php
    
    RewriteRule ^(people)/([a-z0-9-]+)$ /$1/$2/ [R]
    RewriteRule ^(people)/([a-z0-9-]+)/$ $1.php?person=$2
    And this is the relevant PHP code:
    PHP Code:
    <?php
    include "../../includes/dbconn.php";

    if(isset(
    $_GET['person'])) {

        
    $person_url $_GET['person'];
        
        function 
    quote_smart($person_url)
        {
           
    // Stripslashes
           
    if (get_magic_quotes_gpc()) {
               
    $person_url stripslashes($person_url);
           }
           
    // Quote if not a number or a numeric string
           
    if (!is_numeric($person_url)) {
               
    $person_url "'" mysql_real_escape_string($person_url) . "'";
           }
           return 
    $person_url;
        }
        
        
    $sql sprintf("SELECT * FROM persons WHERE person_url='$person_url'",
                
    quote_smart($person_url));
        
    $result mysql_query($sql) or die("Unable to perform query. Reason: ".mysql_error());
        
    $row mysql_fetch_array($resultMYSQL_ASSOC);

        
    $first_name stripslashes($row['first_name']);
        
    $last_name stripslashes($row['last_name']);
        
        
    // and here's where the contents of the page will be.

    } else {
        
    // display list of all people.
    }
    ?>

  2. #2
    Join Date
    Feb 2011
    Location
    Baltimore, MD
    Posts
    12

    Smile Send a 404 header if no record found

    After you try to get the record from the database, see if it contains any data. If not, send the 404 error code with the header() function. If it does contain data, display your page.


    Code:
        ...
        $row = mysql_fetch_array($result, MYSQL_ASSOC);
    
        // NEW CODE
        if (!$row) {
            header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); 
        } else {
        /// the rest of your code, indent it as it is now within the "else" clause
    
            $first_name = stripslashes($row['first_name']);
            $last_name = stripslashes($row['last_name']);
        
            // and here's where the contents of the page will be. 
            ...
    Hope this helps!

    NOTE: The header() function should occur before anything is output to the browser, otherwise you may get an error that headers have already been sent. The easiest way to get around that is to put

    Code:
    ob_start();
    at the beginning of your script to capture all the output buffers, which will allow the header() function to work at any time. At the end of your script put

    Code:
    ob_end_flush();
    and it will display all the captured text.

    Good Luck!

    - Brian

    References:
    header(): http://php.net/manual/en/function.header.php
    ob_start(): http://php.net/manual/en/function.ob-start.php
    ob_end_flush(): http://www.php.net/manual/en/function.ob-end-flush.php

    - Brian

    PS: Your code will generally be more secure (against SQL Injection attacks) if you use the new PDO database classes and used named parameters, rather than messing with quoting strings and putting them in your SQL directly.

  3. #3
    Join Date
    Dec 2002
    Location
    Gφteborg, Sweden
    Posts
    93
    Thanks for the reply!
    I did what you suggested, and it worked in the sense that the response headers now say 404 Not Found. However, I'm not being redirected to a 404 page. (I do have the code for it in my htaccess: ErrorDocument 404 /404.php and a corresponding 404.php in the root directory) Instead I just get a blank page. Any idea why that is happening?

    Oh, and thanks for the tip on the PDO database classes. I'll check them out.

  4. #4
    Join Date
    Feb 2011
    Location
    Baltimore, MD
    Posts
    12

    Smile Handle your own error messages

    If your PHP script is supplying the header, the web server won't "take over" and pull the error message for you. It assumes that the script will handle it.

    You can follow the header() call with the html you want to appear along with the error. The easiest way would probably be to just include your error page after the header() call:

    Code:
        ...
        $row = mysql_fetch_array($result, MYSQL_ASSOC);
    
        // NEW CODE
        if (!$row) {
            header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); 
            include('404.php');
            exit;
        } else {
        /// the rest of your code, indent it as it is now within the "else" clause
    
            $first_name = stripslashes($row['first_name']);
            $last_name = stripslashes($row['last_name']);
        
            // and here's where the contents of the page will be. 
            ..
     .

  5. #5
    Join Date
    Dec 2002
    Location
    Gφteborg, Sweden
    Posts
    93
    Ah, I see. Thank you very much for the help! It works as expected now.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles