日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

php memcached mysql_PHP Memcached使用详解

發(fā)布時(shí)間:2024/4/18 数据库 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php memcached mysql_PHP Memcached使用详解 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

翻譯爛到家了,看不順眼輕噴。。。 1.為什么要使用PDO? mysql_函數(shù)已經(jīng)過(guò)時(shí),相當(dāng)一段時(shí)間以來(lái),mysql_函數(shù)在其他SQL數(shù)據(jù)庫(kù)編程接口方面已經(jīng)有所差別;它不支持預(yù)處理,存儲(chǔ)過(guò)程,事務(wù)等一些現(xiàn)代數(shù)據(jù)庫(kù)設(shè)計(jì)思想,SQL語(yǔ)句字符串轉(zhuǎn)義函數(shù) mysql_real_escape_s

翻譯爛到家了,看不順眼輕噴。。。

1.為什么要使用PDO?

mysql_*函數(shù)已經(jīng)過(guò)時(shí),相當(dāng)一段時(shí)間以來(lái),mysql_*函數(shù)在其他SQL數(shù)據(jù)庫(kù)編程接口方面已經(jīng)有所差別;它不支持預(yù)處理,存儲(chǔ)過(guò)程,事務(wù)等一些現(xiàn)代數(shù)據(jù)庫(kù)設(shè)計(jì)思想,SQL語(yǔ)句字符串轉(zhuǎn)義函數(shù) mysql_real_escape_string() 和 拼接SQL語(yǔ)句的編程方法 已經(jīng)過(guò)時(shí)并且很容易出錯(cuò)。最近一段時(shí)間里,它缺乏開(kāi)發(fā)者的關(guān)注,缺少維護(hù)將可能導(dǎo)致一些安全問(wèn)題不能被即時(shí)修復(fù),或者在適配新版本的MySQL的時(shí)候不能正常工作,這成為mysql_*函數(shù)面臨的的另一個(gè)問(wèn)題。PHP社區(qū)最近也對(duì)mysql_*函數(shù)給出不建議使用的建議,也有可能在未來(lái)的版本中最終被棄用(不過(guò)不用過(guò)于擔(dān)心,這可能還需要很長(zhǎng)一段時(shí)間)。

PDO擁有更好的編程接口,你可以使用它寫(xiě)出更加簡(jiǎn)潔,高效,安全的代碼。PDO還為不同的SQL數(shù)據(jù)庫(kù)提供了不同的驅(qū)動(dòng),方便你使用新的數(shù)據(jù)庫(kù)而不用再學(xué)習(xí)不同的編程接口。與拼接SQL語(yǔ)句構(gòu)造查詢語(yǔ)句不同,綁定參數(shù)可以簡(jiǎn)潔方便的構(gòu)造出更加安全的查詢語(yǔ)句,使用綁定參數(shù)的方法在 多次相似語(yǔ)句查詢(僅僅某個(gè)參數(shù)不同)中也可以提高不少性能。PDO在錯(cuò)誤處理方面也提供了多種方法。mysql_*函數(shù)缺乏一致的處理,與PDO的異常模式相比,或者說(shuō)沒(méi)有處理異常,使用PDO,你可以得到一致的錯(cuò)誤處理,這將節(jié)省您大量的時(shí)間來(lái)跟蹤問(wèn)題。

在當(dāng)前的PHP版本中,PDO模塊是默認(rèn)安裝啟用的,但是在使用PDO前你還需要安裝另外兩個(gè)軟件包,一個(gè)是pdo_mysql數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序,另外一個(gè)是類似php-mysql的mysql驅(qū)動(dòng)程序。

2.連接MySQL

以前的方式:

$link = mysql_connect('localhost', 'user', 'pass');

mysql_select_db('testdb', $link);

mysql_set_charset('UTF-8', $link);

新的方式:

* 創(chuàng)建一個(gè)PDO對(duì)象,參數(shù)包括 DSN, username, password 和 一個(gè)驅(qū)動(dòng)選項(xiàng)的數(shù)組(可忽略)。

* DSN其實(shí)就是一個(gè)告訴PDO該使用哪一種數(shù)據(jù)庫(kù)驅(qū)動(dòng) 和 一些連接信息的字符串,了解更多 PDO MYSQL DSN .

$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'password');

注意:確保DSN中設(shè)置了字符編碼信息,否則將可能返回字符編碼設(shè)置錯(cuò)誤的信息,出于安全考慮,DSN最好包括字符編碼信息設(shè)置。

