2016-11-22 97 views
2

文件夹结构:htaccess的漂亮的URL不工作

- 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添加漂亮的URL,例如 - localhost:8080/app/customers.php?id=5更改为localhost:8080/app/customers/id/5

htaccess添加新行:

RewriteRule /id/(.*) customers.php?id=$1 

它不工作,它总是返回500内部服务器错误可能有问题吗?

加上所需要的所有URL,而不.PHP扩展

+0

/id/(.*)将始终与customers/php?** id **匹配,因此您的规则将始终循环 – Gerrit0

+0

,那么如何更改该行可以在我的情况下工作? –

+2

对不起,我对这个假设过于仓促,问题不在于这个问题,问题在于你的第一条规则,它总是匹配的,所以总是在你的URL的开头添加/查看/。 htaccess规则非常容易搞乱。在尝试很好地回答这个问题之前,我需要学习更多。 – Gerrit0

回答

6

你不得不包括每个规则这些条件。你最好重写所有内容,比如views/router.php,然后使用PHP来包含不同的控制器,或者在URL无效时提供404。

RewriteRule !^views/router\.php$ views/router.php [NS,L,DPI] 
+0

是的,大多数PHP webapps /框架重写为index.php,它将加载所有必需的代码,包括任何路由 –

0

有另一个裂缝。

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] 

您可能需要使用的L代替END标志,如果你的Apache是​​老年人。也为404s设置一个ErrorDocument。

不要用查询字符串来解决问题,只需在PHP中解析$_SERVER['REQUEST_URI'],例如首先在/上爆炸。然后,您将拥有原始漂亮网址的所有参数。你可以在包含中做这个部分,这样每个控制器就可以重用相同的代码。

1

请参阅问题,How to make Clean URLs

我觉得这是你需要的东西。

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

0

我想你的结构和.htaccess文件我发现在Apache日志中无限循环。我敢打赌,你有这样的事情:

RewriteRule id/(.*) /views/app/customers.php?id=$1 

领先不需要/的比赛和目标所需要的完整路径:

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. 

我可以把最后的规则一样解决它。请注意,我在网址上获得了id双精度(例如123/123):http://localhost:8080/id/123

这是由以前的两个规则之一(删除它们修复它)引起的,因此您可能需要更改它们。

0

这里是你想要的东西:

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] 
1

我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 

如你意,这个重写规则将匹配这不是一个文件,而不是目录中的任何URL ,并制作到localhost:8080。

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陈述仅适用于第一重写规则跟了上去,因此正被这里检查了所有的路径是非常重要的。

备注:^(/)?$,因为您未使用$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将立即停止当前迭代,并开始从顶部再次匹配。 The documentation is badly worded。因此,localhost:8080/views/index.php将通过第一条规则运行,不匹配,通过此规则运行,无法匹配,然后由于没有其他规则存在检查(但)不会进行重写。

现在让我们来看看添加破损规则时会发生什么。

RewriteRule /id/(.*) customers.php?id=$1 

这里有几个问题。首先,由于您不需要网址以/id/开头,即使您已经重写了网址,该规则也会始终与包含/id/的网址匹配。如果您使用^/id/(.*)对此进行了修改,那么您仍然会遇到问题,因为重写RegEx所测试的字符串已删除了前导斜杠。最后也是最重要的是,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规则可能令人难以置信地混淆。