2016-11-22 96 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規則可能令人難以置信地混淆。