你也可以在第四個(gè)參數(shù)數(shù)組里填寫(xiě)一些驅(qū)動(dòng)選項(xiàng),建議將 PDO異常模式(下文講解) 和 關(guān)閉預(yù)處理模擬(默認(rèn)打開(kāi)的,僅對(duì)于舊版本MySQL有用)兩個(gè)參數(shù)加入到第四個(gè)參數(shù)數(shù)組中。

$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'password', array(PDO::ATTR_EMULATE_PREPARES => false,PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));

你也可以在創(chuàng)建PDO對(duì)象后再通過(guò)setAttribute方法設(shè)置相應(yīng)選項(xiàng)。

$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'password');

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

3.錯(cuò)誤處理

mysql_*函數(shù)的錯(cuò)誤處理

//connected to mysql

$result = mysql_query("SELECT * FROM table", $link) or die(mysql_error($link));

OR die()是個(gè)不錯(cuò)的錯(cuò)誤處理方法,但是會(huì)因此結(jié)束頁(yè)面,將錯(cuò)誤信息呈現(xiàn)到用戶面前,這可能是我們不想看到的結(jié)果。

PDO有三種錯(cuò)誤處理模式:

PDO::ERRMODE_SILENT # 和 mysql_*函數(shù)類似,檢查代碼并查看 $db->errorInfo(); 獲取詳細(xì)信息。

PDO::ERRMODE_WARNING # 拋出PHP警告。

PDO::ERRMODE_EXCEPTION #拋出 PDOException 異常,在我認(rèn)為,這是我們應(yīng)該使用的模式, 這和 die(mysql_error()); 類似,但是它可以捕獲并拋出具體異常信息。

code:

try {

//connect as appropriate as above

$db->query('hi'); //invalid query!

} catch(PDOException $ex) {

echo "An Error occured!"; //user friendly message

some_logging_function($ex->getMessage());

}

注意:你可以不用立即執(zhí)行并捕獲異常,你可以在任何合適的時(shí)候隨時(shí)捕獲。

function getData($db) {

$stmt = $db->query("SELECT * FROM table");

return $stmt->fetchAll(PDO::FETCH_ASSOC);

}

//then much later

try {

getData($db);

} catch(PDOException $ex) {

//handle me.

}

如果你不想使用try/catch來(lái)處理異常,就像使用OR die()那樣處理,在production模式下關(guān)閉display_errors選項(xiàng)即可。

4.簡(jiǎn)單的查詢語(yǔ)句(SELECT)

mysql_*代碼:

$result = mysql_query('SELECT * from table') or die(mysql_error());

$num_rows = mysql_num_rows($result);

while($row = mysql_fetch_assoc($result)) {

echo $row['field1'].' '.$row['field2']; //etc...

}

PDO代碼:

foreach($db->query('SELECT * FROM table') as $row) {

echo $row['field1'].' '.$row['field2']; //etc...

}

query() 方法返回了一個(gè) PDOStatement 對(duì)象,你可以通過(guò)如下方法獲取結(jié)果:

$stmt = $db->query('SELECT * FROM table');

while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {

echo $row['field1'].' '.$row['field2']; //etc...

}

或者

$stmt = $db->query('SELECT * FROM table');

$results = $stmt->fetchAll(PDO::FETCH_ASSOC);

//use $results

# Fetch Modes

注意 fetch() 和 fetchAll() 代碼中的PDO::FETCH_ASSOC ,它高速 PDO 以關(guān)聯(lián)數(shù)組的形式返回 鍵,值;其他比如PDO::FETCH_NUM模式,則返回?cái)?shù)值鍵值的數(shù)組,默認(rèn)模式是 PDO::FETCH_BOTH 則返回前面兩者的集合,既有數(shù)值鍵值的數(shù)組,又有關(guān)聯(lián)數(shù)組。PDO也可以獲取數(shù)據(jù)返回對(duì)象PDO::FETCH_OBJ,PDO::FETCH_CLASS,PDO::FETCH_BOUND,bindColumn方法等更多內(nèi)容,請(qǐng)閱讀: PDOStatement Fetch documentation。

# 獲取數(shù)據(jù)行數(shù)(Getting Row Count)

代替 mysql_num_rows 方法,你可以使用 PDOStatement對(duì)象的rowCount();方法。

