PHP+MYSQL三日通
Jun 21, 2016 am 09:14 AMmysql
一、PHP/MySQL簡(jiǎn)介
您應(yīng)該聽(tīng)說(shuō)過(guò)開(kāi)放源代碼軟件(OSS),除非最近六到八個(gè)月來(lái)您一直住在火星上。這場(chǎng)運(yùn)動(dòng)有著巨大的沖擊力,已引起一些大公司的注意。象Oralce、Informix,還有多家公司都開(kāi)始把他們的主力數(shù)據(jù)庫(kù)產(chǎn)品移植到OSS的產(chǎn)物之一 - Linux操作系統(tǒng)上。
如果您有足夠的技術(shù)力量,擁有一個(gè)復(fù)雜龐大的關(guān)系數(shù)據(jù)庫(kù)系統(tǒng)(RDBMS)則是如虎添翼。但是也許您對(duì)數(shù)據(jù)庫(kù)還剛剛?cè)腴T(mén),您剛剛讀了Jay的文章,決定自己也來(lái)搞一個(gè)數(shù)據(jù)驅(qū)動(dòng)的網(wǎng)站??墒悄苍S會(huì)發(fā)現(xiàn)您缺乏必要的資源來(lái)運(yùn)行ASP服務(wù)器或昂貴的數(shù)據(jù)庫(kù)系統(tǒng)(您也不需要這些東西)。您需要一些免費(fèi)的、支持Unix的東西。
那么我建議您使用PHP和MySQL。這兩樣?xùn)|西加在一起,對(duì)于開(kāi)發(fā)數(shù)據(jù)驅(qū)動(dòng)的網(wǎng)站這項(xiàng)工作而言,真是最佳組合。其實(shí)用不著我多費(fèi)唇舌解釋。一項(xiàng)由Netcraft組織的非官方調(diào)查顯示,應(yīng)用PHP的主機(jī)數(shù)目由1998年6月的7,500臺(tái)躍升至1999年3月的410,000臺(tái)。不錯(cuò)吧?這兩種軟件的組合還在Webcon98大會(huì)上贏得了年度數(shù)據(jù)庫(kù)產(chǎn)品大獎(jiǎng),還得了一座漂亮的獎(jiǎng)杯。
MySQL是一個(gè)小巧靈瓏的數(shù)據(jù)庫(kù)服務(wù)器軟件,對(duì)于小型(當(dāng)然也不一定很小)應(yīng)用系統(tǒng)是非常理想的。除了支持標(biāo)準(zhǔn)的ANSI SQL語(yǔ)句,它還支持多種平臺(tái),而在Unix系統(tǒng)上該軟件支持多線程運(yùn)行方式,從而能獲得相當(dāng)好的性能。對(duì)于不使用Unix的用戶,它可以在Windows NT系統(tǒng)上以系統(tǒng)服務(wù)方式運(yùn)行,或者在Windows 95/98系統(tǒng)上以普通進(jìn)程方式運(yùn)行。
PHP是一種服務(wù)器端解釋的腳本語(yǔ)言。如果你接觸過(guò)ASP的話,那么您對(duì)于在HTML頁(yè)面中嵌入代碼應(yīng)該是比較熟悉了。PHP代碼在服務(wù)器一端被解釋轉(zhuǎn)變成普通的HTML頁(yè)面內(nèi)容,送給瀏覽器一端。這種模式使得我們可以用它來(lái)完成相當(dāng)復(fù)雜的功能。
除了免費(fèi)這一點(diǎn)(當(dāng)然,MySQL也有一些使用許可方面的限制),PHP-MySQL的組合還可以跨平臺(tái)運(yùn)行,這意味著您可以在Windows上開(kāi)發(fā),然后在Unix平臺(tái)上運(yùn)行。另外,PHP也能作為標(biāo)準(zhǔn)的CGI進(jìn)程來(lái)運(yùn)行,此時(shí)它是一個(gè)獨(dú)立的腳本解釋器,或者是Apache的一個(gè)嵌入模塊。
如果您有興趣使用其他數(shù)據(jù)庫(kù)服務(wù)器的話,PHP也支持Informix、Oracle、Sybase、Solid和PostgreSQL ,以及通用的ODBC。
PHP支持Internet開(kāi)發(fā)的一些前沿技術(shù)。這些技術(shù)包括身份認(rèn)證、XML、動(dòng)態(tài)圖象生成、WDDX、共享內(nèi)存,以及動(dòng)態(tài)PDF文檔等等,不一而足。如果您還不滿意的話,PHP是很容易擴(kuò)展的,所以只要您有編程能力,您盡可以自己大展身手一番。
最后要說(shuō)的是,兩種軟件都是大量程序員協(xié)同開(kāi)發(fā)的,因此文檔及郵件列表等支持方式很多。程序錯(cuò)誤的修正很快,而如果您要求加入新功能的話,總會(huì)有人考慮您的要求,并且在可行性足夠高的前提下加以實(shí)現(xiàn)。
說(shuō)得夠多了!我們來(lái)看看這篇教程里都有些什么內(nèi)容吧。
第一課講的是在Unix和Windows環(huán)境下安裝這兩個(gè)軟件。如果您不太關(guān)心這個(gè)問(wèn)題(也許您是在ISP的服務(wù)器上開(kāi)發(fā)),您可以直接跳到第一個(gè)示例程序,從那里開(kāi)始您的奇妙之旅。
在第二課里,我們要學(xué)習(xí)一些更加復(fù)雜的腳本功能,比如循環(huán)、處理用戶輸入,以及與數(shù)據(jù)庫(kù)交換數(shù)據(jù)等等。
第三課要講的是確認(rèn)功能,以及如何使您的腳本程序清晰簡(jiǎn)練。
我們開(kāi)始吧。>>
二、安裝MySQL
快點(diǎn)行動(dòng),拿到這些軟件包,仔細(xì)研究一下吧。這可不是件容易的事兒。你從獲取軟件包、編譯軟件包到安裝軟件包的過(guò)程中都有不少的選擇項(xiàng)。我們先從MySQL開(kāi)始,因?yàn)橛辛怂拍苓\(yùn)行PHP。
MySQL中央網(wǎng)站是http://www.mysql.com/。為了方便人們下載使用(這軟件還是比較大的),全球有許許多多的鏡像網(wǎng)站。為更有效地利用因特網(wǎng),請(qǐng)找一個(gè)就近的網(wǎng)站下載。
在這時(shí)候你也會(huì)有多種選擇。如果你是發(fā)燒友的話,可以下載源代碼;否則,網(wǎng)上也有各種平臺(tái)上運(yùn)行的預(yù)先編譯過(guò)的二進(jìn)制文件可以直接下載。
另外,MySQL還為Windows用戶準(zhǔn)備了一個(gè)共享軟件版本,它的版本號(hào)稍低一些。如果你想要最新的版本,得花錢(qián)買一個(gè)軟件許可。MySQL還提供了ODBC驅(qū)動(dòng)程序,使前端應(yīng)用程序可以訪問(wèn)MySQL數(shù)據(jù)庫(kù)。有關(guān)其他一些詳細(xì)信息在它的網(wǎng)站上都有得介紹,您可以去看看。
預(yù)先編譯過(guò)的Unix版本和Windows版本都很簡(jiǎn)單,只須解包即可使用,不需要做太多說(shuō)明了。因此,我們來(lái)介紹一下源代碼的編譯。Windows用戶請(qǐng)記住,您需要運(yùn)行mysqld程序,該程序是在mysql/bin目錄下。
下載壓縮過(guò)的軟件包文件,放在一個(gè)目錄下。使用gzip和tar來(lái)解壓縮和解包。比較快的做法是使用下面這樣的命令:
gunzip 其中,xxxx是你自己任取的一個(gè)版本標(biāo)記。上面的命令將創(chuàng)建一個(gè)名為mysql-xxxx目錄,所有的源程序文件都在這個(gè)目錄下。通過(guò)執(zhí)行cd mysql-xxxx命令轉(zhuǎn)入該目錄,仔細(xì)閱讀其中的多個(gè)README文件INSTALL文件。在遇到某些問(wèn)題時(shí),這些文件可能會(huì)幫上大忙呢。
MySQL帶有一些便利的配置腳本程序。只須簡(jiǎn)單地鍵入./configure,您就可以讓這些程序?yàn)槟瓿珊芏喙ぷ?。如果您需要明確指定要做的事情,可以使用./configure -help命令,它會(huì)給您列出你可以使用的選項(xiàng)。例如,如果您正在一臺(tái)內(nèi)存較少的機(jī)器上進(jìn)行編譯,那么可以使用--with-low-memory選項(xiàng)。我喜歡把MySQL安裝在一個(gè)總目錄下,而不是安裝在機(jī)器上多個(gè)目錄下,所以我會(huì)指定安裝目錄,并指定-prefix選項(xiàng)。
您還可以指定許多其他選項(xiàng),象編譯過(guò)程中要略掉哪些部分、保留哪些部分等。我們不妨假定要全部安裝在服務(wù)器的/usr/local/mysql目錄下。這意味著我們將鍵入./configure -prefix=/usr/local/mysql命令。
配置腳本程序運(yùn)行時(shí)會(huì)檢查您的系統(tǒng),然后生成一些文件來(lái)保證編譯的順利進(jìn)行。如果該腳本程序失敗,它也會(huì)顯示一些有用的錯(cuò)誤信息告訴您失敗的原因。大家經(jīng)常會(huì)遇到腳本程序在尋找多線程庫(kù)文件時(shí)失敗。此時(shí)您應(yīng)當(dāng)檢查一下系統(tǒng)中是否已經(jīng)安裝了MIT-pthreads,如果沒(méi)有,那么請(qǐng)您安裝該軟件。Linux用戶則必須安裝LinuxThreads。這些庫(kù)文件對(duì)于MySQL的多線程運(yùn)行模式(也就是運(yùn)行它自己的多個(gè)版本〕是非常關(guān)鍵的。
如果一切都順利進(jìn)行的話,只須簡(jiǎn)單鍵入make命令,然后就可以去泡杯咖啡了。MySQL是相當(dāng)復(fù)雜的程序,編譯起來(lái)得用一段時(shí)間。如果發(fā)現(xiàn)錯(cuò)誤,可以檢查文檔,看看只否您漏掉了某些與您的操作系統(tǒng)有關(guān)的準(zhǔn)備工作。
接下來(lái),鍵入make install命令,所有必需的文件都會(huì)安裝到相應(yīng)的目錄。您差不多就可以開(kāi)始使用了!如果您是MySQL新手,以前從未安裝過(guò)MySQL,那您得創(chuàng)建默認(rèn)的許可權(quán)限才能安裝,因此請(qǐng)鍵入...scripts/mysql_install_db來(lái)進(jìn)行相應(yīng)的設(shè)置。
就這樣。我們的準(zhǔn)備工作完成了。再下面所要做的就是在機(jī)器啟動(dòng)時(shí)自動(dòng)啟動(dòng)數(shù)據(jù)庫(kù),并在關(guān)機(jī)時(shí)自動(dòng)關(guān)閉數(shù)據(jù)庫(kù)。是的,這項(xiàng)工作也有一個(gè)專門(mén)的腳本程序。mysql.server start命令可以啟動(dòng)數(shù)據(jù)庫(kù),而mysql.server stop可以關(guān)閉數(shù)據(jù)庫(kù)。實(shí)在是再簡(jiǎn)單不過(guò)了。如果您想手動(dòng)啟動(dòng)數(shù)據(jù)庫(kù)(這樣就不用重啟機(jī)器了),你以進(jìn)到安裝MySQL的最上層目錄(/usr/local/mysql)然后鍵入bin/safe_mysqld &命令。
我們已經(jīng)完成了一半了。接下來(lái)是PHP部分。>>
三、安裝PHP
好,看到這里時(shí),希望您已經(jīng)把MySQL安裝好并運(yùn)行起來(lái)了。那實(shí)在是太有意思了!下面是PHP...這個(gè)過(guò)程要容易一些,不過(guò)那些大量的選項(xiàng)還是使人眼花繚亂。當(dāng)然,您大可不必驚慌。您隨時(shí)可以重頭再來(lái),重新編譯PHP,根據(jù)需要來(lái)加入或去掉某個(gè)選項(xiàng)。
PHP的老家在http://www.php.net/。這個(gè)網(wǎng)站信息量極大,從開(kāi)發(fā)項(xiàng)目?jī)?nèi)容到軟件錯(cuò)誤報(bào)告都有。和MySQL一樣,您可以選一個(gè)離您最近的鏡像網(wǎng)站下載。很顯然,您得到網(wǎng)站的Downloads部分去下載PHP。
這里您的選擇不是很多。有一些預(yù)選編譯好的二進(jìn)制文件,但那都是實(shí)驗(yàn)性的。如果您不是在Windows平臺(tái)上,那就下載源代碼,自己編譯一下吧。
但是我們還是先談?wù)刉indows。在使用PHP時(shí),一般的作法是在Windows系統(tǒng)上開(kāi)發(fā),然后在Unix服務(wù)器上運(yùn)行。您最終可能也會(huì)選擇這種方式,這就需要您對(duì)兩種平臺(tái)下的安裝都很熟悉才行。
下載Windows二進(jìn)制文件后,您可以用您喜歡的任何一種ZIP解壓縮程序,把軟件包中的文件解壓到C盤(pán)的php3目錄下。軟件包中的README文件對(duì)安裝過(guò)程中的細(xì)節(jié)作了部分說(shuō)明,但是我們?cè)谶@里再對(duì)這個(gè)文件中的關(guān)鍵內(nèi)容做個(gè)讀者文摘:如果您不想把PHP安裝在C:\php3目錄,而是別的目錄,那么您得編輯解壓縮出來(lái)的文件中那個(gè).inf文件。
在php3目錄中,您會(huì)發(fā)現(xiàn)很多.dll文件。把所有文件名不是以php_開(kāi)頭的那些.dll文件都移到\windows\system目錄下。然后,把php.ini-dist文件改一下名,改成php3.ini,并把它移到\windows目錄下。如果您打開(kāi)這個(gè)文件,會(huì)發(fā)現(xiàn)里面有很多有趣的東西可以改。現(xiàn)在,把含有:
extension=php3_mysql.dll
內(nèi)容的那一行的注釋去掉。
如果您使用的是Win32平臺(tái)上的Apache服務(wù)器,那么請(qǐng)?jiān)O(shè)置Apache,使其能夠識(shí)別并解釋PHP文件。您需要在http.conf文件或是srm.conf文件(具體是哪一個(gè)文件取決于您使用的Apache軟件的版本)中加入下一行:
Action application/x-httpd-php3 "php3/php.exe"
AddType application/x-httpd-php3 .php3
或者,如果您使用的是IIS,那么請(qǐng)用鼠標(biāo)右鍵單擊php_iis_reg.inf文件,并選擇“安裝”。您得重新啟動(dòng)系統(tǒng),才能使剛才所做的改動(dòng)生效。
OK,說(shuō)完了Windows,再來(lái)說(shuō)說(shuō)Unix。當(dāng)然,我們要從源代碼開(kāi)始編譯。與MySQL相似,把源文件下載、解包。PHP也同樣包含一個(gè)配置腳本程序,可是您不能完全使用默認(rèn)設(shè)置。運(yùn)行./configure -help | more命令,可以逐頁(yè)地觀看有哪些新的、有趣的選項(xiàng)。您必須選擇是把PHP編譯成外部CGI程序還是Apache內(nèi)嵌模塊。如果您正在使用Apache Web服務(wù)器,并且您可以對(duì)它進(jìn)行重新編譯的話,請(qǐng)選擇內(nèi)嵌模塊方式,這種方式運(yùn)行更快,使用也更簡(jiǎn)便。否則,您可以選CGI方式。另外,您還得指定將對(duì)MySQL的支持部分編譯進(jìn)去。
現(xiàn)在我們假定要以內(nèi)嵌模塊方式編譯,并帶有MySQL支持部分。如果隨后您需要增加其他選項(xiàng)或庫(kù)文件的話,可以在以后再加進(jìn)去。鍵入下面的命令:
./configure -with-apache=/path/to/apache/dir -with-mysql=/usr/local/mysql
如果您打算以外部CGI程序方式來(lái)編譯的話,請(qǐng)去掉-with-apache選項(xiàng)。配置程序運(yùn)行起來(lái)后,會(huì)創(chuàng)建相應(yīng)的系統(tǒng)文件。接下來(lái)簡(jiǎn)單地執(zhí)行make命令就行了。
又可以喝一杯咖啡了。如果您在此時(shí)感到坐立不安的話,不必?fù)?dān)心。每個(gè)人在初次安裝PHP的時(shí)候都有一點(diǎn)近不及待的感覺(jué)。再多喝點(diǎn)咖啡就是了。
如果您選擇CGI程序方式來(lái)編譯,那么現(xiàn)在可以就可以使用了。只須把產(chǎn)生的可執(zhí)行文件復(fù)制到CGI程序目錄下就行了。如果您使用Apache內(nèi)嵌模塊方式來(lái)編譯,要再執(zhí)行一下make install命令,把有關(guān)文件復(fù)制到Apache目錄下。在該目錄下,您可以按照Apache的文檔說(shuō)明,向其中加入PHP模塊,并重新編譯Apache。
現(xiàn)在您得告訴Web服務(wù)器如何通過(guò)PHP程序來(lái)處理頁(yè)面內(nèi)容。如果您使用的不是Apache,那您需要查閱Web服務(wù)器軟件的文檔,看看如何讓它處理后綴是.php3的文件。Apache 1.3.x版本的用戶僅須在httpd.conf或srm.conf文件中加入:AddType application/x-httpd-php3 .php3。如果您使用的是CGI程序方式,那您在AddType前面還得加入下面內(nèi)容:
Action application/x-httpd-php3 "php3/php.exe
就是這樣。您的運(yùn)氣還不那么差,現(xiàn)在MySQL也運(yùn)行起來(lái)了,PHP也工作正常了。別忘了,在遇到問(wèn)題時(shí)可以去查閱常見(jiàn)問(wèn)題解答和軟件文檔。還可以試試電子郵件討論組。
既然我們已經(jīng)進(jìn)行了這么多,下面我們可以實(shí)際操練了。>>
四、第一個(gè)腳本
如果我告訴您真正難過(guò)的一關(guān)已經(jīng)過(guò)了,您一定會(huì)很高興。軟件的安裝過(guò)程總是無(wú)法預(yù)料,因?yàn)橄到y(tǒng)跟系統(tǒng)之間可以說(shuō)是千差萬(wàn)別。不過(guò)您運(yùn)氣不錯(cuò),數(shù)據(jù)庫(kù)運(yùn)行起來(lái),PHP也編譯安裝完畢,Web服務(wù)器也可以正確處理擴(kuò)展名為.php3的文件了。
我們下面就開(kāi)始正式上路,要寫(xiě)第一個(gè)腳本程序了。創(chuàng)建一個(gè)文本文件,在其中加入下面的內(nèi)容:
現(xiàn)在,訪問(wèn)相應(yīng)的URL,例如,http://myserver/test.php3。您應(yīng)該可以看到頁(yè)面中包含“Hello World”的文字。如果您看到的是錯(cuò)誤信息,查一下PHP文檔,看看軟件設(shè)置是否正確無(wú)誤。
就是這樣了!這是您的第一個(gè)PHP程序。如果您查看一下這個(gè)頁(yè)面的HTML源代碼,您會(huì)發(fā)現(xiàn)里面只有Hello World 這樣的文字。
那是因?yàn)镻HP引擎過(guò)濾了文件內(nèi)容,對(duì)其中的代碼作了處理,轉(zhuǎn)換成了標(biāo)準(zhǔn)的HTML。
在上面的程序中您最先注意到的可能是定界符,也就是以表示代碼結(jié)束。PHP的強(qiáng)大之處在于,這些代碼可以以多種不同方式放在任意位置 - 我是說(shuō)任意位置。后面我們會(huì)看到一些很有趣的例子,現(xiàn)在我們還是從最簡(jiǎn)單的開(kāi)始。如果您愿意,也可以設(shè)置PHP,讓它使用短標(biāo)記,,但這與XML會(huì)發(fā)生沖突,所以要小心使用。如果您是從ASP轉(zhuǎn)向PHP,您甚至可以讓PHP使用作為定界符。
您還會(huì)注意到每行后面的分號(hào)。這些分號(hào)稱為分隔符,用于分隔不同的指令。您可以把所有的PHP代碼寫(xiě)在一行里,用分隔符把命令分開(kāi)。但是那樣看起來(lái)很亂,所以我們?cè)诿總€(gè)分號(hào)后面都另起一行。記住,每行最后都要以分號(hào)結(jié)束。
最后,您會(huì)注意到myvar這個(gè)字以$符號(hào)開(kāi)頭。這個(gè)符號(hào)告訴PHP,這是一個(gè)變量。我們把“Hello World”賦給變量$myvar。一個(gè)變量可以是數(shù)字,也可以是數(shù)組。不管怎樣,所有的變量都是以$符開(kāi)頭。
PHP真正強(qiáng)大之處來(lái)源于它的函數(shù)。函數(shù),基本上是處理指令序列。如果您把所有的選件都編譯進(jìn)PHP,總共會(huì)有超過(guò)700個(gè)函數(shù)。這些函數(shù)可以讓您做很多事情。
現(xiàn)在我們?cè)偌舆M(jìn)一些MySQL的內(nèi)容進(jìn)去。>>
五、裝載數(shù)據(jù)庫(kù)
現(xiàn)在,我們要加入MySQL的內(nèi)容了。要想知道PHP中包含哪些選項(xiàng),或服務(wù)器方面的一些情況,一種簡(jiǎn)便的方法是使用函數(shù)phpinfo()。創(chuàng)建一個(gè)象下面這樣的程序:
保存這個(gè)程序,在瀏覽器中訪問(wèn)這個(gè)文件。您會(huì)看到網(wǎng)頁(yè)中包含了一些有趣的、有用的信息,象這樣。這些信息是有關(guān)服務(wù)器、Web服務(wù)器內(nèi)部環(huán)境變量、PHP中包含的選項(xiàng),等等。在第一段Extensions中,找到以MySQL開(kāi)頭的一行。如果沒(méi)有找到,那說(shuō)明MySQL支持選項(xiàng)并沒(méi)有編譯進(jìn)PHP。您可以再檢查一下安裝步驟,查閱一下PHP文檔,看您是否漏掉了什么。
如果找到了MySQL那一行,那您可以繼續(xù)了。
從MySQL數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)之前,我們得先往數(shù)據(jù)庫(kù)里放一些數(shù)據(jù)。在現(xiàn)在這一階段,還沒(méi)有一個(gè)簡(jiǎn)便的方法來(lái)做這件事情。大多數(shù)的PHP程序都帶有一個(gè)數(shù)據(jù)文件,該文件包含一些數(shù)據(jù)來(lái)創(chuàng)建并激活MySQL數(shù)據(jù)庫(kù)。這個(gè)過(guò)程不在本教程范圍之內(nèi),所以讓我來(lái)替您做這件事情吧。
MySQL使用它自己的用戶權(quán)限表。在安裝時(shí),會(huì)創(chuàng)建一個(gè)默認(rèn)的用戶(root),該用戶是沒(méi)有口令的。數(shù)據(jù)庫(kù)管理員可以根據(jù)需要來(lái)增加用戶并賦予用戶各種不同的權(quán)限,但這項(xiàng)工作完全可以另寫(xiě)一本書(shū)了,所以我們只使用root用戶。如果您自己管理服務(wù)器和數(shù)據(jù)庫(kù),為root用戶分配一個(gè)口令是很重要的。
總之,我們還是接著說(shuō)數(shù)據(jù)庫(kù)吧。對(duì)Win32用戶來(lái)說(shuō),很對(duì)不起,不過(guò)您要在DOS下做些工作。您不得不使用DOS窗口,或者在“執(zhí)行”窗口中鍵入所有命令。別忘了,輸入命令時(shí)要帶上MySQL/bin的目錄名。Unix用戶可以在MySQL的bin目錄下輸入命令,但命令必須以./開(kāi)頭,才能讓程序運(yùn)行起來(lái)。
我們要做的第一件事情是實(shí)際創(chuàng)建出數(shù)據(jù)庫(kù)。在命令行下,鍵入下列命令:
mysqladmin -u root create mydb
這樣就創(chuàng)建了一個(gè)名為“mydb”的數(shù)據(jù)庫(kù)。-u選項(xiàng)告訴MySQL我們使用的是root用戶。
下一步,我們要加入一些數(shù)據(jù),這里我們用的示例數(shù)據(jù)是大家都喜歡用的員工數(shù)據(jù)庫(kù)。我們將會(huì)用到我前面提到過(guò)的數(shù)據(jù)文件。如果您想在這方面多了解一些,可以查閱MySQL所帶的手冊(cè)或訪問(wèn) http://www.turbolift.com/mysql/網(wǎng)站。
把下面的文字復(fù)制到一個(gè)文件中,把該文件存在MySQL的bin目錄下(我假定文件名是mydb.dump)。
CREATE TABLE employees ( id tinyint(4) DEFAULT '0' NOT NULL AUTO_INCREMENT, first varchar(20), last varchar(20), address varchar(255), position varchar(50), PRIMARY KEY (id), UNIQUE id (id));INSERT INTO employees VALUES (1,'Bob','Smith','128 Here St, Cityname','Marketing Manager');INSERT INTO employees VALUES (2,'John','Roberts','45 There St , Townville','Telephonist');INSERT INTO employees VALUES (3,'Brad','Johnson','1/34 Nowhere Blvd, Snowston','Doorman');
如果文字是折行的,請(qǐng)確保每一個(gè)INSERT語(yǔ)句都是另起一行的。現(xiàn)在,我們要把數(shù)據(jù)加入到mydb數(shù)據(jù)庫(kù)中了。在命令行下,鍵入下面的命令:
mysql -u root mydb
此時(shí)您應(yīng)該不會(huì)遇到什么錯(cuò)誤。如果真的出錯(cuò)了,請(qǐng)仔細(xì)檢查一下是否因上面的文字折行而引起錯(cuò)誤。>>
六、測(cè)試
OK,現(xiàn)在我們已經(jīng)把數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫(kù)中了?,F(xiàn)在我們來(lái)處理這些數(shù)據(jù)。把下面的文字存入一個(gè)文件中,把該文件存在Web服務(wù)器的文檔目錄下,后綴名為.php3。
\n", mysql_result($result,0,"first"));printf("Last Name: %s
\n", mysql_result($result,0,"last"));printf("Address: %s
\n", mysql_result($result,0,"address"));printf("Position: %s
\n", mysql_result($result,0,"position"));?>
我來(lái)解釋一下上面的代碼。mysql_connect()函數(shù)負(fù)責(zé)以指定的用戶名(本例中用戶名是root)連接到指定機(jī)器(在本例中機(jī)器是本機(jī)localhost)上的MySQL數(shù)據(jù)庫(kù)。如果您想指定用戶口令,您也可以把它送給這個(gè)函數(shù)。連接的結(jié)果保存在變量$db中。
隨后,mysql_select_db()函數(shù)告訴PHP,我們要讀取的數(shù)據(jù)庫(kù)是mydb。我們可以在程序中同時(shí)連接到多臺(tái)機(jī)器上的多個(gè)數(shù)據(jù)庫(kù),但目前我們還是限于連接一個(gè)數(shù)據(jù)庫(kù)。
接下來(lái),mysql_query()函數(shù)完成最復(fù)雜的部分。利用剛才得到的連接結(jié)果標(biāo)識(shí),該函數(shù)把一行SQL語(yǔ)句送給MySQL服務(wù)器去處理。返回的結(jié)果保存在變量$result中。
最后,mysql_result()函數(shù)顯示SQL查詢命令所得到的各個(gè)字段的值。利用變量$result,我們就可以找到第一條記錄,記錄號(hào)是0,并將其中各字段的值顯示出來(lái)。
如果您以前沒(méi)用過(guò)Perl或C語(yǔ)言,那么printf函數(shù)的語(yǔ)法格式會(huì)顯得很奇怪。在上面的每一行程序中,%s代表表達(dá)式第二部分中的那個(gè)變量(例如,mysql_result($result,0,"position"))應(yīng)該以字符串的形式顯示出來(lái)。想更深入了解printf,請(qǐng)參閱PHP文檔。
這一課我們就講到這里了。我們已經(jīng)成功地編譯、安裝和設(shè)置了MySQL和PHP,并且運(yùn)行了一個(gè)簡(jiǎn)單的程序來(lái)讀取數(shù)據(jù)庫(kù)中的信息。在 第二課里,我們會(huì)做一些更復(fù)雜的工作,來(lái)顯示多行記錄的數(shù)據(jù),甚至與數(shù)據(jù)庫(kù)互相交換數(shù)據(jù)。
繼續(xù)努力吧!
一、 while循環(huán)
在這一課里,我們將會(huì)繼續(xù)深入下去,使用PHP和MySQL來(lái)寫(xiě)出一些簡(jiǎn)單而有用的頁(yè)面。我們從昨天創(chuàng)建的數(shù)據(jù)庫(kù)開(kāi)始,顯示庫(kù)中的數(shù)據(jù),但是會(huì)再稍微加以潤(rùn)色。
首先,我們用下面的代碼來(lái)查詢數(shù)據(jù)庫(kù)內(nèi)容。
\n";echo "
您可能已經(jīng)注意到,我們?cè)谶@個(gè)程序里加進(jìn)了一些新東西。最明顯的是while()循環(huán)。該循環(huán)是說(shuō),只要數(shù)據(jù)庫(kù)里還有記錄可讀(使用mysql_fetch_row()函數(shù)),那就把該記錄賦給變量$myrow,然后執(zhí)行大括號(hào)({})內(nèi)的指令。仔細(xì)看一下這里,這部分是比較重要的。
我們應(yīng)該注意一下mysql_fetch_row()函數(shù)。這里有一點(diǎn)小問(wèn)題,它返回的是一個(gè)數(shù)組,必須以數(shù)組下標(biāo)來(lái)訪問(wèn)其中的某個(gè)字段。第一個(gè)字段下標(biāo)為0,第二個(gè)是1,依此類推。在執(zhí)行某些復(fù)雜查詢時(shí),這么做簡(jiǎn)直實(shí)在是太煩瑣了。
現(xiàn)在我們更仔細(xì)地研究一下循環(huán)過(guò)程。程序前幾行我們?cè)诘谝徽n的例子中已經(jīng)看到過(guò)了。然后,在while()循環(huán)中,我們從查詢結(jié)果中讀取一條記錄并把該記錄賦給數(shù)組$myrow。接著,我們用printf函數(shù)把數(shù)據(jù)中的內(nèi)容顯示在屏幕上。隨后,循環(huán)反復(fù)執(zhí)行,讀取下一條記錄賦給$myrow。這樣繼續(xù)下去,直到所有記錄都已被讀取完為止。
使用while()循環(huán)的一個(gè)好處是,如果數(shù)據(jù)庫(kù)查詢沒(méi)有返回任何記錄,那您也不會(huì)收到錯(cuò)誤信息。在剛執(zhí)行循環(huán)語(yǔ)句時(shí),循環(huán)條件就不滿足,不會(huì)有任何數(shù)據(jù)賦給$myrow,程序就直接往下運(yùn)行了。
但是如果查詢未返回任何數(shù)據(jù),我們?cè)趺醋層脩糁肋@一點(diǎn)呢?我們也許該提供點(diǎn)兒相關(guān)的消息給用戶吧。這是可以做到的,下面我們就看看怎么做。>>
二、 if-else
請(qǐng)看下面的程序。
\n"; echo "
這段程序中包含有不少新內(nèi)容,不過(guò)這些內(nèi)容都相當(dāng)簡(jiǎn)單。首先是mysql_fetch_array()函數(shù)。該函數(shù)與mysql_fetch_row()十分相近,只有一點(diǎn)不同:使用這個(gè)函數(shù)時(shí),我們可以通過(guò)字段名而不是數(shù)組下標(biāo)來(lái)訪問(wèn)它返回的字段,比如$myrow["first"]。這樣我們就可以省不少力氣了。另外,程序中還加進(jìn)了do/while循環(huán)和if-else條件判定語(yǔ)句。
if-else條件判定語(yǔ)句的含意是,如果我們成功地把一條記錄賦給了$myrow變量,那就繼續(xù);否則,就跳到else部分,執(zhí)行那里的指令。
do/while循環(huán)是我們?cè)谏享?yè)中用戶的while()循環(huán)的一個(gè)變體。我們要用到do/while的原因是:在最初的if語(yǔ)句中,我們已經(jīng)把查詢返回的第一條記錄賦給變量$myrow了。如果這時(shí)我們執(zhí)行一般的while循環(huán)(比如,while ($myrow = mysql_fetch_row($result)),那我們就會(huì)把第二條記錄賦給$myrow,而第一條記錄就被沖掉了。但是do/while循環(huán)可以讓我們執(zhí)行一次循環(huán)體內(nèi)容之后再來(lái)判定循環(huán)條件。因此,我們就不會(huì)不小心漏掉第一條記錄了。
最后,如果查詢結(jié)果沒(méi)有任何記錄的話,程序就會(huì)執(zhí)行包含在else{}部分的那些語(yǔ)句。如果您想看到這部分程序的執(zhí)行情況,可以把SQL語(yǔ)句改為SELECT * FROM employees WHERE id=6,或改成其他形式,使得查詢結(jié)果中沒(méi)有任何記錄。
下面我們來(lái)擴(kuò)充一下循環(huán)if-else 代碼,使得頁(yè)面內(nèi)容更加豐富。相信您會(huì)喜歡的。>>
三、 第一個(gè)程序腳本
我們剛剛學(xué)到了循環(huán)語(yǔ)句,下面我們將在一個(gè)更加實(shí)際一點(diǎn)的例子中看看如何運(yùn)用它。但是在這之前,您應(yīng)該知道如何處理Web表格、查詢參數(shù)串,以及表單的GET方法和POST方法。不久之前我們剛剛有文章介紹這部分內(nèi)容,您如果對(duì)這一部分還不太熟悉的話可以看看那篇文章。
現(xiàn)在,我們要處理查詢參數(shù)串,正如您所知道的,有三種方法可以把參數(shù)內(nèi)容寫(xiě)入到查詢參數(shù)串中。第一種是在表格中使用GET方法;第二種是在瀏覽器的地址欄中輸入網(wǎng)址時(shí)直接加上查詢參數(shù);第三種是把查詢參數(shù)串嵌入到網(wǎng)頁(yè)的超鏈接中,使得超鏈接的內(nèi)容象下面這樣:。我們現(xiàn)在要用到最后這一種方法。
一開(kāi)始,我們?cè)賮?lái)查詢我們的數(shù)據(jù)庫(kù),列出員工姓名??纯聪旅娴某绦颍渲写蟛糠謨?nèi)容我們都已經(jīng)很熟悉了。
%s %s
\n", $PATH_INFO, $myrow["id"], $myrow["first"], $myrow["last"]); } while ($myrow = mysql_fetch_array($result));} else { echo "對(duì)不起,沒(méi)有找到記錄!"; }?>
這里沒(méi)什么特別的,只是printf函數(shù)有些不同。那我們就來(lái)仔細(xì)研究一下。
首先要注意的是,所有的引號(hào)前面都有一個(gè)反斜杠。這個(gè)反斜杠告訴PHP直接顯示后面的字符,而不能把后面的字符當(dāng)作程序代碼來(lái)處理。另外要注意變量$PATH_INFO的用法。該變量在所用程序中都可以訪問(wèn),是用來(lái)保存程序自身的名稱與目錄位置的。我們之所以用到它是因?yàn)橐陧?yè)面中再調(diào)用這個(gè)程序本身。使用$PATH_INFO,我們可以做到,即使程序被挪到其他目錄,甚至是其他機(jī)器上時(shí),我們也能保證正確地調(diào)用到這個(gè)程序。
正如我剛才提到的,程序所生成的網(wǎng)頁(yè),其中包含的超鏈接會(huì)再次調(diào)用程序本身。不過(guò),再次調(diào)用時(shí),會(huì)加入一些查詢參數(shù)。
PHP見(jiàn)到查詢參數(shù)串中包含有“名字=值”這樣的成對(duì)格式時(shí),會(huì)作一些特別的處理。它會(huì)自動(dòng)生成一個(gè)變量,變量名稱與取值都與查詢參數(shù)串中所給定的名稱和取值相同。這一功能使得我們可以在程序中判斷出是第一次執(zhí)行本程序還是第二次。我們所要做的只是問(wèn)問(wèn)PHP$id這個(gè)變量是否存在。
當(dāng)我知道這個(gè)問(wèn)題的答案后,我可以在第二次調(diào)用程序時(shí)顯示一些不同的結(jié)果出來(lái)。請(qǐng)看:
", $myrow["first"]); printf("姓: %s\n
", $myrow["last"]); printf("住址: %s\n
", $myrow["address"]); printf("職位: %s\n
", $myrow["position"]);} else { // show employee list // 顯示員工列表 $result = mysql_query("SELECT * FROM employees",$db); if ($myrow = mysql_fetch_array($result)) { // display list if there are records to display // 如果有記錄,則顯示列表 do { printf("%s %s
\n", $PATH_INFO, $myrow["id"], $myrow["first"], $myrow["last"]); } while ($myrow = mysql_fetch_array($result)); } else { // no records to display // 沒(méi)有記錄可顯示 echo "對(duì)不起,沒(méi)有找到記錄!"; }}?>
程序開(kāi)始變得復(fù)雜了,所以我在這里面加了注釋,來(lái)解釋一下到底發(fā)生了什么。您可以用//加入單行注釋,或者用/*和*/來(lái)括住大段的注釋。
到這里,我們已經(jīng)學(xué)會(huì)了第一個(gè)真正有用的PHP/MySQL腳本程序!現(xiàn)在,我們要看看怎樣把Web表格加進(jìn)來(lái),并且向數(shù)據(jù)庫(kù)發(fā)送數(shù)據(jù)。>>
四、 向服務(wù)器發(fā)送數(shù)據(jù)
現(xiàn)在我們從數(shù)據(jù)庫(kù)讀取數(shù)據(jù)已經(jīng)沒(méi)有太多困難了。但是怎么反過(guò)來(lái)向數(shù)據(jù)庫(kù)發(fā)送數(shù)據(jù)呢?其實(shí)這不是PHP的問(wèn)題。
首選,我們創(chuàng)建一個(gè)帶有簡(jiǎn)單表格的網(wǎng)頁(yè)。
同樣要注意$PATH_INFO的用法。就象我在第一課里講到的,您可以在HTML代碼中的任意位置使用PHP。您也會(huì)注意到,表格中的每一個(gè)元素都對(duì)應(yīng)著數(shù)據(jù)庫(kù)中的一個(gè)字段。這種對(duì)應(yīng)關(guān)系并不是必須的,這么做只是更直觀一些,便于您以后理解這些代碼。
還要注意的是,我在Submit按鈕中加入了name屬性。這樣我在程序中可以試探$submit變量是否存在。于是,當(dāng)網(wǎng)頁(yè)被再次調(diào)用時(shí),我就會(huì)知道調(diào)用頁(yè)面時(shí)是否已經(jīng)填寫(xiě)了表格。
我應(yīng)該指出,您不一定要把上面的網(wǎng)頁(yè)內(nèi)容寫(xiě)到PHP程序中,再返過(guò)來(lái)調(diào)用程序本身。您完全可以把顯示表格的網(wǎng)頁(yè)和處理表格的程序分開(kāi)放在兩個(gè)網(wǎng)頁(yè)、三個(gè)網(wǎng)頁(yè)甚至更多網(wǎng)頁(yè)中,悉聽(tīng)尊便。放在一個(gè)文件中只是可以使內(nèi)容更加緊湊而已。
那好,我們現(xiàn)在加入一些代碼,來(lái)檢查用戶在表格中輸入的內(nèi)容。我會(huì)把用$HTTP_POST_VARS把所有查詢參數(shù)變量都顯示出來(lái),這只不過(guò)是為了證明PHP確實(shí)把所有變量都傳給了程序。這種方法是一個(gè)很有用的調(diào)試手段。如果您要想看全部的變量,可以用$GLOBALS。
\n"; }} else{ // 顯示表格 ?>
程序現(xiàn)在運(yùn)行正常,那我們現(xiàn)在就可以取到表格輸入的內(nèi)容,并把它們發(fā)送給數(shù)據(jù)庫(kù)。
您現(xiàn)在已經(jīng)向數(shù)據(jù)庫(kù)中插入數(shù)據(jù)了。不過(guò)還有很多完善的工作要做。如果用戶沒(méi)有填寫(xiě)某一欄怎么辦?在需要填入數(shù)字的地方填了文字怎么辦?或者填錯(cuò)了怎么辦?
別擔(dān)心。我們一步一步來(lái)。>>
五、修改數(shù)據(jù)
在個(gè)教程中,我都把要執(zhí)行的SQL語(yǔ)句放到一個(gè)變量($sql)中,然后才用mysql_query()來(lái)執(zhí)行數(shù)據(jù)庫(kù)查詢。在調(diào)試時(shí)這是很有用的。如果程序出了什么問(wèn)題,您隨時(shí)可以把SQL語(yǔ)句的內(nèi)容顯示出來(lái),檢查其中的語(yǔ)法錯(cuò)誤。
我們已經(jīng)學(xué)習(xí)了如何把數(shù)據(jù)插入到數(shù)據(jù)庫(kù)中。現(xiàn)在我們來(lái)學(xué)習(xí)如何修改數(shù)據(jù)庫(kù)中已有的記錄。數(shù)據(jù)的編輯包括兩部分:數(shù)據(jù)顯示和通過(guò)表格輸入把數(shù)據(jù)返回給數(shù)據(jù)庫(kù),這兩部分我們前面都已經(jīng)講到了。然而,數(shù)據(jù)編輯還是有一點(diǎn)點(diǎn)不同,我們必須先在表格中顯示出相關(guān)的數(shù)據(jù)。
首先,我們回過(guò)頭再看看第一課的程序代碼,在網(wǎng)頁(yè)中顯示員工姓名。但是這次,我們要把數(shù)據(jù)顯示在表格中。程序看起來(lái)象下面這樣:
%s %s
\n", $PATH_INFO, $myrow["id"], $myrow["first"], $myrow["last"]); }}?>
我們剛才是把字段內(nèi)容寫(xiě)入到相應(yīng)表格元素中的value屬性里,這是相應(yīng)簡(jiǎn)單的。我們?cè)偻斑M(jìn)一步,使程序可以把用戶修改過(guò)的內(nèi)容寫(xiě)回?cái)?shù)據(jù)庫(kù)去。同樣,我們通過(guò)Submit按鈕來(lái)判斷是否處理表格輸入內(nèi)容。還要注意,我們用的SQL語(yǔ)句稍稍有些不同。
%s %s
\n", $PATH_INFO, $myrow["id"], $myrow["first"], $myrow["last"]); }}?>
就是這樣。在這個(gè)程序中已經(jīng)包含了我們學(xué)過(guò)所大多數(shù)特性。您也已經(jīng)看到,我們?cè)谝粋€(gè)if()條件判別語(yǔ)句中又加了一個(gè)if()語(yǔ)句,來(lái)檢查多重條件。
下面,我們要把所有東西全都加在一起,寫(xiě)出一個(gè)很好的程序來(lái)。>>
六、完整的程序
在本課結(jié)束前,我們要把所有東西加入到一個(gè)程序中,使它具有增加、編輯修改、刪除記錄的功能。這是前面所有內(nèi)容的一個(gè)延伸,也可以作為極好的復(fù)習(xí)方法??纯聪旅娴某绦颉?
";} elseif ($delete) {// 刪除一條記錄 $sql = "DELETE FROM employees WHERE id=$id"; $result = mysql_query($sql); echo "記錄刪除成功!
";} else { // 如果我們還沒(méi)有按submit按鈕,那么執(zhí)行下面這部分程序 if (!$id) { // 如果不是修改狀態(tài),則顯示員工列表 $result = mysql_query("SELECT * FROM employees",$db); while ($myrow = mysql_fetch_array($result)) { printf("%s %s \n", $PATH_INFO, $myrow["id"], $myrow["first"], $myrow["last"]); printf("(DELETE)", $PATH_INFO, $myrow["id"]); } } ?>
這段程序看起來(lái)很復(fù)雜,但實(shí)際上并不難。程序主要有三個(gè)部分。第一個(gè)if()語(yǔ)句檢查我們是否已經(jīng)按下了那個(gè)“輸入信息”的數(shù)據(jù)提交按鈕。如果是,程序再檢查$id是否存在。如果不存在,那我們就是在增加記錄狀態(tài),否則,我們是在修改記錄狀態(tài)。
接下來(lái)我們檢查變量$delete是否存在。如果存在,我們是要?jiǎng)h除記錄。注意,第一個(gè)if()語(yǔ)句檢查的是用POST方法發(fā)送來(lái)的變量,而這一次我們檢查的是GET方法中傳遞過(guò)來(lái)的變量。
最后,程序默認(rèn)的動(dòng)作是顯示員工列表和表格。同樣,我們要檢查變量$id是否存在。如果存在,我們就根據(jù)它的值檢索出相應(yīng)的記錄顯示出來(lái)。否則,我們會(huì)顯示一個(gè)空的表格。
現(xiàn)在,我們已經(jīng)把所學(xué)的東西全部都放在一個(gè)程序里頭了。我們用到了while()循環(huán),用到了if()語(yǔ)句,并且執(zhí)行了全部的SQL基本操作 - SELECT、INSERT、UPDATE以及DELETE。另外,我們也知道如何在不同的網(wǎng)頁(yè)之間通過(guò)URL和表格輸入來(lái)互相傳遞信息。
在第三課里,我們要學(xué)習(xí)如何為網(wǎng)頁(yè)增加智能化處理能力。
一、基本函數(shù)
歡迎來(lái)到本教程的第三課,也是最后一課。如果您已經(jīng)學(xué)過(guò)第一課和第二課,那么您已經(jīng)掌握了MySQL和PHP的安裝及編程的基本知識(shí)。下面我們要介紹PHP的一些其他函數(shù),這些函數(shù)可能會(huì)對(duì)您有用,使您的開(kāi)發(fā)過(guò)程更加簡(jiǎn)單。首先我們來(lái)看看頭文件。
大家應(yīng)該知道頭文件的一些基本概念吧?頭文件是一個(gè)外部文件,它的內(nèi)容被包含到主程序中。方法也十分簡(jiǎn)單:在程序文件中引用頭文件名,這個(gè)頭文件就會(huì)包含進(jìn)來(lái)了。在PHP中使用頭文件,會(huì)涉及兩個(gè)函數(shù):include()和require()。這兩個(gè)函數(shù)差別很小,卻很重要,所以我們要認(rèn)真研究一下。require()函數(shù)工作方式與XSSI相類似;不管在程序的哪個(gè)部分使用了這個(gè)函數(shù),只有程序一開(kāi)始運(yùn)行,頭文件的內(nèi)容就被作為程序本身的一部分來(lái)處理。因此,如果您在一個(gè)條件判定語(yǔ)句中使用了require()函數(shù),那么即使這個(gè)條件即使不為真,頭文件也會(huì)被包含進(jìn)來(lái)。
而include()函數(shù)只是在執(zhí)行到這一條語(yǔ)句時(shí)才會(huì)把頭文件內(nèi)容包含進(jìn)來(lái)。如果程序沒(méi)運(yùn)行到這里,那PHP是不會(huì)管它的。這就意味著,您在條件判定部分使用include時(shí),它會(huì)完全按照您希望的那樣工作。
還有,如果您用了require()函數(shù),而您指定的頭文件并不存在,那么程序?qū)?huì)停止運(yùn)行并產(chǎn)生錯(cuò)誤。如果您用了include(),程序會(huì)產(chǎn)生一個(gè)警告信息,但是會(huì)繼續(xù)運(yùn)行。您可以親自試一下,運(yùn)行下面的程序,然后把include()換成require(),再比較兩個(gè)程序運(yùn)行的結(jié)果。
我喜歡把頭文件的后綴名起成.inc,這樣就可以把頭文件和一般的程序區(qū)分開(kāi)來(lái)。如果您也這么做,那么請(qǐng)您修改Web服務(wù)器軟件的配置文件,使它能夠把.inc文件也當(dāng)作PHP文件來(lái)處理。否則,黑客們也許會(huì)猜到您的頭文件名,然后用瀏覽器把頭文件內(nèi)容以純文本格式顯示出來(lái)。此時(shí)如果您的頭文件中有些機(jī)密信息(如數(shù)據(jù)庫(kù)口令等)那就糟糕了。
那么,您用頭文件來(lái)做什么呢?很簡(jiǎn)單!把對(duì)所有程序都通用的那些內(nèi)容放到頭文件里。象HTML文件頭啦,腳注啦,數(shù)據(jù)庫(kù)連接代碼啦,還有您自己定義的一些函數(shù)什么的。把下面的文字拷貝到一個(gè)文件中,保存為header.inc。
然后再創(chuàng)建另外一個(gè)文件,名字是footer.txt,該文件可以包含一些程序結(jié)束時(shí)用到的一些文字和標(biāo)記。
現(xiàn)在,我們?cè)賮?lái)創(chuàng)建一個(gè)文件,這個(gè)文件里面是真正的PHP程序代碼。試一下下面的代碼,當(dāng)然,您要確認(rèn)MySQL數(shù)據(jù)庫(kù)服務(wù)器正在運(yùn)行。
\n";echo "
看到發(fā)生了什么事了嗎?頭文件里的內(nèi)容被合并到程序中,PHP把所有的代碼都執(zhí)行了一遍。注意在包含header.inc頭文件之前$title是如何定義的。在header.inc中的代碼可以訪問(wèn)到它的值。這樣,網(wǎng)頁(yè)的標(biāo)題就被改掉了?,F(xiàn)在,您可以在任何程序中使用header.inc頭文件了,您所要做的不過(guò)是在每個(gè)主程序中為$title變量取一個(gè)合適的值。
頭文件、HTML、條件判定語(yǔ)句,還有循環(huán)語(yǔ)句,這些東西加在一些,您就可以用最簡(jiǎn)練的代碼,寫(xiě)出功能各異的各種復(fù)雜程序來(lái)。在與函數(shù)同時(shí)使用時(shí),頭文件更能發(fā)揮它的效力,我們后面就會(huì)看到。
接下去,我們會(huì)介紹精彩的部分:數(shù)據(jù)校驗(yàn)。>>
二、 數(shù)據(jù)校驗(yàn)
想象一下這樣的情形:我們把數(shù)據(jù)庫(kù)都設(shè)計(jì)妥當(dāng)了,現(xiàn)在請(qǐng)用戶輸入信息來(lái)寫(xiě)到數(shù)據(jù)庫(kù)中去。假設(shè)您有一個(gè)字段是要求數(shù)字類型的信息,比如價(jià)格;而某個(gè)可愛(ài)的用戶,卻在這一欄里輸入了文字信息,使得您的應(yīng)用程序的執(zhí)行過(guò)程出現(xiàn)了故障。對(duì)您在SQL語(yǔ)句中提供的文字類型的數(shù)據(jù),MySQL數(shù)據(jù)庫(kù)拒不接受,并向您提出了“嚴(yán)正抗議”。
怎么辦呢?您要用數(shù)據(jù)校驗(yàn)來(lái)防止以上狀況發(fā)生。
簡(jiǎn)單地講,數(shù)據(jù)校驗(yàn)是指我們對(duì)數(shù)據(jù)(通常是用戶經(jīng)由HTML表格傳過(guò)來(lái)的)進(jìn)行檢查,看看它是否遵從一定的規(guī)則。規(guī)則可以是多種多樣的,比如某一數(shù)據(jù)元素不能為空,或者要求某一數(shù)據(jù)項(xiàng)的內(nèi)容必須滿足一定的要求(例如前面的例子中要求必須是數(shù)字而不是文字,或者要求電子郵件地址中一定要包含一個(gè)“@”字等等)。
數(shù)據(jù)校驗(yàn)既可以在服務(wù)器一端作,也可以在客戶端來(lái)作。PHP是用來(lái)作服務(wù)器一端的數(shù)據(jù)校驗(yàn)的,而JavaScript或其他客戶端腳本編程語(yǔ)言則能夠提供客戶端的數(shù)據(jù)校驗(yàn)功能。本文說(shuō)的是PHP,所以我們?cè)谶@里著重介紹服務(wù)器端的校驗(yàn)。如果您想找一些現(xiàn)成的、在客戶端運(yùn)行的數(shù)據(jù)較驗(yàn)程序,那您可以去網(wǎng)猴程序庫(kù)看看。
暫時(shí)把數(shù)據(jù)庫(kù)放在一邊不談,我們先來(lái)說(shuō)說(shuō)PHP的數(shù)據(jù)校驗(yàn)方法。如果您愿意(或者說(shuō),您想記錄我們要校驗(yàn)的那些數(shù)據(jù)的話),您可以在前面所建的員工數(shù)據(jù)庫(kù)的里加入其他字段,很簡(jiǎn)單,用MySQL的ALTER 語(yǔ)句就行了。
有好幾個(gè)PHP功能都可以用來(lái)作數(shù)據(jù)校驗(yàn)的工作,有些很簡(jiǎn)單,有些則復(fù)雜一些。其中strlen()是比較簡(jiǎn)單的一個(gè)函數(shù),它能夠告訴我們一個(gè)變量的長(zhǎng)度。
更復(fù)雜一點(diǎn)兒的是ereg(),這個(gè)函數(shù)可以處理完整的常規(guī)表達(dá)式來(lái)進(jìn)行復(fù)雜的校驗(yàn)。我不想就常規(guī)表達(dá)式講得太深,因?yàn)樵S多書(shū)都是專門(mén)寫(xiě)這個(gè)問(wèn)題的。不過(guò)我會(huì)在下一頁(yè)中給出一些簡(jiǎn)單的例子。
我們先從一個(gè)簡(jiǎn)單的例子開(kāi)始吧。下面這個(gè)程序要檢查一個(gè)變量是否存在。
這段程序中關(guān)鍵的地方是嵌套的條件判定語(yǔ)句。第一層檢查用戶是否按了發(fā)送數(shù)據(jù)的按鈕。如果是,程序接著檢查$first和$last兩個(gè)變量是否都存在。那個(gè) || 符號(hào)表示“或”,而 ! 符號(hào)表示“非”。那一句程序用一般語(yǔ)言描述就是“如果$first不存在或者$last不存在,那么就把 $error變量置成下面的值?!?
接下來(lái),我們?cè)龠M(jìn)一步,檢查一段文字的長(zhǎng)度。這對(duì)用戶口令的檢查是很有必要的,因?yàn)槟幌胱屇承卸璧挠脩糨斎胫挥幸?、兩個(gè)字的口令,可能會(huì)要求他們輸入六位長(zhǎng)的口令。
我們已經(jīng)講到strlen()這個(gè)函數(shù)了。它只是簡(jiǎn)單地返回一個(gè)數(shù)字,該數(shù)字等于被測(cè)變量中所包含的字符個(gè)數(shù)。這里,我修改一下上面的程序,檢查一下$first與$last的長(zhǎng)度。
您可以執(zhí)行一下這段程序,輸入六個(gè)字或少于六個(gè)字的內(nèi)容。這種校驗(yàn)很簡(jiǎn)單,但很有效。>>
三、 處理常規(guī)表達(dá)式
我們稍微講講用ereg()和eregi()兩個(gè)函數(shù)處理常規(guī)表達(dá)式。前面我已經(jīng)提過(guò),這些函數(shù)有的很簡(jiǎn)單,有的很復(fù)雜,看您的實(shí)際需要而定。
使用常規(guī)表達(dá)式,您可以對(duì)一個(gè)字符串進(jìn)行檢查,搜索其中的一些結(jié)構(gòu)模式,判定這些模式是否滿足您的規(guī)定。最普遍的用法包括檢查電子郵件地址是否有效(當(dāng)然,即使這種辦法判定有效,也不能保證郵件地址真的存在)。
我們?cè)谶@里不細(xì)究常規(guī)表達(dá)式的復(fù)雜細(xì)節(jié)了,僅僅給出幾個(gè)實(shí)例。您可以使用上一頁(yè)中用過(guò)的表格 - 把相應(yīng)的程序代碼復(fù)制過(guò)來(lái),添加到下面的代碼段中,就可以看到它是怎樣工作的。
首先,我們要確保表格中各欄只能輸入字母。下面的常規(guī)表達(dá)式在用戶輸入一個(gè)或多個(gè)小寫(xiě)字母時(shí)判定為真,而輸入數(shù)字是不允許的:
if (!ereg("[a-Z]", $first) || !ereg("[a-Z]", $last)) {
現(xiàn)在我們更進(jìn)一步,檢查字符串的長(zhǎng)度是否是四到六位字符長(zhǎng)。用[[:alpha:]]是檢查字符是不是字母的簡(jiǎn)單方式。大括號(hào)內(nèi)的數(shù)字檢查字符個(gè)數(shù)。還要說(shuō)明的是,^ 和 $ 分別代表字符串的開(kāi)始和結(jié)束。
if (!ereg("^[[:alpha:]]{4,6}$", $first) || !ereg("^[[:alpha:]]{4,6}$", $last)) {
最后,我們來(lái)構(gòu)造一個(gè)常規(guī)表達(dá)式,來(lái)檢驗(yàn)電子郵件地址的有效性。這種檢驗(yàn)方式的效果已經(jīng)引發(fā)了相當(dāng)多的討論。沒(méi)有什么東西是十全十美的,不過(guò)我下面給出的這段程序還是十分奏效的。
我這段寶貝程序是從PHP郵件討論組上得來(lái)的。那可是個(gè)好去處 - 常去看看吧。不錯(cuò),這段程序看起來(lái)是有點(diǎn)亂糟糟的。
if (!ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'.'@'.'[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.'.'[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$', $last)) {
別花太多時(shí)間來(lái)細(xì)究這段代碼了,還是先到下一頁(yè)內(nèi)容吧。>>
四、 簡(jiǎn)便方法
前面的常規(guī)表達(dá)式怎么樣?很有意思,是吧?要是在每個(gè)需要檢查電子郵件地址的程序里都寫(xiě)上這么一段程序,那才真叫有意思呢?!想想看吧,得寫(xiě)那么亂七八糟的一段程序,還得寫(xiě)上那么多遍!...不過(guò),當(dāng)然了,還有更簡(jiǎn)便的方法。
還記得前面我們學(xué)過(guò)的頭文件嗎?它能讓我們寫(xiě)一段程序,象是這個(gè)電子郵件地址的檢查程序,然后把這段程序包含進(jìn)多個(gè)程序里面去。這樣,我們要改寫(xiě)這段程序時(shí),只須改動(dòng)一處就行了,不用修改多個(gè)文件。
但是,要做到這一點(diǎn),我們必須用到函數(shù)。
我們已經(jīng)用過(guò)很多次函數(shù)了。每次我們查詢數(shù)據(jù)庫(kù)或檢查字符串長(zhǎng)度時(shí),我們都是用函數(shù)來(lái)做的。這些函數(shù)是PHP自帶的。如果您是位熱心的程序員,您可以用自己編寫(xiě)的函數(shù)來(lái)擴(kuò)充PHP本身的功能。但對(duì)本教程而言,這部分內(nèi)容是太過(guò)高深了一點(diǎn)。我們要?jiǎng)?chuàng)建的函數(shù)不是那一種,而是寫(xiě)在PHP腳本程序內(nèi)部的函數(shù)。
函數(shù)就是一段程序代碼,我們可以把一個(gè)或多個(gè)值傳給這段代碼,然后這段代碼會(huì)處理我們傳給它的數(shù)據(jù)并返回一個(gè)值。根據(jù)實(shí)際需要,函數(shù)可以很簡(jiǎn)單,也可以十分復(fù)雜。但是只要我們傳進(jìn)去一個(gè)數(shù),然后能得到一個(gè)數(shù),您管它里面有是復(fù)雜還是簡(jiǎn)單呢!這就是函數(shù)的可愛(ài)之處。
PHP里的函數(shù)與C語(yǔ)言里的函數(shù)表現(xiàn)差不多。當(dāng)我們定義函數(shù)時(shí),必須指明函數(shù)需要接收什么樣的數(shù)據(jù)。一開(kāi)始好象不太好理解為什么它要接收數(shù)據(jù)進(jìn)去,不過(guò)這樣可以防止發(fā)生一些怪異的問(wèn)題。函數(shù)之所以能做到這一點(diǎn),是因?yàn)楹瘮?shù)里面的變量都是私有變量,也就是說(shuō),它只在該函數(shù)內(nèi)部存在。例如,您在程序中有一個(gè)變量叫$myname,如果您創(chuàng)建了一個(gè)函數(shù),想讓這個(gè)函數(shù)也使用那個(gè)$myname變量(值也相同),那是不行的。您可以在函數(shù)內(nèi)部創(chuàng)建一個(gè)變量,名字也叫$myname,這兩個(gè)變量可以各平相處,而各自取不同的值。不過(guò)我可不建議您這么做!您如果真的這么做了,等半年后您再來(lái)修改這樣的程序時(shí),您可能就會(huì)被弄糊涂了。
那我們現(xiàn)在就來(lái)創(chuàng)建一個(gè)函數(shù),先來(lái)個(gè)簡(jiǎn)單的。我們要給它取個(gè)名字,指定它要接收什么的變量。在調(diào)用這個(gè)函數(shù)之前,我們還得定義這個(gè)函數(shù)。
這就行了!首先,我們創(chuàng)建了第一個(gè)自己的函數(shù)。我們定義了兩個(gè)新變量,$first和$second,注意它們是怎樣被定義的。在調(diào)用這個(gè)函數(shù)時(shí),要給這兩個(gè)變量按它們出現(xiàn)的順序賦好值 - 4賦給$first,5賦給$second。然后我們簡(jiǎn)單地把這兩個(gè)數(shù)加在一起,返回結(jié)果?!胺祷亍痹谶@里的意思是把結(jié)果送回去。在程序最后部分我們把數(shù)字9顯示出來(lái)。
我們?cè)賮?lái)創(chuàng)建一個(gè)函數(shù),讓它對(duì)我們的數(shù)據(jù)庫(kù)應(yīng)用有點(diǎn)幫助。一個(gè)能妥善處理錯(cuò)誤的函數(shù)怎么樣?試試下面的程序:
";echo "系統(tǒng)報(bào)告的錯(cuò)誤是:$error.\n
";echo "最好是暫時(shí)關(guān)閉網(wǎng)站并通知系統(tǒng)管理員。";die;}if (!$db = @mysql_connect("localhost","user", "password")) {$db_error = "無(wú)法連接到MySQL數(shù)據(jù)庫(kù)";do_error($db_error);}?>
在運(yùn)行程序之前,試試關(guān)閉MySQL數(shù)據(jù)庫(kù),或使用錯(cuò)誤的用戶名或口令。您會(huì)看到友好的、有用的錯(cuò)誤信息 。細(xì)心的朋友會(huì)注意到在mysql_connect()函數(shù)之前的那個(gè)@符號(hào)。它會(huì)抑制系統(tǒng)錯(cuò)誤信息,使得程序只能從do_error()函數(shù)那里得到有關(guān)的錯(cuò)誤信息。您還會(huì)注意到,我們可以把一個(gè)在別處定義的變量作為參數(shù)傳給函數(shù),而不是在調(diào)用時(shí)直接賦一個(gè)值。
還記得我過(guò)函數(shù)使用的是私有變量吧?這話說(shuō)得不完全對(duì)。事實(shí)上,您可以讓函數(shù)訪問(wèn)到函數(shù)外面的變量。您可能要寫(xiě)一個(gè)函數(shù),用它來(lái)查詢數(shù)據(jù)庫(kù),然后把結(jié)果顯示在多個(gè)網(wǎng)頁(yè)中。您不想每次都把數(shù)據(jù)庫(kù)連接標(biāo)識(shí)都傳給函數(shù)。在這種情況下,您可以把連接標(biāo)識(shí)定義成一個(gè)全局的變量。例如:
這是個(gè)很簡(jiǎn)單的函數(shù),但重要的是,您在調(diào)用這個(gè)函數(shù)時(shí),不必傳遞$db變量 - 您可以通過(guò) global這個(gè)字使得函數(shù)可以訪問(wèn)到該變量。在這條語(yǔ)句中您可以定義多個(gè)全局變量,各個(gè)全局變量之間用逗號(hào)隔開(kāi)。
最后,您可以使用可選參數(shù),這樣看起來(lái)您已經(jīng)是真正的專家了。這里面關(guān)鍵的一點(diǎn)是,在函數(shù)中定義參數(shù)時(shí)要給它指定一個(gè)缺省值。然后您在調(diào)用這個(gè)函數(shù)時(shí),如果不為該參數(shù)變量指定其他值,那么函數(shù)會(huì)自動(dòng)把缺省值賦給這個(gè)變量。如果您指定了其他值,那么缺省值就不起作用了。
不太明白?比方說(shuō),您在連接數(shù)據(jù)庫(kù)時(shí),幾乎總是連接到相同的服務(wù)器,并且使用相同的用戶名和口令。不過(guò)有時(shí)候,您也需要連接到其他的服務(wù)器??纯聪旅娴某绦颍?
很“酷”是不是?在定義函數(shù)時(shí),函數(shù)內(nèi)部用到的變量也定義好了。第一次調(diào)用這個(gè)函數(shù)時(shí),全部參數(shù)變量都是用的缺省值。第二次調(diào)用時(shí),服務(wù)器名變了,而用戶名和口令沒(méi)有變。真是太棒了!
想想您在什么地方還能用到函數(shù)。您可以用函數(shù)來(lái)作數(shù)據(jù)校驗(yàn),來(lái)完成常用的功能,等等。在對(duì)Web網(wǎng)頁(yè)上顯示的文字作處理時(shí),我用到了很多函數(shù)。我可以一次完成對(duì)文字的檢查、解析和修改,來(lái)加入換行符和HTML標(biāo)記等。
現(xiàn)在,剩下的就是我要給您的一些忠告了。>>
五、進(jìn)階技巧
談起數(shù)據(jù)庫(kù)開(kāi)發(fā),我們有很多東西要學(xué)。如果您還沒(méi)有學(xué)習(xí)過(guò)怎樣進(jìn)行數(shù)據(jù)庫(kù)設(shè)計(jì),和怎樣在不同的平臺(tái)上可靠地運(yùn)行數(shù)據(jù)庫(kù),那么請(qǐng)您趕快去找本這方面的好書(shū)來(lái)讀一讀。這方面的能力會(huì)帶給您無(wú)法估量的好處,從長(zhǎng)遠(yuǎn)的眼光看,它會(huì)為您節(jié)省大量的時(shí)間與精力。還有,認(rèn)真學(xué)學(xué)MySQL。這是一個(gè)復(fù)雜而有趣的數(shù)據(jù)庫(kù),有很多不錯(cuò)的文檔。學(xué)學(xué)數(shù)據(jù)庫(kù)的表結(jié)構(gòu)、數(shù)據(jù)類型,還有SQL。如果您真正掌握了SQL,您可以完成相當(dāng)多的實(shí)際工作。
最后,還有PHP。您想要的一切幾乎都可以在PHP的網(wǎng)站上找到,包括全面的文檔、郵件討論組的討論內(nèi)容、程序代碼庫(kù),等等。學(xué)習(xí)PHP的一個(gè)絕好的辦法是研究用戶手冊(cè)中給出的實(shí)例,并查閱網(wǎng)上的代碼。網(wǎng)友們發(fā)表的代碼包括許多函數(shù)和類,您可以在自己的程序中直接使用,而不必自己從頭來(lái)過(guò)。另外,如果您遇到問(wèn)題,郵件討論組是一個(gè)非常值得利用的資源。PHP的開(kāi)發(fā)人員自己也會(huì)參加郵件討論組,還有許多經(jīng)驗(yàn)豐富的高手們,他們都可以幫助您解決問(wèn)題。
祝您編程順利,一切順利

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

