9

为用户在您的网站上的内容提供友好的 URL 固然很好。但如何最好地做到这一点?像 foo.com/users/alice 这样的东西有很多优点,最重要的是你不会弄乱你的根命名空间。但我认为用户的简单性胜过这一切。许多大网站似乎都同意(friendfeed、delicious 和 flickr 浮现在脑海中),这个问题是关于如何在服务器端实现这一点。

假设 alice 的真实 URL 是 foo.com/userpage?user=alice,如果有人试图浏览一个不存在的用户页面(比如说 foo.com/bob),他们应该到达 foo.com/createnew?user=bob .

用户当然不应该看到上面丑陋的“真实” URL,只是 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 命名空间。

4

2 回答 2

6

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

myspace 之类的网站是http://www.myspace.com/jim/,因为该网站完全围绕用户展开。

但是,您可以注册但不重要或不强制的博客或新闻网站可以从中受益

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

你认为如果你正在做一个有用户的网站,你可以从 MVC 设计模式中受益,或者至少是一个流行的 MVC 框架,它使用路由器来引导 URIs?

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

如果您确实想使用 mod_rewrite,请尝试以下规则

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

请注意 Gumbo 建议的前导克拉,因此它仅匹配 TLD 的 /users/。

这将匹配 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 上提问。

于 2009-04-23T04:43:03.240 回答
3

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

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

正如亚历克斯的回答,如果用户不存在,用户页面脚本应该重定向到 createnew:

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

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

于 2009-04-24T01:05:52.697 回答