URL rewriting advice please

2019-06-09 23:02发布

问题:

I would like to make my urls more seo friendly and for example change this:

http://www.chillisource.co.uk/product?&cat=Grocery&q=Daves%20Gourmet&page=1&prod=B0000DID5R&prodName=Daves_Insanity_Sauce

to something nice like this:

http://www.chillisource.co.uk/product/Daves_Gourmet/Daves_Insanity_Sauce

What is the best way of going about doing this? I've had a look at doing this with the htaccess file but this seems very complicated.

Thanks in advance

回答1:

Ben Paton, there is in fact a very easy way out. CMSes like Wordpress tend to use it instead of messing around with regular expressions.


The .htaccess side

First of, you use an .htacess with the content below:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.php [L]
</IfModule>

Let me explain what it does (line by line):

  • if the apache module named mod_rewrite exists..
    • turn the module on
    • let it be known that we will rewrite anything starting after the domain name (to only rewrite some directories, use RewriteBase /subdir/)
    • if the requested path does not exist as a file...
    • and it doesn't even exist as a directory...
    • "redirect" request to the index.php file
  • close our module condition

The above is just a quick explanation. You don't really need it to use this.

What we did, is that we told Apache that all requests that would end up as 404s to pass them to the index.php file, where we can process the request manually.


The PHP side

On the PHP side, inside index.php, you simply have to parse the original URL. This URL is passed in the $_SERVER variable as $_SERVER['REDIRECT_URL'].

The best part, if there was no redirection, this variable is not set!

So, our code would end up like:

if ( isset( $_SERVER['REDIRECT_URL'] ) ) {

    $url = explode('/', $_SERVER['REDIRECT_URL'] );

    switch($url[0]){
        case 'home': // eg:    /home/
            break;
        case 'about': // eg:    /about/
            break;
        case 'images': // eg:    /images/
            switch( $url[1] ){
                case '2010': // eg:    /images/2010/
                    break;
                case '2011': // eg:    /images/2011/
                    break;
            }
            break;
    }

}

Easy Integration

I nearly forgot to mention this, but, thanks to the way it works, you can even end up not changing your existing code at all!

Less talk, more examples. Let's say your code looked like:

<?php

    $page = get_page($_GET['id']);
    echo '<h1>'. $page->title .'</h1>';
    echo '<div>'. $page->content .'</div>';

?>

Which worked with urls like:

index.php?id=5

You can make it work with SEO URLs as well as keep it with your old system at the same time. Firstly, make sure the .htaccess contains the code I wrote in the one above.

Next, add the following code at the very start of your file:

if ( isset( $_SERVER['REDIRECT_URL'] ) ) {

    $url = explode('/', $_SERVER['REDIRECT_URL'] );
    $_GET['id'] = $url[0];

}

What are we doing here? Before going on two your own code, we are basically finding IDs and information from the old URL and feeding it to PHP's $_GET variable. We are essentially fooling your code to think the request had those variables!

The only remaining hurdle to find all those pesky <a/> tags and replace their href accordingly, but that's a different story. :)



回答2:

It's called a mod_rewrite, here is a tutorial:

http://www.workingwith.me.uk/articles/scripting/mod_rewrite



回答3:

What about using the PATH_INFO environment variable?

$path=explode("/",getenv("PATH_INFO"));
echo($path[0]."; ".$path[1] /* ... */);

Will output

product; Daves_Gourmet; Daves_insanity_Sauce

The transition from using $_GET to using PATH_INFO environment is a good programming exercise. I think you cannot just do the task with configuration.



回答4:

try some thing like this

RewriteRule ^/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)  /$1.php?id1=$2&id2=$3 [QSA]

then use $_GET to get the parameter values...



回答5:

I'll have to add: in your original url, there's a 'prod' key, which seems to consist of an ID. Make sure that, when switching to rewritten urls, you no longer solely depend upon a unique id, because that won't be visible in the url. Now, you can use the ID to make a distinction between 2 products with the same name, but in case of rewriting urls and no longer requiring ID in the url, you need to make sure 1 product name can not be used multiple times for different products. Likewise, I see the 'cat'-key not being present in the desired output url, same applies as described above.

Disregarding the above-described "problems", the rewrite should roughtly look like:

RewriteRule ^/product/(.*?)/(.*?)$ /product?&cat=Grocery&q=$1&page=1&prod=B0000DID5R&prodName=$2

The q & prodName will receive the underscored value, rather than %20, so also that will require some patching. As you can see, I didn't touch the id & category, it'll be up to you to figure out how to handle that.