$stmt = $db->query('SELECT * FROM table');

$row_count = $stmt->rowCount();

echo $row_count.' rows selected';

注意:官方文檔稱此函數(shù)僅適用于返回 `UPDATE`, `INSERT`, `DELETE`操作的`affected rows`,而 `SELECT`操作,僅對(duì)于`PDO_MYSQL` 驅(qū)動(dòng),此函數(shù)同樣適用(謹(jǐn)記),在操作其他數(shù)據(jù)庫(kù)的時(shí)候尤其注意。

# 獲取最后操作ID(Getting the Last Insert Id)

mysql_*代碼:

$result = mysql_query("INSERT INTO table(firstname, lastname) VALUES('John', 'Doe')") or die("Insert Failed ".mysql_error());

$insert_id = mysql_insert_id();

PDO代碼:

$result = $db->exec("INSERT INTO table(firstname, lastname) VAULES('John', 'Doe')");

$insertId = $db->lastInsertId();

5.執(zhí)行 INSERT, UPDATE, DELETE 操作

mysql_*代碼:

$results = mysql_query("UPDATE table SET field='value'") or die(mysql_error());

$affected_rows = mysql_affected_rows($result);

echo $affected_rows.' were affected';

PDO代碼:

$affected_rows = $db->exec("UPDATE table SET field='value'");

echo $affected_rows.' were affected'

DELETE , INSERT 操作同樣適用。

6.運(yùn)行帶有查詢參數(shù)的語(yǔ)句(Running Statements With Parameters)

對(duì)于 不攜帶任何參數(shù)的查詢語(yǔ)句,我們可以使用 query方法處理SELECT操作,使用exec方法處理 INSERT,UPDATE,INSERT操作,而對(duì)于攜帶查詢參數(shù)的語(yǔ)句,你應(yīng)該使用綁定參數(shù)的方法來(lái)安全的處理這些操作。

mysql_*代碼:

$results = mysql_query(sprintf("SELECT * FROM table WHERE id='%s' AND name='%s'",

mysql_real_escape_string($id), mysql_real_escape_string($name))) or die(mysql_error());

$rows = array();

while($row = mysql_fetch_assoc($results)){

$rows[] = $row;

}

PDO代碼:

$stmt = $db->prepare("SELECT * FROM table WHERE id=? AND name=?");

$stmt->execute(array($id, $name));

$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

prepare方法將查詢語(yǔ)句發(fā)送到服務(wù)器,以“?”作為參數(shù)占位符進(jìn)行編譯,execute方法將查詢參數(shù)發(fā)送到服務(wù)器,運(yùn)行之前編譯好的查詢語(yǔ)句。因?yàn)?查詢語(yǔ)句 和 查詢參數(shù) 是分開(kāi)發(fā)送的,所以在參數(shù)里的SQL語(yǔ)句是不可能被執(zhí)行的,所以不會(huì)發(fā)生 SQL注入,這是一種比連接字符串構(gòu)造SQL語(yǔ)句更加安全的解決方法。

注意:當(dāng)你使用**綁定參數(shù)**的時(shí)候,不要對(duì)"?"占位符使用引號(hào)(SQL語(yǔ)句原來(lái)是對(duì)參數(shù)使用引號(hào)的),因?yàn)閰?shù)類型是在execute方法的時(shí)候確定的,所以在prepare的時(shí)候不必對(duì)占位符使用引號(hào)。

還有一些綁定參數(shù)的方法,bindValue方法可以分別綁定每個(gè)參數(shù)來(lái)代替execute方法的數(shù)組方式,同時(shí)還分別設(shè)置每個(gè)參數(shù)的類型。

$stmt = $db->prepare("SELECT * FROM table WHERE id=? AND name=?");

$stmt->bindValue(1, $id, PDO::PARAM_INT);

$stmt->bindValue(2, $name, PDO::PARAM_STR);

$stmt->execute();

$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

#命名占位符

如果你有許多參數(shù)需要綁定,不要使用問(wèn)號(hào)占位符,以防混淆出錯(cuò),你可以使用命名占位符代替問(wèn)號(hào)占位符。

$stmt = $db->prepare("SELECT * FROM table WHERE id=:id AND name=:name");

$stmt->bindValue(':id', $id, PDO::PARAM_INT);

$stmt->bindValue(':name', $name, PDO::PARAM_STR);

$stmt->execute();

