PHP腳本數(shù)據(jù)庫功能詳解
當(dāng)前位置:點晴教程→知識管理交流
→『 技術(shù)文檔交流 』
在當(dāng)前互聯(lián)網(wǎng)發(fā)展迅速、電子商務(wù)網(wǎng)站層出不窮的形勢下,對網(wǎng)站開發(fā)的效率和質(zhì)量提出了越來越高的要求。 對于大型和結(jié)構(gòu)復(fù)雜、內(nèi)容繁多的網(wǎng)站,都要實現(xiàn)網(wǎng)站的動態(tài)化和方便的管理。數(shù)據(jù)管理離不開數(shù)據(jù)庫系統(tǒng)的支持。而衡量一種CGI語言的重要標(biāo)志,就是它對后臺數(shù)據(jù)庫的訪問能力、效率等。 而目前流行的PHP腳本語言,它的新特性給我們帶來了新的感覺。它支持以面向?qū)ο蟮姆绞竭M行設(shè)計開發(fā)。同時,為了滿足網(wǎng)頁獨特的需要,用模板、XML支持等帶來了網(wǎng)站開發(fā)的新方法。在語言結(jié)構(gòu)上,PHP具有類似于C++語言的結(jié)構(gòu),并引入了類的概念,簡化了開發(fā)。 PHP還具有強大的數(shù)據(jù)庫支持能力。我們這里就通過實例,首先介紹PHP訪問數(shù)據(jù)庫的一般流程,然后通過文件的數(shù)據(jù)庫存儲介紹PHP訪問數(shù)據(jù)庫的一種高級應(yīng)用。最后通過數(shù)據(jù)庫類的使用實例,介紹真正實用高效的數(shù)據(jù)庫開發(fā)方法。 圖1 PHP數(shù)據(jù)庫功能簡介 PHP提供對10余種常見數(shù)據(jù)庫的支持,如Oracle、dBase、Informix、SQL Server、Sysbase、MySQL等。正是由于廣泛的數(shù)據(jù)庫支持,才拓展了PHP的應(yīng)用范圍, 使得各種應(yīng)用都可以利用PHP進行開發(fā)。 在各種數(shù)據(jù)庫中,MySQL由于其免費、跨平臺、使用方便、訪問效率較高,獲得了很大的應(yīng)用。很多中心型網(wǎng)站都使用PHP+MySQL這一最佳搭檔。 Oracle是典型的大型數(shù)據(jù)庫應(yīng)用系統(tǒng)。如果你設(shè)計的網(wǎng)站數(shù)據(jù)量大,性能、效率要求高的話,Oracle是個不錯的選擇。 在Win32平臺上,SQL Server占有較大的市場。PHP可以訪問SQL Server。 PHP對各種數(shù)據(jù)庫的訪問方法進行封裝,針對不同數(shù)據(jù)庫系統(tǒng)的函數(shù)也很相似,增加了使用的方便性。 下面,我們將以一個簡單的人才信息交流中心(見圖1)為例子,編程實現(xiàn)個人簡歷的在線提交、瀏覽等功能,講述PHP數(shù)據(jù)庫操作的全過程。數(shù)據(jù)庫采用最常用的MySQL數(shù)據(jù)庫。 PHP數(shù)據(jù)庫操作基本步驟 我們將在本地機器創(chuàng)建名為ResumeDB的數(shù)據(jù)庫,數(shù)據(jù)庫中有名為Resume的表。表中存儲個人簡歷的編號、人員名稱、個人簡介,以及Word格式的簡歷文件等。 1.數(shù)據(jù)庫的創(chuàng)建 切換至/usr/local/mysql/bin目錄,在命令行,執(zhí)行以下語句創(chuàng)建數(shù)據(jù)庫: ./mysqladmin-u root-p create ResumeDB Enter password: 在提示后輸入密碼。如果數(shù)據(jù)庫是第一次使用,默認(rèn)的密碼為空,直接回車即可。 然后創(chuàng)建保存?zhèn)€人簡歷的表。 創(chuàng)建文本文件Resume.sql,內(nèi)容如下: use ResumeDB; CREATE TABLE Resume ( ID tinyint(4) NOT NULL auto_increment, Name varchar(10) NOT NULL, Intro varchar(255), ResuFile longblob, PRIMARY KEY (ID), KEY ID (ID) ); 將其放到My的可執(zhí)行目錄/usr/local/mysql/bin下,執(zhí)行如下命令: ./mysql-u root-p〈 Resume.sql Enter password: 輸入數(shù)據(jù)庫密碼后,表Resume自動創(chuàng)建成功。其中,ResuFile字段為longbolb型,用來存儲二進制的Word文檔。 2.數(shù)據(jù)庫訪問流程 PHP對數(shù)據(jù)庫的訪問一般包括下列步驟:連接數(shù)據(jù)庫系統(tǒng)→選擇數(shù)據(jù)庫→執(zhí)行SQL語句→關(guān)閉結(jié)果集→關(guān)閉數(shù)據(jù)庫連接→結(jié)束。 (1) 連接數(shù)據(jù)庫 連接數(shù)據(jù)庫是建立用戶程序到數(shù)據(jù)庫系統(tǒng)的對話通道的過程。連接MySQL數(shù)據(jù)庫的語句如下: 〈? $LinkID=@mysql_connect("localhost", "root" , "") or die("不能連接到數(shù)據(jù)庫服務(wù)器!可能是數(shù)據(jù)庫服務(wù)器沒有啟動,或者用戶名密碼有誤!"); ?〉 其中,函數(shù)mysql_connect()用于與數(shù)據(jù)庫服務(wù)器建立連接。三個參數(shù)分別為:數(shù)據(jù)庫服務(wù)器的主機名(也可以是IP)、數(shù)據(jù)庫用戶名和用戶密碼。函數(shù)返回值用于表示這個數(shù)據(jù)庫連接。 從這個命令可以看到,我們可以指定并非本機的機器名作為數(shù)據(jù)庫服務(wù)器。這樣,就為數(shù)據(jù)的異地存放、數(shù)據(jù)庫的安全隔離提供了可能。外界用戶往往具有WWW服務(wù)器的直接訪問權(quán)限,如果數(shù)據(jù)庫系統(tǒng)直接放置在WWW服務(wù)器上,就可能會帶來安全隱患。而如果將數(shù)據(jù)庫系統(tǒng)放置于一臺防火墻后面的計算機上,PHP可以通過局域網(wǎng)訪問數(shù)據(jù)庫,而局域網(wǎng)內(nèi)部的計算機對外部是不可見的。這樣,就保證了數(shù)據(jù)庫不受外來攻擊的可能。 函數(shù)前面的“@”符號,用于限制這個命令的出錯信息的顯示。如果函數(shù)調(diào)用出錯,將執(zhí)行or后面的語句。die( )函數(shù)表示向用戶輸出引號中的內(nèi)容后,程序終止執(zhí)行。這樣做是為了防止數(shù)據(jù)庫連接出錯時,用戶看到一堆莫名其妙的專業(yè)名詞,而是提示定制的出錯信息。不過在調(diào)試的時候,我們還是可以不要屏蔽出錯信息,免得出錯后,難以找到到底哪里有問題。 (2) 數(shù)據(jù)庫選擇 一個數(shù)據(jù)庫系統(tǒng)可以包含多個數(shù)據(jù)庫。在建立了和數(shù)據(jù)庫服務(wù)器的連接后,我們就要告訴系統(tǒng),我們將要用到的數(shù)據(jù)庫是哪個。選擇數(shù)據(jù)庫的命令如下: 〈? @mysql_select_db("ResumeDB",$LinkID) or die("選擇數(shù)據(jù)庫出錯,可能是您指定的數(shù)據(jù)庫不存在!"); ?〉 選擇數(shù)據(jù)庫時,要提供的參數(shù)是數(shù)據(jù)庫的名稱、和服務(wù)器連接號。 當(dāng)我們只使用一臺數(shù)據(jù)庫服務(wù)器時,$LinkID可以省略,系統(tǒng)自動查找最近的一個數(shù)據(jù)庫連接然后使用它。但是,當(dāng)你要實現(xiàn)大型站點的時候,必不可少的要遇到多主機、多數(shù)據(jù)庫系統(tǒng)的情況。這時,數(shù)據(jù)庫連接參數(shù)就不能省略了。 (3) 數(shù)據(jù)庫訪問 好了,我們已經(jīng)建立了到數(shù)據(jù)庫的連接,選定了數(shù)據(jù)庫,接下了來的一切就是執(zhí)行SQL語句了。SQL語句的易用而強大的功能,將完成我們絕大部分的數(shù)據(jù)庫操作動作。 我們可以首先向數(shù)據(jù)庫里寫入一條個人信息記錄,然后把它顯示出來。 〈? $Name= "OpenBall"; //實際操作中,$Name、$Intro為從瀏覽器表單傳來的值 $Intro = "OpenBall的個人簡介……"; $query = "insert into Resume(Name,Intro) values('$Name', '$Intro')"; //生成SQL語句 $result = @mysql_query("$query",$LinkID); //執(zhí)行 if(! $result) echo "數(shù)據(jù)插入失敗!"; $query= "select ID,Name,Intro from Resume"; //生成SQL語句 $result = mysql_query($query,$LinkID); //執(zhí)行,結(jié)果集保存到變量$result中 $num= mysql_num_rows($result); //取得查詢返回的記錄行數(shù) if($num == 0) { echo "沒有找到任何記錄"; exit(); } while($row=mysql_fetch_array($result)) //取結(jié)果集的下一行數(shù)據(jù)到數(shù)組$row中 { echo $row["ID"]." ".$row["Name"]." ".$row["Intro"]."〈br〉"; //以字段名為索引訪問數(shù)組變量的值 } ?〉 上面的操作,共執(zhí)行了兩次數(shù)據(jù)庫操作。第一次為插入操作,第二次為查詢操作。程序首先插入當(dāng)前用戶的一天記錄,然后,顯示所有數(shù)據(jù)庫中的個人情況。 (4)資源釋放 操作的最后,是釋放結(jié)果集,釋放結(jié)果集和數(shù)據(jù)庫連接資源。 〈? @mysql_free_result($result); @mysql_close($LinkID); ?〉 如果在多個網(wǎng)頁中都要頻繁進行數(shù)據(jù)庫訪問,則可以建立與數(shù)據(jù)庫服務(wù)器的持續(xù)連接來提高效率。因為每次與數(shù)據(jù)庫服務(wù)器的連接需要較長的時間和較大的資源開銷,持續(xù)的連接相對來說會更有效。 建立持續(xù)連接的方法,就是在數(shù)據(jù)庫連接的時候,調(diào)用函數(shù)mysql_pconnect()代替mysql_connect() 。建立的持續(xù)連接在本程序結(jié)束時,不需要調(diào)用mysql_close()來關(guān)閉。下次程序在此執(zhí)行mysql_pconnect()時,系統(tǒng)自動直接返回已經(jīng)建立的持續(xù)連接的ID號,而不再去真的連接數(shù)據(jù)庫。 利用PHP將文件保存到數(shù)據(jù)庫 數(shù)據(jù)庫是數(shù)據(jù)組織、存儲的中心。將要處理的也可能是各種數(shù)據(jù),包括程序、文件、報表,甚至音頻、視頻數(shù)據(jù)。由于通過瀏覽器,個人用戶只能填寫少部分的個人簡歷。因此,我們這里示范用戶個人簡歷上載的功能。其他類型的數(shù)據(jù)可以模仿此例進行操作。 首先是信息收集頁面。讓用戶選擇要上載的文件。此頁面的html代碼如下: 〈!-- begin of post.htm--〉 〈p〉 〈/p〉 〈form method="POST" action="insert.php" ENCTYPE="multipart/form-data"〉 〈p〉〈b〉個人簡歷提交〈/b〉〈/p〉 〈p〉姓名:〈br〉 〈input type="text" name="Name" size="20"〉〈/p〉 〈p〉個人簡介:〈br〉 〈textarea rows="2" name="Intro" cols="20"〉〈/textarea〉〈/p〉 〈p〉簡歷文件:〈br〉 〈input type="file" name="ResuFile"〉〈/p〉 〈p〉〈input type="submit" value="提交" name="B1"〉〈/p〉 〈/form〉 〈!-End of post.htm--〉 注意,ENCTYPE關(guān)鍵字一定不能省,否則文件無法正確上載。 這里,我們再把向數(shù)據(jù)庫插入記錄的代碼重新設(shè)計: 〈? //begin of file insert.php if($ResuFile != "none") //確定用戶選擇了文件 { $Size = filesize($ResuFile); //確定文件大小 $mFileData = addslashes(fread(fopen($ResuFile, "r"), $Size)); //讀取文件,對內(nèi)容進行處理 unlink($ResuFile); //刪除上載臨時文件 } $LinkID=@mysql_connect("localhost", "root" , "") or die("不能連接到數(shù)據(jù)庫服務(wù)器!可能是數(shù)據(jù)庫服務(wù)器沒有啟動,或者用戶名密碼有誤!"); $DBID = @mysql_select_db("ResumeDB",$LinkID) or die("選擇數(shù)據(jù)庫出錯,可能是您指定的數(shù)據(jù)庫不存在!"); $query = "insert into Resume(Name,Intro,ResuFile) values('$Name', '$Intro', '$mFileData')"; $result = @mysql_query("$query",$LinkID); //執(zhí)行查詢,插入文件到數(shù)據(jù)庫 if(! $result) echo "數(shù)據(jù)插入失敗!"; else echo "文件上載成功!"; @mysql_close($LinkID); //end of file insert.php ?〉 有了上面的基礎(chǔ),寫出從數(shù)據(jù)庫讀數(shù)據(jù)的程序應(yīng)該很簡單了。需要注意的是文件向客戶發(fā)送的方法。服務(wù)器必須向瀏覽器發(fā)送頭信息,說明將要發(fā)送的數(shù)據(jù)為word文檔。如果用戶計算機裝有MSWord,瀏覽器將自動調(diào)用word進行文檔顯示。 我們可以設(shè)置一個超級鏈接,來下載這個Word文件: 〈? //begin of file show.php $LinkID=@mysql_connect("localhost", "root" , "") or die("不能連接到數(shù)據(jù)庫服務(wù)器!可能是數(shù)據(jù)庫服務(wù)器沒有啟動,或者用戶名密碼有誤!"); $DBID = @mysql_select_db("ResumeDB",$LinkID) or die("選擇數(shù)據(jù)庫出錯,可能是您指定的數(shù)據(jù)庫不存在!"); $query = "insert into Resume(Name,Intro,ResuFile) values('$Name', '$Intro', '$mFileData')"; $result = @mysql_query("$query",$LinkID); //執(zhí)行查詢,插入文件到數(shù)據(jù)庫 $query= "select ID,Name,Intro from Resume"; //生成SQL語句 $result = mysql_query($query,$LinkID); //執(zhí)行,結(jié)果集保存到變量$result中 $num= mysql_num_rows($result); //取得查詢返回的記錄行數(shù) if($num == 0) { echo "沒有找到任何記錄"; exit(); } while($row=mysql_fetch_array($result)) //取結(jié)果集的下一行數(shù)據(jù)到數(shù)組$row中 { echo $row["ID"]." ".$row["Name"]." ".$row["Intro"]." "; echo "〈a href= \"download.php?ID=".$row["ID"]."\"〉查看Word文檔〈/a〉〈br〉"; } //end of file show.php ?〉 訪問文件show.php,用戶看到的是個人簡要信息的列表。點擊“查看Word文檔”,即可看到對應(yīng)成員詳細(xì)的個人簡歷。 Word文檔的顯示是用下面的文件: 〈? // begin of file download.php $LinkID=@mysql_connect("localhost", "root" , "") or die("不能連接到數(shù)據(jù)庫服務(wù)器!可能是數(shù)據(jù)庫服務(wù)器沒有啟動,或者用戶名密碼有誤!"); $DBID = @mysql_select_db("ResumeDB",$LinkID) or die("選擇數(shù)據(jù)庫出錯,可能是您指定的數(shù)據(jù)庫不存在!"); $query = "select ResuFile from Resume where ID=$ID"; //$ID為調(diào)用傳遞的變量 $result = @mysql_query("$query",$LinkID); //執(zhí)行查詢,從數(shù)據(jù)庫讀取文件內(nèi)容 if(mysql_num_rows($result) 〈 1 ) { echo "沒有找到相應(yīng)的文件!"; exit(); } $row = mysql_fetch_array($result); $mFileData = $row["ResuFile"]; //讀取個人簡歷的內(nèi)容(Word文件格式的數(shù)據(jù)) header("Content-type: application/msword"); //發(fā)送頭信息,說明將要發(fā)送的數(shù)據(jù)為word文檔 echo $mFileData; //發(fā)送文檔數(shù)據(jù) //end of file download.php ?〉 至此,我們已經(jīng)實現(xiàn)了個人簡歷的提交、數(shù)據(jù)庫存儲、信息瀏覽等功能,基本完成了“人才信息交流”的框架功能。 需要說明的是,通過PHP進行文件上載及數(shù)據(jù)庫存儲是個較突出的技術(shù)難題。很多關(guān)于PHP的網(wǎng)站都不斷出現(xiàn)這類問題。這些操作,對平臺、環(huán)境設(shè)置依賴性較大。不同的平臺配置,都可能導(dǎo)致操作的失敗。本文后面附了上述程序的運行平臺、編譯參數(shù),以供參考。 用類加快PHP的數(shù)據(jù)庫開發(fā) 數(shù)據(jù)庫的訪問函數(shù)較多,使用不當(dāng)會降低效率,甚至導(dǎo)致錯誤。而PHP的本身就是開放的和可擴充的,很多人為它開發(fā)各種功能的源代碼。每一個PHP程序員都應(yīng)該善于繼承他人的成果,節(jié)省時間和精力。站在巨人的肩膀上,才能看得更遠(yuǎn)。當(dāng)然,你也可以把你的代碼共享出來,體會自己的勞動被承認(rèn)和創(chuàng)造價值而帶來的成就感。 使用數(shù)據(jù)庫類,可以使我們完全不必考慮具體的數(shù)據(jù)庫類型,而專注于程序的開發(fā)上。 眾多的開發(fā)工具包中,PHPLib是性能較穩(wěn)定、功能較完善的一個。PHPLib可以在http://phplib.netuse.de/ 獲得。它包含了數(shù)據(jù)庫的支持類。以MySQL數(shù)據(jù)庫為例,PHPLib自帶名為DB_Sql的類。它包裝了數(shù)據(jù)庫的連接、查詢、取結(jié)果、數(shù)據(jù)庫表的遍歷等功能。 使用數(shù)據(jù)庫類,可以使我們完全不必考慮具體的數(shù)據(jù)庫類型,而專注于程序的開發(fā)上。即使數(shù)據(jù)庫系統(tǒng)類型換了,程序代碼也不用改。同時,數(shù)據(jù)庫類提供了完整而健壯的數(shù)據(jù)庫訪問方法,這可能是使用類的包裝的最大的優(yōu)勢了。 下面,我們就使用PHPLib提供的數(shù)據(jù)庫類,來訪問我們剛才建立的數(shù)據(jù)庫,并對內(nèi)容進行顯示。 〈? require "db_mysql.php"; //包含數(shù)據(jù)庫類的生成文件 $db=new DB_Sql; //聲明數(shù)據(jù)庫類的實例 $db-〉connect("ResumeDB","localhost", "root", ""); //連接數(shù)據(jù)庫服務(wù)器 //提供的參數(shù)依次為:數(shù)據(jù)庫名,主機名,用戶名,用戶密碼 if ($db-〉Link_ID) //判斷是否正確建立連接 { $db-〉query("select ID,Name,Intro FROM Resume"); //查詢 if ($db-〉nf()) //判斷結(jié)果集是否為空 { while ($db-〉next_record()) //取得下一行記錄值,直到記錄集內(nèi)容取完 { echo "ID:", $db-〉f("ID"); //f()函數(shù)返回當(dāng)前記錄某個子段的值 echo "〈br〉"; echo "姓名:"; $db-〉p("Name"); //p()函數(shù)直接打印某個子段的值 //等價于echo $db-〉f("name") echo "〈br〉"; echo "簡介:"; echo $db-〉f("Intro"); echo "〈br〉"; echo "〈a href= \"download.php?ID=".$db-〉f("ID")."\"〉查看Word文檔〈/a〉"; echo "〈br〉〈hr〉"; } } $db-〉free (); //釋放資源 } ?〉 從上面的流程可以看出,用類訪問數(shù)據(jù)庫的方法和直接訪問數(shù)據(jù)庫的方法基本相同。不同的是,這里我們調(diào)用的方法都是類的方法,而不是具體針對某種數(shù)據(jù)庫的函數(shù)。由于代碼和具體數(shù)據(jù)庫類型的分離,使得當(dāng)數(shù)據(jù)庫系統(tǒng)改變的時候,我們不用改變程序代碼,只要改變基類的實現(xiàn)方法即可。 如果結(jié)合使用PHPLib模板進行設(shè)計的話,即可實現(xiàn)程序與顯示的分離。也將使得程序結(jié)構(gòu)清晰,網(wǎng)頁美工設(shè)計制作方便。 簡便的用法、合理的任務(wù)分配、合乎思維的對象包裝,將使得網(wǎng)站開發(fā)效率大大提高。 附:代碼測試平臺 以上程序代碼全部在下面的平臺測試通過 RedHat Linux 6.1+Apache1.3.12+ PHP4.0+MySql3.22.32 數(shù)據(jù)庫的安裝配置過程為: cd /usr/local/src/mysql* ./configure --refix=/usr/local/mysql make make install Apache的安裝配置過程為: cd /usr/local/src/apache* ./configure --prefix=/usr/local/apache --enable-shared=max make make install PHP的安裝配置過程為: cd /usr/local/src/php* ./configure --with-apxs=/usr/local/apache/bin/apxs \ --with-config-file-path=/usr/local/ apache/conf \ --with-mysql=/usr/local/mysql \ --enable-debug=no \ --enable-track-vars php.ini配置過程為: 拷貝php.ini-dist到/usr/local/ apache/conf/php.ini 編輯httpd.conf,把下面兩行的注釋去掉 AddType application/x-httpd-php .php .php3 AddType application/x-httpd-php-source .phps
該文章在 2012/3/27 22:41:53 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |