最近,在做自己的個人網站時,采用了輕量級的php框架CodeIgniter。乍一看上去,代碼清晰簡潔,MVC模型非常容易維護。開發時我采用的工具是Netbeans IDE 8.0,當然,本文的內容和開發工具是沒有關系的,和我們最後網站采用的服務器有很大的關系。目前最為常用的兩款免費web服務器是Apache和Nginx(這兩款服務器的比較,可以參考一篇網上的經典文章:http://zyan.cc/nginx_php_v6/)。在我網站開發與上線的過程中,剛好兩個服務器都用到了,他們配置CodeIgniter時稍有區別,接下來分別闡述一下,也為了讓其他開發者在使用CodeIgniter框架時少踩坑。
(1)關於CodeIgniter
CodeIgniter是一款開源的超輕量級MVC框架,常用於快速地Web開發中,如果你願意,甚至可以隨意地更改其中的源代碼,以適應自己的需求。這個框架本身不想多做介紹,需要熟悉的朋友可以去CodeIgniter官方網站下載,並且官網也提供了非常詳細的中文幫助手冊,可以很好的幫助新人學習。幫助手冊鏈接: http://codeigniter.org.cn/user_guide/toc.html 。幫助手冊中從0開始教你搭建一個簡單的網站。
(2)CodeIgniter架設的網站URL
最開始CodeIgniter搭建的網站URL是這樣子的:
http://[網站網址]/index.php/[controller class name]/[class function name]/[function parameter]
舉個例子說明:http://127.0.0.1/index.php/welcome/hello/zhangsan。這個例子中,假設了網站的網址是127.0.0.1,也就是我們常用的本機地址,采用controller文件夾中的welcome.php這個用php編寫的類處理這個url請求,具體處理方法是調用這個welcome類裡面的hello函數,這個函數是需要一個參數的,我們傳進去的參數是字符串zhangsan。不過有一點比較礙眼,就是url裡面包含了一個固定的字段index.php,看著很不爽。我想要的結果是這樣的:http://127.0.0.1/welcome/hello/zhangsan。那麼如何把index.php去掉呢?這就是我想主要分享的地方。
在講如何去掉index.php之前,我們先弄清楚它為什麼會出現在這裡。對於任意一個url請求,CodeIgniter都是先由位於網站跟目錄下的index.php文件處理的,這個文件再根據你提供的url中index.php後面的部分來確定把這個請求重新交給哪一個類的哪一個函數處理。因此,url中必須包含index.php這個字段,顯式的告訴服務器,這個url你先讓index.php去重新定向到我後面指定的類去處理。如果不經過任何配置就直接把index.php去掉,你的網頁是顯示不出來的。那麼我們如果要去掉它,就是希望經過一些配置選項,讓服務器見到一個url默認地就用index.php去處理就好了,不用再把index.php顯示在url裡面。
(3)Apache服務器下去掉index.php
我在自己電腦上開發時使用的是Apache服務器,因此不可避免地要先在Apache服務器下解決這個問題。其實,文章開始時提到的CodeIgniter官方幫助手冊裡面已經給了Apache下的解決辦法,卻沒有給出Nginx下的解決辦法。沒辦法,Apache服務器據說市場占有率已經超過60%,作為如此主流的服務器,官方手冊還是有必要說明它的配置方法的。為了更加清晰一些,我再更加詳細地說明一下。
在網站根目錄下(也就是與前文提到的index.php同一個目錄下),新建一個文件,名為.htaccess。注意不要忘了htaccess前面還有個點。用記事本打開這個文件,寫入如下命令:
RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond $1 !^(index\.php|images|js|css|robots\.txt) RewriteRule ^(.*)$ /index.php/$1 [L]
看一下英文單詞Rewrite也猜到了,其實這個文件控制的就是url的重寫規則。關於.htaccess文件的具體重寫規則和全部種類的語法又是一門大學問,在這裡就不詳述了。我們只關心上面寫的這幾句話是啥意思。
第一句 RewriteEngine on:翻譯過來就是“重寫引擎 開啟”,相當於啟動url重寫機制。
第二句 RewriteCond %{REQUEST_FILENAME} !-f:翻譯過來就是“重寫條件 請求文件名不是個文件”。最後一個字母f理解為file,!-f的感歎號表示否定,也就表示不是個file。
第三句 RewriteCond %{REQUEST_FILENAME} !-d:翻譯過來就是“重寫條件 請求文件名不是個目錄”。最後一個字母d理解為directory。
第二句與第三句的用途是說,只有在你的URL請求不是文件的名字或者文件夾名字的時候,才啟用重寫規則。舉例說明,比如http://127.0.0.1/test.html。這個請求其實就是在你的網站根目錄下尋找test.html,如果找到了,就直接返回這個文件即可,不用重寫;只有在根目錄找不到test.html時,才重寫這個url,這是REQUEST_FILENAME是個文件的例子。再比如http://127.0.0.1/nihao,這裡nihao很有可能是根目錄下的一個文件夾(當然也可以是一個沒後綴的文件),這種情況下先尋找根目錄有沒有nihao這個文件夾,沒有的話再啟用url重寫,這是REQUEST_FILENAME是個目錄的例子。
第四句 RewriteCond $1 !^(index\.php|images|js|css|robots\.txt):翻譯過來就是“重寫條件 url網址後的第一個參數不可以是index.php,images, css, js, robots.txt任何一個”。比如 http://127.0.0.1/images/girl.png,這個url第一個參數是images,這種情況下不要重寫,只有不是以上列出來的那些時才重寫。這句話目的是排除一些url請求的重寫,因為我們經常會把網站的css文件,javascript文件,圖片文件放在根目錄下的css,js,images文件夾下,然後在網頁中通過url引用這些資源,如果請求這些資源的url也被重寫了,網頁中就引用不到了。你可以根據自己的實際需求,新添加一些需要排除在外的重寫url的情況。
第五句 RewriteRule ^(.*)$ /index.php/$1 [L]:翻譯過來就是“重寫規則 把url網址後第一個參數前面加上index.php”。[L]表示這是最後一條重寫規則,後面沒有了。
這樣,你如果在浏覽器輸入http://127.0.0.1/hello/zhangsan,其實相當於是http://127.0.0.1/index.php/hello/zhangsan。
最後還有一個小坑,就是在使用工具開發網站的時候,往往我們網站代碼並不在Apache服務器的根目錄下,比如我們在Apache服務器的根目錄下又建立一個文件夾xxx,並且把網站整個放在這個文件夾裡面,那麼我們的主頁地址就是http://127.0.0.1/xxx/index.php。這時必須把上面配置文件第五句話改為RewriteRule ^(.*) /xxx/index.php/$1 [L],還有一種改法是直接去掉第五句話中index.php前面的斜槓(即RewriteRule ^(.*)$ index.php/$1 [L]),這一點千萬注意!
完成了上面的.htaccess文件後,還有兩件事情要做。
第一,找到CodeIgniter中的application/config/config.php文件,把index_page設為空值,即$config['index_page'] = '"";還有base_url設為網站根目錄(index.php所在目錄),$config['base_url']="http://127.0.0.1/xxx/"。部署到真正服務器上使網站上線前,不要忘了把127.0.0.1改成你網站的網址,如果index.php放在服務器根目錄,也記得把base_url裡這個xxx去掉。
第二,找到Apache的配置文件,也就是conf/httpd.conf這個文件,確保LoadModule rewrite_module modules/mod_rewrite.so前面的井號#已經去掉了。然後關鍵字搜索htaccess,找到配置.htaccess的部分,其設置應該改為AllowOverride All。其實如果你沒有用很舊版本的Apache,井號和AllowOverride All默認就應該是設置好了的。這一步只是確認一下,不是這麼配的要改成這樣。
至此,Apache服務器下CodeIgniter的URL配置大功告成。現在index.php已經不需要出現在URL中了,系統會默認讓index.php先去處理URL。
(4)Nginx服務器下去掉index.php
上文中提到的Apache去掉index.php在官方幫助文檔也有簡要的說明,但是Nginx服務器就沒有這麼幸運了。我在網站開發時本地是Apache,但是網站上線時的服務器卻是Nginx的,因此不得已又去網上搜索Nginx服務器下的配置,折騰了很久,試錯試了很多次,總算把一個正確的版本試出來了,現在可以提供給大家參考。因為自己對於Nginx的配置沒有深入研究過,所以先說明一下自己線上服務器用的環境,然後再展示Nginx配置的修改內容。以我目前的配置,親測可以很好地工作,大家碰到了類似的問題可以按照我的配置嘗試一下,不過我也不敢保證在您的系統上一定會奏效……我的線上服務器是買的XX雲(避免廣告~)服務器(自己從零開始搞一個服務器實在太麻煩了),系統配置好之後默認就是Nginx。操作系統采用的是Ubuntu 12.04,Nginx版本是nginx/1.1.19。
看網上好多人的Nginx服務器默認配置文件是/etc/nginx/nginx.conf,我的也不例外。不過有個注意事項,有時候nginx.conf中會有一句include ***(另外一個文件),也就是引用外邊某個文件的內容作為配置文件,這時候,如果你沒有在nginx.conf中找到服務器server相關配置,不妨去它include的另外一個文件中找一下,我的就是這種情況。在我的配置文件中,和服務器有關的配置應該改成如下:
server { listen 80; root /usr/share/nginx/www; index index.php index.html index.htm; # Make site accessible from http://localhost/ server_name localhost; location / { index index.php index.html index.htm; # Uncomment to enable naxsi on this location # include /etc/nginx/naxsi.rules # 請留意下面這條重寫規則,和前面的Apache有些類似 if (!-e $request_filename) { ##如果沒有找到目標文件 rewrite ^/(.*)$ /index.php/$1 last; break; } # 上面的重寫規則也可以改成下面這種形式,親測兩者都可行 # if ($request_filename !~ (js|styles|images|robots\.txt|index\.php.*)){ ##如果不是請求js,styles等文件
# rewrite ^/(.*)$ /index.php/$1 last;
# break;
# } } location /doc/ { alias /usr/share/doc/; autoindex on; allow 127.0.0.1; deny all; } location ~ \.php($|/) { fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # location ~ /\.ht { deny all; } }
具體的改動已經標注在上面的注釋中了,很簡單的一句重寫規則,我卻折騰了蠻久的時間。希望分享出來,幫助大家少踩坑。就寫到這裡吧!
//use url helper
$this->load->helper('url');
current_url = current_url();
CodeIgniter 是一個輕量級的,快速的,能生成非常干淨而且是對搜索引擎友好化的URL的PHPMVC框架,默認情況下,index.php 文件將被包含在你的 URL 中 例如:example.com/index.php/news/article/my_article首先確保你的Apache服務器支持支持 mod_rewrite,開啟mod_rewrite需要修改httpd.conf,去掉LoadModule rewrite_module modules/mod_rewrite.so前的#你可以很容易的通過 .htaccess 文件來設置一些簡單的規則刪除它。下面是一個例子,使用“negative”方法將非指定內容進行重定向:RewriteEngine onRewriteRule ^(.*)$ /index.php/$1 [L]如果你的項目不在根目錄請把上面這一句改為:RewriteRule ^(.*)$ index.php/$1 [L]然後將該文件放在網站的根目錄在上面的例子中,可以實現任何非 index.php、images 和 robots.txt 的 HTTP 請求都被指向 index.php。注意根據你項目的位置修改文件的配置。將AllowOverride設置為none可以完全禁止使用.htaccess文件,注意將你Apache的配置文件AllowOverride設置成All