PHPisstillrelevantinmodernenterpriseenvironments.1.ModernPHP(7.xand8.x)offersperformancegains,stricttyping,JITcompilation,andmodernsyntax,makingitsuitableforlarge-scaleapplications.2.PHPintegrateseffectivelyinhybridarchitectures,servingasanAPIgateway

Avoid N 1 query problems, reduce the number of database queries by loading associated data in advance; 2. Select only the required fields to avoid loading complete entities to save memory and bandwidth; 3. Use cache strategies reasonably, such as Doctrine's secondary cache or Redis cache high-frequency query results; 4. Optimize the entity life cycle and call clear() regularly to free up memory to prevent memory overflow; 5. Ensure that the database index exists and analyze the generated SQL statements to avoid inefficient queries; 6. Disable automatic change tracking in scenarios where changes are not required, and use arrays or lightweight modes to improve performance. Correct use of ORM requires combining SQL monitoring, caching, batch processing and appropriate optimization to ensure application performance while maintaining development efficiency.

To build a flexible PHP microservice, you need to use RabbitMQ to achieve asynchronous communication, 1. Decouple the service through message queues to avoid cascade failures; 2. Configure persistent queues, persistent messages, release confirmation and manual ACK to ensure reliability; 3. Use exponential backoff retry, TTL and dead letter queue security processing failures; 4. Use tools such as supervisord to protect consumer processes and enable heartbeat mechanisms to ensure service health; and ultimately realize the ability of the system to continuously operate in failures.