$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

你也可以使用execute方法,以數(shù)組的方式綁定參數(shù):

$stmt = $db->prepare("SELECT * FROM table WHERE id=:id AND name=:name");

$stmt->execute(array(':name' => $name, ':id' => $id));

$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

#INSERT, DELETE, UPDATE 預(yù)處理查詢

INSERT, DELETE, UPDATE 預(yù)處理語(yǔ)句的使用和SELECT類似,我們舉幾個(gè)例子:

$stmt = $db->prepare("INSERT INTO table(field1,field2,field3,field4,field5) VALUES(:field1,:field2,:field3,:field4,:field5)");

$stmt->execute(array(':field1' => $field1, ':field2' => $field2, ':field3' => $field3, ':field4' => $field4, ':field5' => $field5));

$affected_rows = $stmt->rowCount();

$stmt = $db->prepare("DELETE FROM table WHERE id=:id");

$stmt->bindValue(':id', $id, PDO::PARAM_STR);

$stmt->execute();

$affected_rows = $stmt->rowCount();

$stmt = $db->prepare("UPDATE table SET name=? WHERE id=?");

$stmt->execute(array($name, $id));

$affected_rows = $stmt->rowCount();

#在預(yù)處理中使用SQL函數(shù)

無(wú)效方法:

//THIS WILL NOT WORK!

$time = 'NOW()';

$name = 'BOB';

$stmt = $db->prepare("INSERT INTO table(`time`, `name`) VALUES(?, ?)");

$stmt->execute(array($time, $name));

正確方法

$name = 'BOB';

$stmt = $db->prepare("INSERT INTO table(`time`, `name`) VALUES(NOW(), ?)");

$stmt->execute(array($name));

你也可以在SQL函數(shù)里綁定參數(shù):

$name = 'BOB';

$password = 'badpass';

$stmt = $db->prepare("INSERT INTO table(`hexvalue`, `password`) VALUES(HEX(?), PASSWORD(?))");

$stmt->execute(array($name, $password));

但是不能作為L(zhǎng)IKE的參數(shù):

//THIS DOES NOT WORK

$stmt = $db->prepare("SELECT field FROM table WHERE field LIKE %?%");

$stmt->bindParam(1, $search, PDO::PARAM_STR);

$stmt->execute();

正確使用LIKE并綁定參數(shù)的方法:

$stmt = $db->prepare("SELECT field FROM table WHERE field LIKE ?");

$stmt->bindValue(1, "%$search%", PDO::PARAM_STR);

$stmt->execute();

注意:這里使用的是bindValue而不是bindParam,否則會(huì)發(fā)生PDOException或致命錯(cuò)誤。

#使用循環(huán)運(yùn)行預(yù)處理語(yǔ)句

預(yù)處理語(yǔ)句可以一次設(shè)置,多次調(diào)用,因?yàn)閮H在第一次傳入的時(shí)候編譯,因此在后來(lái)的多次調(diào)用中提高了不少效率。

典型的應(yīng)用就是bindParam,bindParam與bindValue的不同之處在于,它不是綁定了參數(shù)的值,而是綁定參數(shù)變量本身,因此,如果參數(shù)變量變化了,那么在execute處理的時(shí)候,查詢也將相應(yīng)變化。

$values = array('bob', 'alice', 'lisa', 'john');

$name = '';

$stmt = $db->prepare("INSERT INTO table(`name`) VALUES(:name)");

$stmt->bindParam(':name', $name, PDO::PARAM_STR);

foreach($values as $name) {

$stmt->execute();

}

6.PDO中的事務(wù)(Transactions)

注意:調(diào)用beginTransaction()方法即自動(dòng)關(guān)閉了自動(dòng)提交。

try {

$db->beginTransaction();

$db->exec("SOME QUERY");

$stmt = $db->prepare("SOME OTHER QUERY?");

$stmt->execute(array($value));

$stmt = $db->prepare("YET ANOTHER QUERY??");

$stmt->execute(array($value2, $value3));

$db->commit();

} catch(PDOException $ex) {

//Something went wrong rollback!

$db->rollBack();

echo $ex->getMessage();

}

原文鏈接:PDO Tutorial for MySQL Developers

參考鏈接:PDO Documentation

延伸閱讀:Validation and SQL Injection

總結(jié)

以上是生活随笔為你收集整理的php memcached mysql_PHP Memcached使用详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。