Apache .htaccess mod_重写问题

Apache .htaccess mod_重写问题,apache,.htaccess,Apache,.htaccess,几乎在我从事的任何项目中,.htaccess都会出现一些问题。我通常只是找到最简单的解决方案,然后离开它,因为我对Apache、服务器等没有任何知识或理解。但这次我想我会问你们 这是我的(简化)设置中的文件和文件夹: “config”、“inc”和“lib”文件夹意味着从网站的根目录中“隐藏”。我试图通过在根目录中创建一个.htaccess文件来实现这一点,该文件将用户重定向到“public_html”。.htacess文件包含以下内容: RewriteEngine On RewriteRule

几乎在我从事的任何项目中,.htaccess都会出现一些问题。我通常只是找到最简单的解决方案,然后离开它,因为我对Apache、服务器等没有任何知识或理解。但这次我想我会问你们

这是我的(简化)设置中的文件和文件夹:

“config”、“inc”和“lib”文件夹意味着从网站的根目录中“隐藏”。我试图通过在根目录中创建一个.htaccess文件来实现这一点,该文件将用户重定向到“public_html”。.htacess文件包含以下内容:

RewriteEngine On
RewriteRule   (.*) public_html/$1
RewriteEngine On

# Root
RewriteRule   ^$ page.php [L]

# Login
RewriteRule   ^(admin)|(login)\/?$ login.php [L]

# Page (if not a file/directory)
RewriteCond   %{REQUEST_FILENAME} !-d
RewriteCond   %{REQUEST_FILENAME} !-f
RewriteRule   ^(.*)$ page.php?url=$1 [L]
这很好用。如果我在浏览器中键入“”,我将进入public_html/login.php,这是我的意图。所以这很好用。“public_html”中的.htaccess文件包含以下内容:

RewriteEngine On
RewriteRule   (.*) public_html/$1
RewriteEngine On

# Root
RewriteRule   ^$ page.php [L]

# Login
RewriteRule   ^(admin)|(login)\/?$ login.php [L]

# Page (if not a file/directory)
RewriteCond   %{REQUEST_FILENAME} !-d
RewriteCond   %{REQUEST_FILENAME} !-f
RewriteRule   ^(.*)$ page.php?url=$1 [L]
如果我试图达到“”,第一次重写只是将我重定向到public_html/page.php。下一次重写只是为了方便尝试登录的用户-因此,如果他们尝试访问“”或“”,最终将访问login.php-file。第三次也是最后一次重写处理其余的请求。如果我尝试访问“”,它只会将我重定向到public_html/page.php(设置了'url'GET变量),而不是找到一个名为“la”的文件夹,其中包含一个名为“bla”等的文件夹

所有这些工作都很完美,但当我尝试在URL末尾不加斜杠地到达“”时,会出现一个小问题。当我试图访问该页面时,浏览器不知何故被重定向到“”。显示正确的页面,但为什么会重定向并在URL中添加“public_html”部分?所需的行为是URL保持不变,并显示页面public_html/cms/navigation/index.php

(简化版)中的文件和文件夹可在

找到,可能会有所帮助。在public_html/.htaccess中尝试此操作:

RewriteEngine On
RewriteBase /
也许会有帮助。在public_html/.htaccess中尝试此操作:

RewriteEngine On
RewriteBase /
将以下内容添加到
/modrewrite test/.htaccess

RewriteBase /modrewrite-test
为了安全起见,我还要在
/modrewrite test/public\u html/.htaccess
中添加相同的规则。我发现,总是设置RewriteBase可以防止将来出现很多潜在问题。但是,这意味着如果更改站点的URI结构,可能需要更新这些值

更新:
我认为这在您当前的文件夹结构中是不可能的。我认为问题在于现有的子目录阻止重写规则触发。请注意行为-由于以下两个条件,在处理不存在的文件和目录时,一切正常:

RewriteCond   %{REQUEST_FILENAME} !-d
RewriteCond   %{REQUEST_FILENAME} !-f
但是,如果尝试从现有子目录打开任何索引文件,则会被重定向到
../public\u html/..
。由于您可以正确地打开
/modrewrite test/cms/navigation/edit.php
,因此我只能假设请求被某些Apache核心指令覆盖,该指令在文件夹URL的末尾添加了斜杠。请注意,如果在每个URL上都有一个结束斜杠,那么一切都可以正常工作(即,Apache核心目录不需要“更正”URL,因此所有内容都可以由您自己的重写规则重写)

建议的解决方案(除非有人能给出更好的建议):

/modrewrite test/public_html/.htaccess
更改如下:

RewriteEngine On
RewriteBase /modrewrite-test

# Page (if not a file/directory)
RewriteCond   %{REQUEST_FILENAME} !-d
RewriteCond   %{REQUEST_FILENAME} !-f
RewriteRule   ^(.*)$ page.php?url=$1 [L]
然后从子文件夹中删除所有PHP文件并使用,即通过主
page.PHP
文件发送所有请求,并且不要委托下面的任何内容

然后,您可以使用启动单个UI(即,
导航/edit.php
)直接从主
页面.php
文件根据$\u GET['url']的内容启动(请确保正确清理)

更新#2:
这为Zend框架使用的项目结构提供了建议——它本质上展示了我上面建议的方法。无论您是否使用Zend Framework,它都是有价值的信息资产。

将以下内容添加到
/modrewrite test/.htaccess

RewriteBase /modrewrite-test
为了安全起见,我还要在
/modrewrite test/public\u html/.htaccess
中添加相同的规则。我发现,总是设置RewriteBase可以防止将来出现很多潜在问题。但是,这意味着如果更改站点的URI结构,可能需要更新这些值

更新:
我认为这在您当前的文件夹结构中是不可能的。我认为问题在于现有的子目录阻止重写规则触发。请注意行为-由于以下两个条件,在处理不存在的文件和目录时,一切正常:

RewriteCond   %{REQUEST_FILENAME} !-d
RewriteCond   %{REQUEST_FILENAME} !-f
但是,如果尝试从现有子目录打开任何索引文件,则会被重定向到
../public\u html/..
。由于您可以正确地打开
/modrewrite test/cms/navigation/edit.php
,因此我只能假设请求被某些Apache核心指令覆盖,该指令在文件夹URL的末尾添加了斜杠。请注意,如果在每个URL上都有一个结束斜杠,那么一切都可以正常工作(即,Apache核心目录不需要“更正”URL,因此所有内容都可以由您自己的重写规则重写)

建议的解决方案(除非有人能给出更好的建议):

/modrewrite test/public_html/.htaccess
更改如下:

RewriteEngine On
RewriteBase /modrewrite-test

# Page (if not a file/directory)
RewriteCond   %{REQUEST_FILENAME} !-d
RewriteCond   %{REQUEST_FILENAME} !-f
RewriteRule   ^(.*)$ page.php?url=$1 [L]
然后从子文件夹中删除所有PHP文件并使用,即通过主
page.PHP
文件发送所有请求,并且不要委托下面的任何内容

然后,您可以使用启动单个UI(即,
导航/edit.php
)直接从主
页面.php
文件根据$\u GET['url']的内容启动(请确保正确清理)

更新#2:
这为Zend框架使用的项目结构提供了建议——它本质上展示了我上面建议的方法。无论您是否使用Zend Framework,它都是一项宝贵的信息资产