十年網(wǎng)站開發(fā)經驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
PHP訪問MySQL數(shù)據(jù)庫:

公司主營業(yè)務:成都網(wǎng)站建設、成都做網(wǎng)站、移動網(wǎng)站開發(fā)等業(yè)務。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出晉州免費做網(wǎng)站回饋大家。
因為連接數(shù)據(jù)庫需要較長的時間和較大的資源開銷,所以如果在多個網(wǎng)頁中都要頻繁地訪問數(shù)據(jù)庫,則可以建立與數(shù)據(jù)庫的持續(xù)連接。即調用mysql_pconnect()代替mysql_connect()。
基本步驟:
1.連接服務器:mysql_connect();
2.選擇數(shù)據(jù)庫:mysql_select_db();
3.執(zhí)行SQL語句:mysql_query();
查詢:select
顯示:show
插入:insert into
更新:update
刪除:delete
4.關閉結果集:mysql_free_result($result);
5.關閉數(shù)據(jù)庫:mysql_close($link);
以mysql為例
字段:userid,username,password,email
1.連接數(shù)據(jù)庫:$conn=mysql_connect("localhost","username","password");
2.選擇數(shù)據(jù)庫:$db=mysql_select_db("databaseName",$conn);
3.構造sql語句:$sql="select * from userinfo";
4.執(zhí)行查詢:$result=mysql_query($sql);
5.讀取數(shù)據(jù):$row=mysql_fetch_query($result);
6.循環(huán)顯示讀取數(shù)據(jù):
while($row){
echo $row["username"];
echo $row["password"];
echo $row["email"];
……
$row=mysql_fetch_query($result);
}
我只針對你這個做優(yōu)化吧。。
第一個不要用select * 這樣的sql語句,你需要什么字段就寫哪些字段
都需要的話,你都寫出來,select * 效率很低的。。
第二個如果說你的后臺中對這些數(shù)據(jù)的變動不是很頻繁
然后你可以將查詢結果存入memcahe中
我寫一段偽代碼
$mem_key="all";
$res = $memcache-get($mem_key);
//如果沒有存入memcache中
if (empty($res){
//sql語句可以用left jion on關聯(lián)查詢
$aaa="select b.字段1,b.字段2...from btb as b left jion tb as b.id=t.id";
$bb=$mysql-_query($aaa);
while(!!$_rows=$mysql-_fetch_array_list($bb)){
//do something
$res ....
}
//結果存入memecahed中
$memcache-set($mem_key,$res,0,超時時間);
}
$res就是你獲取的結果。。
你這段代碼基本可以這樣。。
Web數(shù)據(jù)庫訪問技術通常是通過三層結構來實現(xiàn)的。目前建立與Web數(shù)據(jù)庫連接訪問的技術方法可歸納為CGI技術,ODBC技術和ASP、JSP、PHP技術。
CGI技術
CGI(Common Gateway Interface,通用網(wǎng)關界面)是一種Web服務器上運行的基于Web瀏覽器輸入程序的方法,是最早的訪問數(shù)據(jù)庫的解決方案。CGI程序可以建立網(wǎng)頁與數(shù)據(jù)庫之間的連接,將用戶的查詢要求轉換成數(shù)據(jù)庫的查詢命令,然后將查詢結果通過網(wǎng)頁返回給用戶。
CGI程序需要通過一個接口才能訪問數(shù)據(jù)庫。這種接口多種多樣,數(shù)據(jù)庫系統(tǒng)對CGI程序提供了各種數(shù)據(jù)庫接口如Perl、C/C++、VB等。為了使用各種數(shù)據(jù)庫系統(tǒng),CGI程序支持ODBC方式,通過ODBC接口訪問數(shù)據(jù)庫。
ODBC技術
ODBC(Open Database Connectivity,開放數(shù)據(jù)庫互接)是一種使用SQL的應用程序接口(API)。ODBC最顯著的優(yōu)點就是它生成的程序與數(shù)據(jù)庫系統(tǒng)無關,為程序員方便地編寫訪問各種DBMS的數(shù)據(jù)庫應用程序提供了一個統(tǒng)一接口,使應用程序和數(shù)據(jù)庫源之間完成數(shù)據(jù)交換。ODBC的內部結構為4層:應用程序層、驅動程序管理器層、驅動程序層、數(shù)據(jù)源層。它們之間的關系如圖1-5所示。由于ODBC適用于不同的數(shù)據(jù)庫產品,因此許多服務器擴展程序都使用了包含ODBC層的系統(tǒng)結構。
Web服務器通過ODBC數(shù)據(jù)庫驅動程序向數(shù)據(jù)庫系統(tǒng)發(fā)出SQL請求,數(shù)據(jù)庫系統(tǒng)接收到的是標準SQL查詢語句,并將執(zhí)行后的查詢結果再通過ODBC傳回Web服務器,Web服務器將結果以HTML網(wǎng)頁傳給Web瀏覽器,工作原理如圖1-6所示。
由于Java語言所顯示出來的編程優(yōu)勢贏得了眾多數(shù)據(jù)庫廠商的支持。在數(shù)據(jù)庫處理方面,Java提供的JDBC為數(shù)據(jù)庫開發(fā)應用提供了標準的應用程序編程接口。與ODBC類似,JDBC也是一種特殊的API,是用于執(zhí)行SQL語句的Java應用程序接口。它規(guī)定了Java如何與數(shù)據(jù)庫之間交換數(shù)據(jù)的方法。采用Java和JDBC編寫的數(shù)據(jù)庫應用程序具有與平臺無關的特性。
ASP、JSP、PHP技術
ASP是Microsoft開發(fā)的動態(tài)網(wǎng)頁技術,主要應用于Windows NT+IIS或 Windows 9x+PWS平臺。確切地說ASP不是一種語言,而是Web服務器端的開發(fā)環(huán)境。利用ASP可以產生和運行動態(tài)的、交互的、高性能的Web服務應用程序。ASP支持多種腳本語言,除了VBScript和Pscript,也支持Perl語言,并且可以在同一ASP文件中使用多種腳本語言以發(fā)揮各種腳本語言的最大優(yōu)勢。但ASP默認只支持VBScript和Pscript,若要使用其他腳本語言,必須安裝相應的腳本引擎。ASP支持在服務器端調用ActiveX組件ADO對象實現(xiàn)對數(shù)據(jù)庫的操作。在具體的應用中,若腳本語言中有訪問數(shù)據(jù)庫的請求,可通過ODBC與后臺數(shù)據(jù)庫相連,并通過ADO執(zhí)行訪問庫的操作。關于ASP的編程技術將會在第7章中詳細介紹。
JSP是Sun公司推出的新一代Web開發(fā)技術。作為Java家族的一員,幾乎可以運行在所有的操作系統(tǒng)平臺和Web服務器上,因此JSP的運行平臺更為廣泛。目前JSP支持的腳本語言只有Java。JSP使用JDBC實現(xiàn)對數(shù)據(jù)庫的訪問。目標數(shù)據(jù)庫必須有一個JDBC的驅動程序,即一個從數(shù)據(jù)庫到Java的接口,該接口提供了標準的方法使Java應用程序能夠連接到數(shù)據(jù)庫并執(zhí)行對數(shù)據(jù)庫的操作。JDBC不需要在服務器上創(chuàng)建數(shù)據(jù)源,通過JDBC、JSP就可以實現(xiàn)SQL語句的執(zhí)行。
PHP是Rasmus Lerdorf推出的一種跨平臺的嵌入式腳本語言,可以在Windows、UNIX、Linux等流行的操作系統(tǒng)和IIS、Apache、Netscape等Web服務器上運行,用戶更換平臺時,無需變換PHP代碼。PHP是通過Internet合作開發(fā)的開放源代碼軟件,它借用了C、Java、Perl語言的語法并結合PHP自身的特性,能夠快速寫出動態(tài)生成頁面。PHP可以通過ODBC訪問各種數(shù)據(jù)庫,但主要通過函數(shù)直接訪問數(shù)據(jù)庫。PHP支持目前絕大多數(shù)的數(shù)據(jù)庫,提供許多與各類數(shù)據(jù)庫直接互連的函數(shù),包括Sybase、Oracle、SQL Server等,其中與SQL Server數(shù)據(jù)庫互連是最佳組合。
很多程序員都學習過如何使用 MySQL 或 MySQLi 擴展訪問數(shù)據(jù)庫。在 PHP 5.1 中,有一個更好的方法。?PHP Data Objects?(PDO) 提供了很多預處理語句的方法,且使用對象將使你的工作更有成效!
PDO 介紹
“PDO – PHP Data Objects – 是一個對多種數(shù)據(jù)庫提供統(tǒng)一操作方法的數(shù)據(jù)庫訪問層?!?/p>
它并不具備數(shù)據(jù)庫特有的語法,但它將使切換數(shù)據(jù)庫和平臺更加容易,多數(shù)情況下,只需要簡單修改鏈接字符串。
這并非一篇完整教導如何使用SQL的教程。它重要為那些現(xiàn)今仍在使用 mysql 或 mysqli 擴展的人,幫助他們躍至更具可移植性和強力的 PDO。
數(shù)據(jù)庫支持
此擴展可以使用 PDO 驅動編寫過的所有數(shù)據(jù)庫。在本文書寫時,下面的數(shù)據(jù)庫支持已經實現(xiàn):
PDO_DBLIB ( FreeTDS / Microsoft SQL Server / Sybase )
PDO_FIREBIRD ( Firebird/Interbase 6 )
PDO_IBM ( IBM DB2 )
PDO_INFORMIX ( IBM Informix Dynamic Server )
PDO_MYSQL ( MySQL 3.x/4.x/5.x )
PDO_OCI ( Oracle Call Interface )
PDO_ODBC ( ODBC v3 (IBM DB2, unixODBC and win32 ODBC) )
PDO_PGSQL ( PostgreSQL )
PDO_SQLITE ( SQLite 3 and SQLite 2 )
PDO_4D ( 4D )
你的系統(tǒng)不會也不必支持所有上面的驅動;下面是一個快速檢查所支持數(shù)據(jù)庫的方法:
1 print_r(PDO::getAvailableDrivers());
連接
不同數(shù)據(jù)庫的連接方法可能稍有不同,下面是一些較為流行的數(shù)據(jù)庫連接方法。你將注意到,雖然數(shù)據(jù)庫類型不同,前三種數(shù)據(jù)庫的連接方式是相同的——而 SQLite 使用自己的語法。
Connection String
01 try {
02 ?# MS SQL Server andSybase with PDO_DBLIB
03 ?$DBH = newPDO("mssql:host=$host;dbname=$dbname, $user, $pass");
04 ?$DBH = newPDO("sybase:host=$host;dbname=$dbname, $user, $pass");
05
06 ?# MySQL with PDO_MYSQL
07 ?$DBH = newPDO("mysql:host=$host;dbname=$dbname", $user, $pass);
08
09 ?# SQLite Database
10 ?$DBH = newPDO("sqlite:my/database/path/database.db");
11 }
12 catch(PDOException $e) {
13 ? ?echo$e-getMessage();
14 }
注意 try/catch 塊——你應該總是使用 try/catch 包裝你的 PDO 操作,并使用異常機制——這里只是簡單的示例。通常,你只需要一個連接——有很多可以教你語法的列表。 $DBH 代表“數(shù)據(jù)庫句柄”,這將貫穿全文。
通過將句柄設置為 NULL,你可以關閉任一連接。
1 # close the connection
2 $DBH = null;
你可以在PHP.net找到更多數(shù)據(jù)庫特定選項和/或其它數(shù)據(jù)庫連接字符串的信息。
異常與 PDO
PDO 可以使用異常處理錯誤,這意味著你的所有 PDO 操作都應當包裝在一個 try/catch 塊中。你可以通過設定錯誤模式屬性強制 PDO 在新建的句柄中使用三種錯誤模式中的某一個。下面是語法:
1 $DBH-setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
2 $DBH-setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
3 $DBH-setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
無論你設定哪個錯誤模式,一個錯誤的連接總會產生一個異常,因此創(chuàng)建連接應該總是包裝在 try/catch 塊中。
PDO::ERRMODE_SILENT
這是默認的錯誤模式。如果你使用這個模式,你將得使用同 mysql 或 mysqli 擴展一樣的方法差錯。其它兩種模式更適合 DRY 編程。
PDO::ERRMODE_WARNING
此方法將會發(fā)出一個標準PHP警告,并允許程序繼續(xù)運行。這對調試很有幫助。
PDO::ERRMODE_EXCEPTION
這是多數(shù)情況下你所希望的方式。它生成異常,允許你更容易的處理錯誤,隱藏可能導致它人了解你系統(tǒng)的信息。下面是一個充分利用異常的示例:
01 # connect to the database
02 try {
03 ?$DBH = newPDO("mysql:host=$host;dbname=$dbname", $user, $pass);
04 ?$DBH-setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
05
06 ?# UH-OH! Typed DELECT instead of SELECT!
07 ?$DBH-prepare('DELECT name FROM people');
08 }
09 catch(PDOException $e) {
10 ? ?echo"I'm sorry, Dave. I'm afraid I can't do that.";
11 ? ?file_put_contents('PDOErrors.txt', $e-getMessage(), FILE_APPEND);
12 }
在 select 語句中有一個故意留下的錯誤;這將導致一個異常。異常錯誤細節(jié)保存至一個 log 文件,并生成一段友好的(或不怎么友好的)信息於用戶。
插入和更新
插入新數(shù)據(jù),更新已存數(shù)據(jù)是一種非常常見的數(shù)據(jù)庫操作。使用 PDO,這通常需要兩個步驟。本節(jié)中所述的所有內容對更新和插入都有效。
這里有一個最基本的插入示例:
1 # STH means "Statement Handle"
2 $STH = $DBH-prepare("INSERT INTO folks ( first_name ) values ( 'Cathy' )");
3 $STH-execute();
你也可以使用 exec() 完成相同的操作,這將減少調用。多數(shù)情況下,你會使用調用多的方法,以充分利用語句預處理的優(yōu)勢。即使你只用它一次,使用語句預處理,幫助你保護你的 SQL 免于注入攻擊。
預處理語句
使用語句預處理將幫助你免于SQL注入攻擊。
一條預處理語句是一條預編譯的 SQL 語句,它可以使用多次,每次只需將數(shù)據(jù)傳至服務器。其額外優(yōu)勢在于可以對使用占位符的數(shù)據(jù)進行安全處理,防止SQL注入攻擊。
你通過在 SQL 語句中使用占位符的方法使用預處理語句。下面是三個例子:一個沒有占位符,一個使用無名占位符,一個使用命名占位符。
1 # no placeholders - ripe for SQL Injection!
2 $STH = $DBH-("INSERT INTO folks (name, addr, city) values ($name, $addr, $city)");
3
4 # unnamed placeholders
5 $STH = $DBH-("INSERT INTO folks (name, addr, city) values (?, ?, ?);
6
7 # named placeholders
8 $STH = $DBH-("INSERT INTO folks (name, addr, city) value (:name, :addr, :city)");
你希望避免第一種方法。選擇命名我無名占位符將會對你對語句中數(shù)據(jù)的設置產生影響。
無名占位符
01 # assign variables to each place holder, indexed 1-3
02 $STH-bindParam(1, $name);
03 $STH-bindParam(2, $addr);
04 $STH-bindParam(3, $city);
05
06 # insert one row
07 $name = "Daniel"
08 $addr = "1 Wicked Way";
09 $city = "Arlington Heights";
10 $STH-execute();
11
12 # insert another row with different values
13 $name = "Steve"
14 $addr = "5 Circle Drive";
15 $city = "Schaumburg";
16 $STH-execute();
這里有兩步。首先,我們對各個占位符指定變量(2-4行)。然后,我們對各個占位符指定數(shù)據(jù),并執(zhí)行語句。要發(fā)送另一組數(shù)據(jù),只需改變這些變量的值并再次執(zhí)行語句。
這種方法看上去對擁有很多參數(shù)的語句很笨拙吧?的確。然而,當數(shù)據(jù)保存于數(shù)組中時,這非常容易簡略:
1 # the data we want to insert
2 $data = array('Cathy', '9 Dark and Twisty Road', 'Cardiff');
3
4 $STH = $DBH-("INSERT INTO folks (name, addr, city) values (?, ?, ?);
5 $STH-execute($data);
容易吧!
數(shù)組中的數(shù)據(jù)按順序填入占位符中。 $data[0]是第一個,$data[1]是第二個,依次。不過,要是數(shù)組中數(shù)據(jù)的次序不正確,這將不能正常運行,你需要先對數(shù)組排序。
命名占位符
你可能已經開始猜測語法了,不過下面就是示例:
1 # the first argument is the named placeholder name - notice named
2 # placeholders always start with a colon.
3 $STH-bindParam(':name', $name);
你可以看使用快捷方式,但它需使用關聯(lián)數(shù)組。下面是示例:
1 # the data we want to insert
2 $data = array( 'name' = 'Cathy', 'addr' = '9 Dark and Twisty', 'city' = 'Cardiff' );
3
4 # the shortcut!
5 $STH = $DBH-("INSERT INTO folks (name, addr, city) value (:name, :addr, :city)");
6 $STH-execute($data);
數(shù)組中的鍵不需要以冒號開頭,但其它部分需要同占位符匹配。如果你有一個二維數(shù)組,你只需遍歷它,并對遍歷的每個數(shù)組執(zhí)行語句。
命名占位符的另一個好的功能是直接將對象插入到你的數(shù)據(jù)庫中,只要屬性同命名字段匹配。下面是一個示例對象,以及如何將它插入到數(shù)據(jù)庫中的示例:
01 # a simple object
02 class person {
03 ? ?public $name;
04 ? ?public $addr;
05 ? ?public $city;
06
07 ? ?function __construct($n,$a,$c) {
08 ? ? ? ?$this-name = $n;
09 ? ? ? ?$this-addr = $a;
10 ? ? ? ?$this-city = $c;
11 ? ?}
12 ? ?# etc ...
13 }
14
15 $cathy = new person('Cathy','9 Dark and Twisty','Cardiff');
16
17 # here's the fun part:
18 $STH = $DBH-("INSERT INTO folks (name, addr, city) value (:name, :addr, :city)");
19 $STH-execute((array)$cathy);
通過在執(zhí)行時將對象轉換為數(shù)組,輸將將會同數(shù)組的鍵一樣對待。
連接到一個?url?地址為localhost?、?端口為?3306?的mysql服務器上。mysql服務器的帳號是"root",密碼是"9999"。mysql?服務器上有一個數(shù)據(jù)庫?ok?,?數(shù)據(jù)庫里有一個表?abc。表?abc?一共為兩列,列名分別是?"id"?和?"name"?,將?abc?里的所有數(shù)據(jù)讀出來。
??
$dbh?=?@mysql_connect("localhost:3306","root","9999");?
/*?定義變量dbh?,?mysql_connect()函數(shù)的意思是連接mysql數(shù)據(jù)庫,?"@"的意思是屏蔽報錯?*/?
if(!$dbh){die("error");}?
/*?die()函數(shù)的意思是將括號里的字串送到瀏覽器并中斷PHP程式?(Script)。括號里的參數(shù)為欲送出的字串。?*/?
@mysql_select_db("ok",?$dbh);?
/*?選擇mysql服務器里的一個數(shù)據(jù)庫,這里選的數(shù)據(jù)庫名為?ok?*/?
$q?=?"SELECT?*?FROM?abc";?
/*?定義變量q,?"SELECT?*?FROM?abc"是一個SQL語句,意思是讀取表abc中的數(shù)據(jù)?*/?
??
br?/?
!--=========?方法一?=========--?
br?/?
??
$rs?=?mysql_query($q,?$dbh);?
/*?定義變量?rs?,函數(shù)mysql_query()的意思是:送出?query?字串供?MySQL?做相關的處理或者執(zhí)行.由于php是從右往左執(zhí)行的,所以,rs的值是服務器運行mysql_query()函數(shù)后返回的值?*/?
if(!$rs){die("Valid?result!");}?
echo?"table";?
echo?"trtdID/tdtdName/td/tr";?
while($row?=?mysql_fetch_row($rs))?echo?"trtd$row[0]/tdtd$row[1]/td/tr";?
/*?定義量變(數(shù)組)row,并利用while循環(huán),把數(shù)據(jù)一一寫出來.??
函數(shù)mysql_fetch_row()的意思是:將查詢結果$rs單列拆到陣列變數(shù)中.??
$row[0]?和?$row[1]?的位置可以換*/?
echo?"/table";?
??
br?/?
!--=========?方法二?=========--?
br?/?
??
$rs?=?mysql_query($q,?$dbh);?
while($row?=?mysql_fetch_object($rs))?echo?"$row-id?$row-name?br?/";?
/*?id和name可以換位置?*/?
??
br?/?
!--=========?方法三?=========--?
br?/?
??
$rs?=?mysql_query($q,?$dbh);?
while($row?=?mysql_fetch_array($rs))?echo?"$row[id]?$row[name]?br?/";?
/*?id和name可以換位置?*/?
??
!--=========?方法三最快?=========--?
??
@mysql_close($dbh);?
/*?關閉到mysql數(shù)據(jù)庫的連接?*/?
?