dre*_*ves 9 url mod-rewrite friendly-url namespaces url-rewriting
为用户提供网站内容的友好网址当然很好.但是如何最好地做到这一点?像foo.com/users/alice这样的东西有很多优点,最重要的是你不会弄乱根命名空间.但我认为用户的简单性胜过所有这些.许多大型网站似乎都同意(友情,美味和flickr想到),这个问题是关于如何在服务器端实现这一点.
让我们假设alice的真实网址是foo.com/userpage?user=alice,如果有人试图浏览到不存在的用户页面(让我们说foo.com/bob),他们应该访问foo.com/createnew?user=bob .
当然,用户永远不应该看到上面那些丑陋的"真实"网址,只有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命名空间.
我会说这取决于您的网站以用户为中心.
像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]
Run Code Online (Sandbox Code Playgroud)
请注意Gumbo建议的领先Carat,因此它仅匹配TLD /用户/.
这将匹配任何像foo.com/users/bob和可选的尾部斜杠.它不区分大小写,将是最后应用的规则.
如果请求进入并且您的数据库中不存在$ _GET ['user'],您可以尝试这样的事情
$user = $_GET['user'];
if (!user_exists($user)) {
header('Location: createnew?user=' . urlencode($user));
exit();
}
Run Code Online (Sandbox Code Playgroud)
然后在createnew页面上,只需执行此类操作即可
<input type="text" name="username" value="<?php echo htmlspecialchars(urldecode($_GET['user'])); ?>" />
Run Code Online (Sandbox Code Playgroud)
这将使用他们尝试访问配置文件的用户名自动填写用户名.
如果您想了解有关PHP和MVC的更多信息,请尝试Google搜索或在Stack Overflow上提问.
以下规则将 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>
Run Code Online (Sandbox Code Playgroud)
正如 Alex 的回答所示,如果用户不存在,用户页面脚本应重定向到 createnew:
$user = $_GET['user'];
if (!user_exists($user)) {
header('Location: createnew?user=' . urlencode($user));
}
Run Code Online (Sandbox Code Playgroud)
(正如 Knuth 所说,请注意上述代码中的错误 - 我只是证明了它是正确的,没有尝试过。当我真正确认它有效时,我会更新这个答案。) PS:已确认!