Use subprocess.run() to safely execute shell commands and capture output. It is recommended to pass parameters in lists to avoid injection risks; 2. When shell characteristics are required, you can set shell=True, but beware of command injection; 3. Use subprocess.Popen to realize real-time output processing; 4. Set check=True to throw exceptions when the command fails; 5. You can directly call chains to obtain output in a simple scenario; you should give priority to subprocess.run() in daily life to avoid using os.system() or deprecated modules. The above methods override the core usage of executing shell commands in Python.

Using the correct PHP basic image and configuring a secure, performance-optimized Docker environment is the key to achieving production ready. 1. Select php:8.3-fpm-alpine as the basic image to reduce the attack surface and improve performance; 2. Disable dangerous functions through custom php.ini, turn off error display, and enable Opcache and JIT to enhance security and performance; 3. Use Nginx as the reverse proxy to restrict access to sensitive files and correctly forward PHP requests to PHP-FPM; 4. Use multi-stage optimization images to remove development dependencies, and set up non-root users to run containers; 5. Optional Supervisord to manage multiple processes such as cron; 6. Verify that no sensitive information leakage before deployment

PHP's garbage collection mechanism is based on reference counting, but circular references need to be processed by a periodic circular garbage collector; 1. Reference count releases memory immediately when there is no reference to the variable; 2. Reference reference causes memory to be unable to be automatically released, and it depends on GC to detect and clean it; 3. GC is triggered when the "possible root" zval reaches the threshold or manually calls gc_collect_cycles(); 4. Long-term running PHP applications should monitor gc_status() and call gc_collect_cycles() in time to avoid memory leakage; 5. Best practices include avoiding circular references, using gc_disable() to optimize performance key areas, and dereference objects through the ORM's clear() method.

ReadonlypropertiesinPHP8.2canonlybeassignedonceintheconstructororatdeclarationandcannotbemodifiedafterward,enforcingimmutabilityatthelanguagelevel.2.Toachievedeepimmutability,wrapmutabletypeslikearraysinArrayObjectorusecustomimmutablecollectionssucha

Bref enables PHP developers to build scalable, cost-effective applications without managing servers. 1.Bref brings PHP to AWSLambda by providing an optimized PHP runtime layer, supports PHP8.3 and other versions, and seamlessly integrates with frameworks such as Laravel and Symfony; 2. The deployment steps include: installing Bref using Composer, configuring serverless.yml to define functions and events, such as HTTP endpoints and Artisan commands; 3. Execute serverlessdeploy command to complete the deployment, automatically configure APIGateway and generate access URLs; 4. For Lambda restrictions, Bref provides solutions.
