Apache htaccess不工作

Apache htaccess不工作,apache,.htaccess,mod-rewrite,Apache,.htaccess,Mod Rewrite,文件夹结构: - assets - all css / js - calsses - all models, db ant etc - views - admin - app - index.php - customers.php ....... 我的.htaccess RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d Re

文件夹结构:

- assets
  - all css / js
- calsses
  - all models, db ant etc
- views
  - admin
  - app
    - index.php
    - customers.php
    .......
我的.htaccess

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteCond %{HTTP_HOST} ^(www.)?localhost:8080$

RewriteRule ^(.*)$ /views/$1
RewriteRule ^(/)?$ /views/index.php [L]
地址:
localhost:8080/app/
-工作正常,但随后我尝试在我的
customers.php
-
localhost:8080/app/customers.php?id=5
更改为
localhost:8080/app/customers/id/5

htaccess添加了新行:

RewriteRule /id/(.*) customers.php?id=$1
它不工作,总是返回500内部服务器错误可能有问题吗


另外,如果您需要所有不带.php extend的URL,则必须为每个规则包含这些条件。您最好将所有内容重写为,比如说
views/router.php
,然后使用php包含不同的控制器,或者在URL无效时提供404

RewriteRule !^views/router\.php$ views/router.php [NS,L,DPI]
又有裂缝

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{HTTP_HOST} !^(?:www\.)?localhost:8080$ [OR]
RewriteCond $0 =views
RewriteRule [^/]* - [END]

RewriteRule ^(app|admin)/([^/]+) views/$1/$2.php [DPI,END]
RewriteRule ^(app|admin)/?$ views/$1/index.php [DPI,END]
如果Apache较旧,则可能必须使用
L
而不是
END
标志。也为404设置一个错误文档


不要乱动查询字符串,只需在PHP中解析
$\u服务器['REQUEST\u URI']
,例如,首先在
/
上分解它。然后您将拥有原始漂亮URL的所有参数。您可以在include中执行该部分,这样每个控制器都可以重用相同的代码。

请参考问题

我想这就是你需要的


您可以使用
RewriteRule^(.*)$index.php[QSA,L]

我自己尝试了您的结构和.htaccess文件,在apache日志中发现了一个无休止的循环。我打赌你会得到这样的东西:

Mon Nov 28 19:57:32.527765 2016] [core:error] [pid 10] [client 172.18.0.1:35048] AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
我可以通过添加最后一条规则来修复它,如:

RewriteRule id/(.*) /views/app/customers.php?id=$1
匹配不需要前导/前导,目标需要完整路径。请注意,我在url上获得了双id(例如123/123)


这是由前面两条规则之一(删除它们会修复它)导致的,因此您可能需要更改它们。

以下是您想要的:

RewriteEngine On
RewriteBase /app/

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l

RewriteRule ^\/?$ views/index.php [L]
RewriteRule ^([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)\/?$ views/$1.php?$2=$3 [L]
RewriteRule ^([a-zA-Z0-9]+)\/?$ views/$1.php [L]

我同意Walf的观点,通过路由器类处理路由比使用
.htaccess
重定向更好(尤其是从长远来看!)

然而,由于你的问题似乎更多的是关于为什么这不起作用,而不是关于你应该如何做,这里是一个关于发生了什么的解释

我将使用以下URL作为示例:

localhost:8080
localhost:8080/app
localhost:8080/app/customers/id/5
你的第一条规则:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} ^(www.)?localhost:8080$
RewriteRule ^(.*)$ /views/$1
正如您所希望的那样,此重写规则将匹配任何不是文件、不是目录且创建为localhost:8080的URL

localhost:8080 # not matched because it leads to a directory. 
localhost:8080/app -> localhost:8080/views/app
localhost:8080/app/customers/id/5 -> localhost:8080/views/app/customers/id/5
你的下一条规则:

RewriteRule ^(/)?$ /views/index.php [L]
重要的是要认识到RewriteCond语句只适用于它们后面的第一个RewriteRule,因此这里要检查的就是路径

旁注:
^(/)?$
,因为您没有使用
$1
,所以可以简化为
^/?$

localhost:8080 -> localhost:8080/views/index.php
localhost:8080/views/app # not matched
localhost:8080/views/app/customers/id/5 # not matched
当指定了
L
标志时,Apache将立即停止当前的迭代,并从顶部重新开始匹配。因此,
localhost:8080/views/index.php
将通过第一条规则运行,不匹配,通过此规则运行,不匹配,然后由于没有其他规则可供检查,因此不会进行重写

现在让我们看看当你添加你的破规则时会发生什么

RewriteRule /id/(.*) customers.php?id=$1
这里有一些问题。首先,由于您不要求URL以
/id/
开头,因此即使您已经重写了URL,规则也将始终匹配包含
/id/
的URL。如果使用
^/id/(.*)
对其进行了修改,那么仍然会有问题,因为测试重写正则表达式所针对的字符串删除了前导斜杠。最后也是最重要的一点,
customers.php
不存在于根目录中

localhost:8080/views/index.php # not matched
localhost:8080/views/app # not matched
localhost:8080/views/app/customers/id/5 -> localhost:8080/customers.php?id=5
这是当前文件中的最后一条规则,所以现在Apache将重新开始
customers.php
在您的目录中不存在,因此它将被重写为
views/customers.php
。没有匹配的其他规则,但URL已更改,因此Apache将重新启动,因为
/views/customers.php
不存在,它将被重写为
/views/views/customers.php
。。。此模式将重复,直到达到最大迭代限制,Apache将以500错误响应

你可以用几种方法来解决这个问题。这是我的首选方法,但前提是你不能使用路由器

RewriteEngine on

# Rewrite the main page, even though it is a directory
RewriteRule ^/?$ views/index.php [END]

# Don't rewrite any existing files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .? - [S=999,END]

RewriteRule ^app/?$ views/app/index.php [END]
RewriteRule ^app/id/(.*)$ views/app/customers.php?id=$1 [END]


TL;DR使用基于PHP的路由器
.htaccess
规则可能会令人难以置信地困惑。

/id/(*)将始终匹配客户/php?**id**,因此您的规则将始终循环,那么我如何更改这一行才能在我的情况下起作用呢?抱歉,我的假设太仓促了,问题不是这一行,问题是您的第一条规则,它将始终匹配,因此始终将/views/添加到URL的开头。htaccess规则非常容易搞乱。在我试图回答好这个问题之前,我需要学习更多。这是否意味着您希望
app
显示在您的live站点的URL中?是的,我想显示的app是,大多数PHP Web应用/框架也会重写为index.PHP,它将加载所有必需的代码,包括任何路由