【问题标题】:Create vanity URLs in a LAMP configuration在 LAMP 配置中创建虚 URL
【发布时间】:2011-08-18 03:57:52
【问题描述】:

在 LAMP 配置下创建用户虚 URL 的最佳方法是什么?

例如,可以按如下方式访问用户个人资料页面:

http://www.website.com/profile.php?id=1

现在,如果用户为其个人资料输入“虚 URL”,我希望虚 URL 加载上面的页面。

例如,如果用户选择“i.am.a.user”作为他们的虚 URL,并且他们在数据库中的用户 ID 为 1,则该 URL 可以访问 http://www.website.com/profile.php?id=1并且 http://www.website.com/i.am.a.user.

我知道 .htaccess 中的 mod 重写,但不确定在此处如何工作。

正如我提到的,我的网站使用 PHP、MySQL、Linux 和 Apache。

谢谢。

【问题讨论】:

  • 为什么你认为 modrewite 行不通?
  • 无法理解 mod-rewrite 如何获得虚 URL 值

标签: php mysql apache mod-rewrite vanity-url


【解决方案1】:

假设您的其他页面具有可以检查的特定 URL,以下内容应该会有所帮助。

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9-_]*)$ /profile.php?user=$1 [L]

这有助于维护当前 URL,同时允许用户使用快捷 URL。此外,RewriteRule 将仅匹配不包含 / 的 URL,这将有助于防止非预期重定向。所以,

/i-am-a-user -> MATCHES
/i_am_a_user -> MATCHES
/i-!am-a-user -> NOT MATCHED
/i.am.a.user  -> NOT MATCHED
/i.am.a.user/ -> NOT MATCHED
/some/page/ -> NOT MATCHED
/doesnotexist.php -> NOT MATCHED
/doesnotexist.html -> NOT MATCHED

希望对您有所帮助。

编辑

我已经更新了上面的规则,以便不会重定向实际的文件/目录,并确保任何.php.html 文件也不会发送到profile.php

【讨论】:

  • 如何防止像 /doesnotexist.php 这样的 404?如果用户尝试访问类似的内容,而不是显示我的 404 页面,他们会获得个人资料页面,然后由于没有有效参数(id 或名称)而重定向到我的主页?
  • @Tom,我已经更新了规则,以便它只匹配没有/ 和没有. 的请求。刚刚意识到现在i.am.a.user 将不起作用,而i-am-a-user 会。我再调整一下……
  • 是的,我想如果我们可以让这条规则与“.”一起使用。我们会有解决方案的。
  • 我实际上回到了你原来的版本,因为我认为我不会允许用户选择带有“。”的虚 URL。在他们之中。是否可以修改该 RegEx 以仅允许带有字母数字字符和破折号的虚 URL? /iam!invalid 之类的东西应该映射触发 404 而 /iam-valid 不会。伙计,我讨厌一直这样调整,但我对正则表达式很糟糕。
  • 没问题 :) 再次更新,现在应该只包含不存在的字母数字 URL
【解决方案2】:

为 site.com/user/USERNAME 重写:

在您的网络根目录中,放置一个 .htaccess 文件:

RewriteEngine on
RewriteRule ^user/(.+)$ profile.php?name=$1 [L]

这会将所有以“user”开头的请求路由到 profile.php 并将 URI 传递给$_GET['name']。如果您有很多文件/目录/其他重写,则首选此方法。

为 site.com/USERNAME 重写:

RewriteEngine on
# if directory or file exists, ignore
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ profile.php?name=$1 [L]

仅当请求的文件或目录不存在并且请求 URI 不为空(即 www.site.com)时,才会路由到 profile.php

PHP 后端

现在在 profile.php 中,你可以有这样的东西:

if (!empty($_GET['name'])
    $user = ... // get user by username
else 
    $user = ... // get user by id

【讨论】:

  • 我不建议这样做,因为如果你没有 /user/ 部分,htaccess 文件要么会变得非常混乱,要么你的域之后的整个 url 将被传递给 @987654326 @
  • 那么 Facebook 是如何做到的呢?他们正在运行 LAMP。当然它的规模很大,但概念应该是一样的。
  • 查看martinmelin.se/rewrite-rule-tester 以测试您的 mod_rewrite 设置(免责声明:刚刚发现该站点,但我希望我在几年前就已经考虑过)。
  • 这个概念是相似的,但是你会被一个处理所有请求的 PHP 脚本困住。所以你必须检查每个请求是否存在有效的用户快捷方式,否则找到正确的页面。
  • @Tom:您将拥有一个带有 URL/PHP 页面对的 DB 表并检查它。
【解决方案3】:

首先设置您的 .htaccess 文件以将所有对不存在的文件和目录的请求发送到单个 php 文件:

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) router.php [NC,L]

然后在您的 router.php 中,查看 $_SERVER['REQUEST_URI'] 以获取用户名,然后您可以在查询中使用该用户名来获取有关用户的数据。

这假定所有不是用户个人资料页面的 URL 作为物理文件存在于您的服务器上。

如果不是这样,您可以在 router.php 中执行一些逻辑来决定对每个请求执行什么操作。谷歌搜索 php 中的 url 路由,你会得到很多例子。

【讨论】:

    【解决方案4】:

    当然,您也可以使用 apache RewriteMap 来解决这个问题。 RewriteMap 可以是纯文本文件(您可以根据用户输入的内容定期更新),或者您可以将其指向一个脚本(Perl、PHP,任何适合您的)来为您进行重写。

    有关如何使用 PHP 进行设置的快速摘要,请参阅 Using a MySQL database to control mod_rewrite via PHP

    【讨论】:

      猜你喜欢
      • 2018-11-07
      • 1970-01-01
      • 2018-05-09
      • 1970-01-01
      • 1970-01-01
      • 2011-04-23
      • 1970-01-01
      • 2013-11-03
      • 1970-01-01
      相关资源
      最近更新 更多