htaccess 重写 url 以便仅在根目录而不是子目录中删除 php 扩展名

htaccess to rewrite url in order to remove php extension only at the root directory and not in subdirectories

我有一个网站组成如下:

index.php
page1.php
page2.php
page3.php
 - images
   image1.jpg
   image2.jpg
 - style
   style.css

我想写一个可以给我 SEO 友好的 htaccess 文件 URL。例如:

还有:

但我只想在第一个目录上应用这些规则,因此可以使用扩展名继续访问“图像”和“样式”目录。

有人可以帮忙吗?谢谢

  1. 您应该已经链接到文件 ,而没有 内部 URL 上的 .php 扩展名(即。href="/page1",而不是 href="/page1.php")。我还假设您的 URLs 不包含点(通常用于分隔文件扩展名)。

  2. 实施重写以在需要时附加 .php 扩展名。这需要靠近根 .htaccess 文件的顶部:

    RewriteEngine On
    
    # Internally rewrite extenionless URLs to append ".php" if required
    # Tests only requests (that do not contain a dot) in the root directory
    RewriteCond %{DOCUMENT_ROOT}/.php -f
    RewriteRule ^([^./]+)$ .php [L]
    

    RewriteCond(文件系统检查)的替代方法:

    RewriteCond %{REQUEST_FILENAME}.php -f
    :
    

    或者,您可以完全删除 RewriteCond 指令以无条件地重写根目录中的所有请求(没有文件扩展名)以附加 .php 扩展名。

  3. (可选)如果您要更改 URL 结构并从 URL 中删除 .php,而旧的 URL 已被第三方链接到的搜索引擎 and/or 索引,那么您还需要实施重定向以删除 SEO 的 .php 扩展。

    在上面的 RewriteEngine 指令之后立即添加以下内容(在内部重写之前):

    # Redirect to remove the `.php` extension inbound requests
    # Only affects the root directory
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^([^./]+)\.php$ / [R=301,L]
    

    针对 REDIRECT_STATUS 环境变量进行测试的 条件 确保我们不会通过稍后的重写重定向已经重写的请求,这避免了重定向循环。

    注意:首先使用 302(临时)重定向进行测试,以避免潜在的缓存问题。

  4. 或者(而不是 #3),以防止直接访问 .php 文件并提供 404 Not Found 而不是添加在上面的 RewriteEngine 指令之后(内部重写之前):

    # Prevent direct access to ".php" file and serve a 404 instead
    # Only affects the root directory
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^([^./]+)\.php$ - [R=404]
    

what is the best way to show the content of my custom 404 page every time a 404 error occurs? (I would not like to use redirect)

.htaccess 文件的顶部使用以下内容,将完整的 URL-path 传递给 ErrorDocument 指令。

ErrorDocument 404 /error-docs/e404.php

声明的错误文档是使用内部子请求调用的(没有外部重定向)。

请注意,此处应包括 .php 文件扩展名 - 这对用户来说是完全不可见的。