开发者

How can I do a clean Mod_Rewrite that hides the variable numbers passed in the query string but just shows the titles in php?

I have been developing web applications for a while now. My applications have been fairing poorly in search engine results because of the dynamic links that my websites generate.

I admire the way s开发者_开发技巧ome developers do their mod_rewrite to produce something like: http://www.mycompany.com/accommodation/europe/ to run a substitute of "index.php?category_id=2&country=23"

How can I achieve that in my urls?


You will need a mapping to map the names to the IDs. You can either do this with mod_rewrite. Or, what I suggest, you can use PHP for that:

// maps that map the names to IDs
$categories = array('accommodation'=>2 /*, … */);
$countries = array('europe'=>23 /*, … */);

$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'],  PHP_URL_PATH);
$segments = explode('/', trim($_SERVER['REQUEST_URI_PATH'], '/'));

// map category name to ID
$category = null;
if (isset($segments[0])) {
    if (isset($categories[$segments[0]])) {
        $category = $categories[array_shift($segments)];
    } else {
        // category not found
    }
} else {
    // category missing
}
// map country name to ID
$country = null;
if (isset($segments[0])) {
    if (isset($countries[$segments[0]])) {
        $country = $countries[array_shift($segments)];
    } else {
        // country not found
    }
} else {
    // country missing
}

Now you just need one single rule to rewrite the request to your PHP script:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule %{REQUEST_FILENAME} !-d
RewriteRule !^index\.php$ index.php [L]

This rule excludes requests that’s URL can be either mapped to existing regular files (-f) or existing directories (-d).


Edit    Since you really want the other way round: If you still want to solve this with PHP, then you just need the reverse mappings (just exchange key and value) and the header function for the redirect:

// maps that map the IDs to names
$categories = array(2=>'accommodation' /*, … */);
$countries = array(23=>'europe' /*, … */);

$newPath = '';
// map category ID to name
if (isset($_GET['category_id'])) {
    if (isset($categories[$_GET['category_id']])) {
        $newPath .= '/'.$categories[$_GET['category_id']];
    } else {
        // category not found
    }
} else {
    // category missing
}
// map country ID to name
if (isset($_GET['country'])) {
    if (isset($countries[$_GET['country']])) {
        $newPath .= '/'.$countries[$_GET['country']];
    } else {
        // country not found
    }
} else {
    // country missing
}
header('Location: http://example.com'.$newPath);
exit;

You should add some error handling since currently the redirect takes place even when both arguments are missing.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