...

View Full Version : Custom 404 redirect based on typed URL



galahad3
09-16-2009, 08:08 PM
Hi,

I need to set up a 404 error page in such a way that the URL typed by the user (for example aboutts.html instead of aboutus.html - or whatever mistyped URL it is) is checked against the entries in a database byt the 404 page.

If the database has an entry that matches the mistyped URL then the user gets forwarded to a different URL- not the 404 page but a different one.

If the database has no entry correspondiong to what was typed by the user, we just show the 404 page as normal.

Can this be done at all and if so, how would we go about it?

Thanks

hinch
09-16-2009, 08:22 PM
you need the .htaccess file setup to trap 404's and redirect them to a 404.php page that then checks the accessed url and uses that for the DB compare. if it finds a match do a simple header() redirect else show the real 404 error page

I do something similar here.
http://www.fcsoftware.co.uk/abouttus.php

galahad3
09-16-2009, 08:28 PM
Thanks, so what code would I use to get it to check for a match inside the db?

kbluhm
09-16-2009, 11:09 PM
Ok, let's drop levenshtein (http://www.php.net/levenshtein) on your head.

In the following example:
- $current: the current page name sans the .html extension (aboutts.html yields `aboutts`)
- $pages: an array of all page data in your database. Grab them however you like, I'm using a pseudo database wrapper for demonstration purposes
- $matches: the collection of matching pages
- $distances: a collection of corresponding distances, used to sort closer matches
- $names: a collection of corresponding pages names, used to sort matches alphabetically after they've been sorted by distance
- the demo database uses a table called `page` that at least contain fields named `page_name` and `page_title`
- an assumption has been made that if the path is /aboutus.html, the `page_name` in the database is `aboutus`, and so on...

Zero testing has been done on this as I don't have a database nearby full of page names, but I figure it's a good starting point for you that will need very little work.


<?php // 404.php

/* - - - - - - - - - -
* Whatever files need to fire up your environment
*/

require dirname( __FILE__ ) . '/bootstrap.php';

/* - - - - - - - - - -
* Grab the current page name
* /aboutts.html -> aboutts
* /path/to/helllp.html -> helllp
*/

$current = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
$current = preg_replace( '/\.html$/i', '', $current );
$current = preg_split( '/\//', $current, -1, PREG_SPLIT_NO_EMPTY );
$current = array_pop( $current );

/* - - - - - - - - - -
* Grab all the pages in the database
*/

$pages = $db->fetchAll( 'SELECT `page_name`, `page_title` FROM `page`' );

/* - - - - - - - - - -
* Calculate the distance for each using levenshtein()
*/

$matches = array();
$distances = array();
$names = array();

foreach ( $pages as $page )
{
// calculate the distance
$distance = levenshtein( $page['page_name'], $current );
// we'll keep anything with a distance under 3, this can be tweaked
// the smaller the distance, the more similar the two must be
// if the distance is equal to the length, there's a good chance the name is all wrong
if ( strlen( $page['page_name'] ) > $distance && $distance < 3 )
{
$matches[] = $page;
$distances[] = $distance;
$names[] = $page['page_name'];
}
}

/* - - - - - - - - - -
* Display the custom error
*/

?>
<h1>Whoops!</h1>
<p>That page does not exist!</p>
<?php

/* - - - - - - - - - -
* Display the suggestions, if we have any
*/

if ( ! empty( $matches ) )
{

// sort them by distance, then by page name
// the lower the distance, the greater the possibility of a match
array_multisort(
$distances,
SORT_ASC,
SORT_NUMERIC,
$names,
SORT_ASC,
SORT_REGULAR,
$matches
);

echo '<h2>Did you mean:</h2>';

echo '<ul>';
foreach ( $matches as $page )
{
echo '<li><a href="/', $page['page_name'], '.html">', $page['page_title'], '</a></li>';
}
echo '</ul>';

}

hinch
09-17-2009, 01:52 PM
thats quite smart that kb never thought of doing that :)

I do a simple select and compare and my db contains all the mappings of possible > actual then if i can't find a possible db match it does the standard can't find this page.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum