Erklärt: Mod_rewrite, URL-Rewriting und das Erstellen von „hübschen Links' verstehen
P粉501007768
P粉501007768 2023-10-20 15:47:10
0
2
632

„Hübsche Links“ ist ein oft nachgefragtes Thema, das aber selten vollständig erklärt wird. mod_rewrite ist eine Möglichkeit, „hübsche Links“ zu erstellen, aber es ist komplex, die Syntax ist sehr knapp, schwer zu verstehen und die Dokumentation setzt eine gewisse Vertrautheit mit HTTP voraus. Kann jemand kurz erklären, wie „Pretty Links“ funktionieren und wie man sie mit mod_rewrite erstellt?

Andere gebräuchliche Namen, Aliase und Begriffe für saubere URLs: RESTful-URL, benutzerfreundliche URL, SEO-freundliche URL, Slugging und MVC-URL (möglicherweise eine Fehlbezeichnung)

P粉501007768
P粉501007768

Antworte allen (2)
P粉276064178

为了扩展deceze的答案,我想提供一些示例和一些其他 mod_rewrite 功能的解释。 p>

以下所有示例均假设您已在.htaccess文件中包含RewriteEngine On

重写示例

让我们举个例子:

RewriteRule ^blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$ /blog/index.php?id=$1&title=$2 [NC,L,QSA]

该规则分为 4 个部分:

  1. RewriteRule- 启动重写规则
  2. ^blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$- 这称为模式,但是我'只需将其称为规则的左侧 - 您想要重写的内容
  3. blog/index.php?id=$1&title=$2- 称为替换,或重写规则的右侧 - 您想要重写的内容
  4. [NC,L,QSA]是重写规则的标志,以逗号分隔,稍后我将详细解释

上面的重写将允许您链接到类似/blog/1/foo/的内容,并且它实际上会加载/blog/index.php?id=1&title=foo代码>.

规则的左侧

  • ^表示页面名称的开头 - 因此它将重写example.com/blog/...但不会重写example.com/foo/博客/...
  • 每组(…)括号代表一个正则表达式,我们可以将其捕获为规则右侧的变量。在这个例子中:
    • 第一组括号 -([0-9]+)- 匹配长度至少为 1 个字符且仅包含数字值(即 0-9)的字符串。这可以通过规则右侧的$1引用
    • 第二组括号匹配长度至少为 1 个字符的字符串,仅包含字母数字字符(A-Z、a-z 或 0-9)或-+ code> (注意+用反斜杠转义,因为如果不转义它,这将作为正则表达式重复字符)。这可以通过规则右侧的$2引用
  • ?表示前面的字符是可选的,因此在本例中/blog/1/foo//blog/1/foocode> 将重写到同一位置
  • $表示这是我们要匹配的字符串的结尾

标志

这些选项添加在重写规则末尾的方括号中,用于指定某些条件。同样,您可以在文档中阅读许多不同的标志,但我将介绍一些更常见的标志:

NC

无大小写标志意味着重写规则不区分大小写,因此对于上面的示例规则,这意味着/blog/1/foo//BLOG/1/ foo/(或其任何变体)将被匹配。

L

最后一个标志表明这是应该处理的最后一条规则。这意味着当且仅当该规则匹配时,在当前重写处理运行中不会评估进一步的规则。如果规则不匹配,则将照常尝试所有其他规则。如果您不设置L标志,则随后的所有规则都将应用于重写的URL。

END

自 Apache 2.4 起,您还可以使用[END]标志。与之匹配的规则将完全终止进一步的别名/重写处理。 (而[L]标志通常会触发第二轮,例如在重写子目录或重写子目录时。)

QSA

查询字符串追加标志允许我们将额外的变量传递到指定的 URL,这些变量将添加到原始的 get 参数中。对于我们的示例,这意味着像/blog/1/foo/?comments=15这样的内容将加载/blog/index.php?id=1&title=foo&comments=15

R

这个标志不是我在上面的示例中使用的标志,但我认为值得一提。这允许您指定 http 重定向,并可以选择包含状态代码(例如R=301)。例如,如果您想在 /myblog/ 上执行 301 重定向到 /blog/,您只需编写如下规则:

RewriteRule ^/myblog/(*.)$ /blog/$1 [R=301,QSA,L]

重写条件

重写条件使重写更加强大,允许您指定针对更具体情况的重写。您可以在文档中阅读很多条件>,但我将介绍一些常见示例并对其进行解释:

# if the host doesn't start with www. then add it and redirect RewriteCond %{HTTP_HOST} !^www\. RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

这是一种非常常见的做法,它将在您的域名前面添加www.(如果尚不存在)并执行 301 重定向。例如,加载http://example.com/blog/会将您重定向到http://www.example.com/blog/

# if it cant find the image, try find the image on another domain RewriteCond %{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (.*)$ http://www.example.com/$1 [L]

这种情况稍微不太常见,但这是一个很好的示例,说明如果文件名是服务器上存在的目录或文件,则不会执行该规则。

  • %{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]只会对文件扩展名为 jpg、jpeg、gif 或 png 的文件执行重写(大小写为不敏感)。
  • %{REQUEST_FILENAME} !-f将检查当前服务器上是否存在该文件,如果不存在则执行重写
  • %{REQUEST_FILENAME} !-d将检查当前服务器上是否存在该文件,如果不存在则执行重写
  • 重写将尝试加载另一个域上的相同文件
    P粉022140576

    要了解 mod_rewrite 是什么,您首先需要了解 Web 服务器的工作原理。 Web 服务器响应HTTP 请求。最基本级别的 HTTP 请求如下所示:

    GET /foo/bar.html HTTP/1.1

    这是浏览器向 Web 服务器请求URL/foo/bar.html的简单请求。需要强调的是,它并不请求文件,它只是请求一些任意的 URL。该请求也可能如下所示:

    GET /foo/bar?baz=42 HTTP/1.1

    这与 URL 请求一样有效,而且显然与文件无关。

    Web 服务器是一个侦听端口的应用程序,接受来自该端口的 HTTP 请求并返回响应。 Web 服务器完全可以自由地以它认为合适的任何方式响应任何请求/以您配置它响应的任何方式响应。此响应不是一个文件,而是一个HTTP 响应,它可能与任何磁盘上的物理文件有任何关系,也可能没有任何关系。 Web 服务器不一定是 Apache,还有许多其他 Web 服务器,它们都只是持久运行并附加到响应 HTTP 请求的端口的程序。你可以自己写一个。本段的目的是让您摆脱 URL 直接等于文件的任何观念,理解这一点非常重要。 :)

    大多数 Web 服务器的默认配置是在硬盘上查找与 URL 匹配的文件。如果服务器的文档根设置为/var/www,它可能会查找文件/var/www/foo/bar. html存在,如果存在则提供它。如果文件以“.php”结尾,它将调用 PHP 解释器并返回结果。所有这些关联都是完全可配置的;文件不必以“.php”结尾,Web 服务器即可通过 PHP 解释器运行该文件,并且 URL 不必与磁盘上的任何特定文件匹配才能发生某些事情。

    mod_rewrite 是一种重写内部请求处理的方法。当 Web 服务器收到对 URL/foo/bar的请求时,您可以将该 URL 重写为其他内容,然后 Web 服务器会在磁盘上查找匹配的文件它。简单的例子:

    RewriteEngine On RewriteRule /foo/bar /foo/baz

    此规则表示只要请求匹配“/foo/bar”,请将其重写为“/foo/baz”。然后该请求将被处理,就像/foo/baz。这可用于各种效果,例如:

    RewriteRule (.*) $1.html

    此规则匹配任何内容 (.*) 并捕获它 ((..)),然后重写它以附加“.html” ”。换句话说,如果/foo/bar是请求的 URL,则将按照/foo/bar.html已被请求的方式进行处理。有关正则表达式匹配、捕获和替换的详细信息,请参阅http://regular-expressions.info

    另一个经常遇到的规则是:

    RewriteRule (.*) index.php?url=$1

    这再次匹配任何内容并将其重写到文件index.php,并在url查询参数中附加最初请求的 URL。即,对于传入的任何和所有请求,都会执行文件index.php,并且该文件将有权访问$_GET['url']中的原始请求,因此它可以做任何它想做的事情有了它。

    首先,您将这些重写规则放入您的网络服务器配置文件中。 Apache 还允许*您将它们放入文档根目录中名为.htaccess的文件中(即 .php 文件旁边)。

    *如果主 Apache 配置文件允许;它是可选的,但通常会启用。

    mod_rewrite 不做什么

    mod_rewrite 不会神奇地使所有 URL 变得“漂亮”。这是一个常见的误解。如果您的网站中有此链接:

    mod_rewrite 无法使之变得漂亮。为了使其成为一个漂亮的链接,您必须:

    1. 将链接更改为漂亮的链接:

    2. 使用上述任何一种方法,在服务器上使用 mod_rewrite 来处理对 URL/my/pretty/link的请求。

    (可以使用mod_substitute结合转换传出的 HTML 页面及其包含的链接。尽管这通常比仅仅更新 HTML 资源更费力。)

    mod_rewrite 可以做很多事情,您可以创建非常复杂的匹配规则,包括链接多个重写、将请求代理到完全不同的服务或机器、返回特定的 HTTP 状态代码作为响应、重定向请求等。它非常强大,可以如果您了解基本的 HTTP 请求响应机制,将会非常有用。它不会自动使您的链接变得漂亮。

    请参阅官方文档了解所有可能的标志和选项。

      Neueste Downloads
      Mehr>
      Web-Effekte
      Quellcode der Website
      Website-Materialien
      Frontend-Vorlage
      Über uns Haftungsausschluss Sitemap
      Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!