foo.com/alice与foo.com/users/alice

时间:2009-04-23 04:25:29

标签: url mod-rewrite url-rewriting namespaces friendly-url

为用户提供网站内容的友好网址当然很不错。但是如何最好地做到这一点?像foo.com/users/alice这样的东西有很多优点,最重要的是你不会弄乱根命名空间。但我认为用户的简单性胜过所有这些。许多大型网站似乎都同意(友情,美味和flickr),这个问题是关于如何在服务器端实现这一点。

我们假设alice的真实网址是foo.com/userpage?user=alice,如果有人试图浏览一个不存在的用户页面(让我们说foo.com/bob),他们应该访问foo.com/createnew?用户鲍勃=

用户当然不应该看到上面丑陋的“真实”网址,只有foo.com/alice或foo.com/bob。请注意,根命名空间是共享的。例如,foo.com / help不应转换为foo.com/userpage?user=help。

据推测,我要求一些简单的mod_rewrite规则,但也许有一些完全不同的方法,我没想到。无论如何,我认为在这个常见问题上记录一个确定的或“最佳实践”的解决方案会很好。

PS:请随意评论alice.foo.com或users.foo.com/alice等其他替代方案的优点。

PPS:我想我已经看到这个问题在其他问题上有争议,但搜索似乎很棘手。指针欢迎!当然,除了可以使其更易于搜索的其他关键字。关键字:用户空间,全局命名空间,URL命名空间。

2 个答案:

答案 0 :(得分:5)

我想说这取决于您的网站以用户为中心。

像myspace这样的网站是http://www.myspace.com/jim/,因为该网站完全围绕着用户。

博客或新闻网站,您可以注册,但不重要或强制性可以从

中受益

http://www.news.com.au/users/jim/

您认为如果您正在与用户建立一个可以从MVC设计模式中受益的网站,或者至少是一个使用路由器来引导URI的流行MVC框架吗?

如果该URI来自路由器,然后被发送到UsersController,您可以决定显示用户的配置文件,或指示他们创建该用户。你不需要乱用mod_rewrite,除了制定一个规则,将所有对不存在文件的请求定向到index.php(或者服务器端语言的默认值)

如果您确实想使用mod_rewrite,请尝试使用这些规则

RewriteEngine On
RewriteCond %{REQUEST_URI} !(home|contact|about) [NC] // this line may be incorrect
RewriteRule ^/users/([^/]+)/?$ userpage?user=$1 [NC,L]

请注意Gumbo建议的领先Carat,因此它仅匹配TLD /用户/。

这将匹配foo.com/users/bob之类的可选尾部斜杠。它不区分大小写,将是最后应用的规则。

如果请求进来且您的数据库中不存在$ _GET ['user'],您可以尝试这样的事情

$user = $_GET['user'];

if (!user_exists($user)) {

    header('Location: createnew?user=' . urlencode($user));
    exit();

}

然后在createnew页面上,只需执行类似这样的操作

<input type="text" name="username" value="<?php echo htmlspecialchars(urldecode($_GET['user'])); ?>" />

这将使用他们尝试访问配置文件的用户名自动填写用户名。

如果您想了解有关PHP和MVC的更多信息,请尝试Google搜索或在Stack Overflow上提问。

答案 1 :(得分:3)

以下规则将表格foo.com/bar的URL重写为foo.com/userpage?user=bar条件,条件不是服务器上的文件或目录。将以下内容放在.htaccess中:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ userpage?user=$1 [NC,L]
</IfModule>

与Alex的回答一样,如果用户不存在,用户页面脚本应该重定向到createnew:

$user = $_GET['user'];
if (!user_exists($user)) {
  header('Location: createnew?user=' . urlencode($user));
}

(正如Knuth所说,要注意上面代码中的错误 - 我只是证明它是正确的,没有尝试过。当我确实确认它有效时,我会更新这个答案。)PS:确认!