douya7309 2010-10-24 08:08
浏览 52
已采纳

重定向/ .htaccess将旧的PHP参数URL更改为SEO友好的CakePHP URL?

I'm about to update my site to use CakePHP instead of an old homegrown framework. I need to write the HTAccess file to redirect the old PHP parameter URLs to the new CakePHP SEO friendly urls, but I can't get it to work.

My htacess file (the one in app/webroot) looks like this at the moment:

RewriteEngine On

RewriteRule ^index.php?action=view&item=172$ index.php?url=item/172 [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

It doesn't work. I tried removing the L and just having it redirect to item/172, but that didn't work either. The current one winds up with the URL parameter unset, and if I look in $_SERVER['REQUEST_URI'] it is unchanged. Though I don't know if mod_rewrite would change that. My rewrite rule doesn't seem to be activating, even though that is directly copied from the URL bar of my browser. I tried it with out and with out a leading /. No dice.

What's going on here?

And how can I write a more generalize URL to do the conversion? I tried something like:

RewriteRule ^index.php?action=view&item=([0-9]+)$ index.php?url=items/$1 [R=301,L]    

But that didn't work either. What am I doing wrong?

EDIT This is positively infuriating.

RewriteRule ^(.*)$ /index.php?url=item/172 [R=301]

That works. It funnels ALL urls into that correctly formed Cake url. Which cake's processor then picks up and somehow handles. I'm not sure how it misses Cake's second rewrite rule, but it does. Trying this:

RewriteRule ^(.*)$ item/172 [R=301]

Returns a malformed redirect, as does specifying last on the previous one:

RewriteRule ^(.*)$ /index.php?url=item/172 [R=301,L]

That declares that it could never complete.

So I'm actually rather baffled as to why this one:

RewriteRule ^(.*)$ /index.php?url=item/172 [R=301]

Returns the correct Cake url, but it does and it gets sent to the correct page. However, as soon as I attempt to change the first part, it starts failing.

Wait a second. It's when it hits the ? that it starts failing. It successfully matches index.php but not index.php? But escaping it makes no difference.

RewriteRule ^index.php\?$ /index.php?url=item/172 [R=301]

That fails to match or return the correct URL. And it doesn't seem to match Cake's normal catch all either, because $_GET['url'] is empty. How do you escape parameter characters to match literally in mod_rewrite?

  • 写回答

1条回答 默认 最新

  • donvo24600 2010-10-24 08:48
    关注

    With RewriteRule you can only test the URI path but not the query:

    The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string. If you wish to match against the hostname, port, or query string, use a RewriteCond with the %{HTTP_HOST}, %{SERVER_PORT}, or %{QUERY_STRING} variables respectively.

    So:

    RewriteCond %{QUERY_STRING} ^action=view&item=([0-9]+)$
    RewriteRule ^index\.php$ /index.php?url=item/%1 [R=301,L]
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?