How can I display SEO friendly URLs using mod_rewr

2019-01-15 10:57发布

I am not a PHP developer at heart and I have been asked to perform some SEO on an existing PHP website.

The first thing I noticed was the ugly URLs so I want to get these to rewrite to something more informative. Here are all the possible patterns:

/index.php?m=ModuleType&categoryID=id
/index.php?m=ModuleType&categoryID=id&productID=id
/index.php?page=PageType
/index.php?page=PageType&detail=yes

So basically what I want to do is convert these into something like:

/ModuleType/Category
/ModuleType/Category/ProductName
/Page
/Page

I haven't used mod_rewrite before any advice or examples would be great!

Thanks.

3条回答
smile是对你的礼貌
2楼-- · 2019-01-15 11:03

I'm not a mod_rewrite expert by any means, but this is an example of how I put together the .htaccess for the Image Flair site:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)/(.*)\.png$ imageFlair.php?mode=$1&userid=$2 [L]
RewriteRule ^(.*)\.png$ imageFlair.php?userid=$1 [L]
</IfModule>

This basically maps:

MODE/USERID.png -> imageFlair.php?mode=MODE&userid=USERID

and

USERID.png -> imageFlair.php?userid=USERID

You should be able to adapt that to your needs, but you may have a couple of issues:

  1. If you want to use "names" rather than IDs on your URL you will need to alter the PHP to accept the names.
  2. You might have an issue with /Page and /ModuleType conflicting, if you wanted to also include more parameters in with Page, unless you can put together a regex that can determine which is which.

Going on the list of URLs you want, this should work, although I won't claim it's the best or only way to do it :-)

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)/(.*)/(.*)$ index.php?m=$1&categoryID=$2&productID=$3 [L]
RewriteRule ^(.*)/(.*)$ index.php?m=$1&categoryID=$2 [L]
RewriteRule ^(.*)$ index.php?Page=$1 [L]
</IfModule>

As suggested, you may want to replace the .* with [^/]+ but I had issues with non-matches when I did that, and had no time to troubleshoot, so YMMV :-)

查看更多
一夜七次
3楼-- · 2019-01-15 11:10

It's not quite clear from your post what the variables are. But assuming that ModuleType, id (x2) and Page are all variables then the following rules with backreferences should work within a .htaccess file.

RewriteEngine On
RewriteRule ^([^/]+)/([^/]+)$ /index.php?m=$1&categoryID=$2 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)$ /index.php?m=$1&categoryID=$2&productID=$3 [L]
RewriteRule ^([^/]+)$ /index.php?page=PageType [L]
RewriteRule ^([^/]+)/detail$ /index.php?page=PageType&detail=yes [L]

The last one didn't really make sense as you've written it. So instead you can add /detail on the end.

These should slip straight over the top of your existing applications without any modifications to the app. Because they aren't redirecting with [R] it will be transparent to your users.

查看更多
霸刀☆藐视天下
4楼-- · 2019-01-15 11:14

mod_rewrite would rather be used to do the opposite: rewrite requests of /ModuleType/Category/ProductName internally to /index.php?m=ModuleType&categoryID=id&productID=id. Using the new URLs in the documents is the job of your application.


Edit    Here’s an example of how a function might look like that turns your parameterized URLs into the new ones:

function url($url, $rules) {
    $url = parse_url($url);
    parse_str($url['query'], $url['query']);
    $argNames = array_keys($url['query']);
    foreach ($rules as $rule) {
        if ($rule[0] == $url['path'] && array_keys($rule[1]) == $argNames) {
            $newUrl = $rule[2];
            foreach ($rule[1] as $name => $pattern) {
                if (!preg_match('/'.addcslashes($pattern, '/').'/', $url['query'][$name], $match)) {
                    continue 2;
                }
                $newUrl = str_replace('<'.$name.'>', $match[0], $newUrl);
            }
            return $newUrl;
        }
    }
    return $url;
}

$rules = array(
    array(
        '/index.php',
        array('m'=>'.*', 'categoryID'=>'.*', 'productID'=>'.*'),
        '/<m>/<categoryID>/<productID>'
    )
);
echo '<a href="' . url('/index.php?m=ModuleType&categoryID=categoryID&productID=productID', $rules) . '">/ModuleType/Category/ProductName</a>';
查看更多
登录 后发表回答