亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

(唯一合適) PDO 教程

sf190404 / 1688人閱讀

摘要:是什么首先思考為什么選擇是一個數(shù)據(jù)訪問抽象層抽象是雙重的一個是眾所周知但不太重要的另一個是模糊的但是是最重要的眾所周知為不同的數(shù)據(jù)庫提供了統(tǒng)一的接口雖然這個功能本身很龐大但是對于固定程序來說不是過于重要的事情基本所有的程序都是使用統(tǒng)一的后端

PDO是什么

首先思考, 為什么選擇PDO

PDO 是一個數(shù)據(jù)訪問抽象層(Database Access Abstraction Layer). 抽象是雙重的: 一個是眾所周知但不太重要的. 另一個是模糊的但是是最重要的.
眾所周知 PDO 為不同的數(shù)據(jù)庫提供了統(tǒng)一的接口. 雖然這個功能本身很龐大, 但是對于固定程序來說不是過于重要的事情, 基本所有的程序都是使用統(tǒng)一的后端數(shù)據(jù)庫. 盡管有一些謠言, 但是通過改變單行 PDO 配置來切換后端數(shù)據(jù)庫是不可能的-由于不同的 SQL 風(fēng)格(為此, 需要使用像 DQL 這樣的平均查詢語言). 因此對于普通的 LAMP 開發(fā)者來說, 這一點是微不足道的, 并且對他而言, PDO只是熟悉的 mysql(i)_query() 函數(shù)的另一個更復(fù)雜版本. 但實際上它不是, 它有豐富的其他功能.
PDO 不僅抽象了數(shù)據(jù)庫API, 還抽象了基本操作, 否則必須在每個應(yīng)用程序中重復(fù)數(shù)百次, 使您的代碼非常WET. 不同于 mysqlmysqli , 兩個都不能直接使用低級裸 APIs(但僅作為某些更高級別抽象層的構(gòu)建材料), PDO就是這樣的抽象. 雖然仍是不完整的, 但是至少可用.
真正的PDO好處是:

安全性 (可用的準備語句)

可用性 (許多輔助函數(shù)可以自動執(zhí)行日常操作)

可重用性 (用于訪問大量數(shù)據(jù)庫的統(tǒng)一API, 從SQLITE到oracle)

請注意, 盡管 PDO 是原生數(shù)據(jù)庫驅(qū)動程序中最好的, 但對于現(xiàn)代WEB應(yīng)用程序來說, 請考慮將使用有查詢構(gòu)建器的 ORM 或者與其他更高抽象級別的庫一起使用, 只是偶爾使用原生的PDO. 好的ORM比如 Doctrine, Eloquent, RedBeanYii::AR. Aura.SQL 是具有很多附加功能的使用PDO包裝器的一個很好的例子.
無論哪種方式, 首先要了解基本工具是件好事. 那么, 讓我們開始吧:

connection DSN

PDO有一個叫 DSN 的預(yù)想接方式. 它并不復(fù)雜-PDO需要你在三個不同的位置輸入不同的配置, 而不是一個簡單的選項列表.

database driver, host, db(schema) namecharset, 以及不常使用的 portunix_socket 設(shè)置 DSN

user_namepassword 設(shè)置構(gòu)造方法

其他所有的配置在options數(shù)組

其中 DSN 是以分號分隔的字符串, 由 param=value 鍵值對組成, 從驅(qū)動程序名稱和冒號開始:

    mysql:host=localhost;dbname=test;port=3306;charset=utf8mb4
driver^  ^colon           ^param=value pair   ^semicolon

注意, 遵循正確的格式是非常重要的- DSN中不能使用 空格, 引號, 和其他的符號, 只能使用參數(shù), 值和定界符. 就像手冊上展示的.

這里有一個例子:

$host = "127.0.0.1";
$db = "test";
$pass = "root";
$charset = "utf8mb4";

$dsn = "mysql:host={$host};dbnamej={$db};charset={$charset}";
$options = [
    PDO::ATR_ERRMODE => PDO::ERRMODE_EXECPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false,
];
try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
}

設(shè)置了所有上述變量屬性, 我們將在 $pdo 變量中得到一個正確的 PDO 實例.
使用舊mysql擴展用戶重要通知

不同于 mysql_* 函數(shù), 可以在代碼的任意位置使用, pdo 實例被存儲在一個變量中, 那就意味著只能在函數(shù)內(nèi)部進行訪問. 因此, 必須通過函數(shù)參數(shù)傳遞或使用更高級的技術(shù), 比如IOC容器.

連接只用創(chuàng)建一次. 不要在函數(shù), 類構(gòu)造函數(shù)創(chuàng)建連接, 否則, 會創(chuàng)建多個連接, 最終導(dǎo)致數(shù)據(jù)庫服務(wù)宕機. 因此必須創(chuàng)建唯一的 PDO 實例, 讓整個腳本使用.(適用于FPM模式)

通過DSN設(shè)置字符集是非常重要的-這是唯一正確的方式因為它會告訴PDO哪個字符集會被使用. 因此, 忘記通過 Query 運行SET NAMES 或者通過 PDO::MYSQL_ATTR_INIT_COMMAND. 只有當PHP版本過低時(低于5.3.6), 才可以使用 SET NAMES 查詢, 并且關(guān)閉仿真模式.

更多關(guān)于連接的內(nèi)容可以在 連接MySQL查看

運行查詢 PDO::query()

使用 PDO 有兩種方式運行查詢. 如果查詢中沒有使用變量, 可以使用 PDO::query 方法. 它會運行查詢并返回一個 PDOStatement 類的對象, 該類與 mysql_query 返回的資源大致相同, 特別時從中獲取實際記錄的操作:

$stmt = $pdo->query("SELECT name FROM users");
while ($row = $stmt->fetch()) {
    echo $row["name"] . "
";
}

并且 query() 方法允許我們使用一個整潔的方法連接 SELECT 查詢, 如下所示.

預(yù)處理, 防止SQL注入

放棄熟悉的 mysql_query()函數(shù) 并進入嚴格數(shù)據(jù)對象領(lǐng)域的主要原因是 PDO 已經(jīng)準備好了開箱即用的預(yù)處理語句. 如果要在語句中使用變量, 預(yù)處理語句是唯一正確運行的方式. 它如此重要的原因在 The Hitchhiker"s Guide to SQL Injection prevention.有詳細的解釋.
對于運行的查詢, 如果至少使用一個變量, 你必須使用占位符替換它. 準備執(zhí)行語句, 然后分別傳入變量執(zhí)行.
長話短說, 它不像感覺的那么困難. 在大多數(shù)例子中, 你只需要使用函數(shù) prepareexecute .
首先, 需要修改查詢, 在使用變量的位置添加占位符, 就像這樣

$sql = "SELECT * FROM users WHERE email = "{$email}" AND status = "{$status}"";

改為

$sql = "SELECT * FROM users where email = ? and status = ?";

或者

$sql = "SELECT * FROM users where email = :email AND status = :status";

注意 PDO 支持位置(?)和命名(:email)占位符, 后者始終以冒號開始,并且只能使用字母, 數(shù)字和下劃線. 還需要注意 占位符周圍不能使用引號 .
一個查詢使用了占位符, 就必須使用PDO::prepare()方法預(yù)處理. 這個方法返回一個和我們上邊討論的相同的 PDOStatement 對象, 但是沒有綁定任何數(shù)據(jù).
最后, 必須使用 PDOStatement 對象的 execute() 方法執(zhí)行查詢, 并且通過數(shù)組形式傳遞參數(shù). 之后, 就可以從語句中得到結(jié)果數(shù)據(jù)(如果適用).

$stmt = $pdo->prepare("SELECT * FROM users WHERES email = ? AND status = ?");
$stmt->execute([$email, $status])
$user = $stmt->fetch();

// or
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email AND status = :status");
$stmt->execute(["email" => $email, "status" => $status]);
$user = $stmt->fetch();

可以看到, 位置占位符, 你需要提供一個索引數(shù)組. 命名占位符, 需要提供一個關(guān)聯(lián)數(shù)組, 并且鍵要匹配查詢中的占位符. 同一個查詢中不能混合位置占位符和命名占位符.
位置占位符可以讓你寫更簡短的代碼, 但是對參數(shù)順序是敏感的(必須于查詢中參數(shù)的順序一致). 雖然命名占位符使代碼更冗長, 但是允許隨機參數(shù)綁定.
另外需要注意, 雖然存在普遍的誤解, 但是數(shù)組鍵中 : 不是必須的.
執(zhí)行后就可以使用支持的方法獲取結(jié)果.

更多的例子可以查看(respective article)[https://phpdelusions.net/pdo_...].

參數(shù)綁定

將數(shù)據(jù)傳入 execute() (如上所示)方法中應(yīng)被視為默認的最方便的方式. 如果使用這個方法, 所有參數(shù)都將會綁定為字符串(如果使用NULL值, 將會使用SQL NULL發(fā)送給查詢), 大多數(shù)時候都沒有問題.
但是, 有時候最好明確設(shè)置類型. 可能情況如下:

開啟仿真模式的 LIMIT 子句(或者其他不能接受字符串操作數(shù)的 SQL 子句)

可能受到錯誤操作數(shù)類型影響具有特殊查詢計劃的復(fù)雜特殊查詢

特有的列類型, 像 bigint boolean 必須綁定精確的操作數(shù)(為了將 BIGINT 綁定為 PDO::PARAM_INT 需要基于 mysqlnd)

這種情況下, 必須使用顯式綁定, 可以從 bindvalue()bindParam() 兩個函數(shù)中選擇一個. 前者是推薦使用的, 它不像 bindParam()具有一定的副作用.

查詢可以綁定的部分

了解哪些查詢部分可以使用參數(shù)綁定哪些部分不能使用是非常重要的. 事實上, 這個列表是非常短的: 只有字符串和數(shù)字字面量可以被綁定. 只要你的數(shù)據(jù)在查詢中能被表示為數(shù)字或者帶引號的字符串, 就可以被綁定. 其他所有情況你不能使用 PDO 預(yù)處理語句: 既不是標識符也不是逗號分隔列表, 或者是引用的文字字符串的一部分, 或者其他任意查詢部分都不能使用預(yù)準備語句綁定
最常見的用例解決方案可以在[本章的響應(yīng)部分查看]()

預(yù)處理, 多次執(zhí)行

有時候你可以使用預(yù)處理多次執(zhí)行準備好的查詢, 比一次又一次執(zhí)行相同的查詢快一點, 因為它只解析查詢一次. 如果可以執(zhí)行另一個PHP實例中的預(yù)處理語句, 這個功能就是非常有用的, 但是事實并非如此. 只會在同一個實例中重復(fù)相同的查詢, 這在常規(guī)的PHP腳本中很少使用到, 并限制了此功能用于重復(fù)插入和更新.

$data = [
    1 => 1000,
    2 => 200,
    3 => 200,
];
$stmt = $pdo->prepare("UPDATE users SET bonus = bonus + ? where id = ?");
foreach ($data as $id => $bonus) {
    $stmt->execute([$bonus, $id]);
}

注意這個功能有點被高估了. 不僅需要討論, 而且性能提升也不是很大 - 查詢解析有時候是
很快的. 而且只有在關(guān)閉仿真模式的時候才能帶來性能提升.

運行SELECT INSERT UPDATE DELETE語句

這些查詢沒有什么特別之處, 對PDO來說他們都是一樣的. 運行哪個查詢并不重要.
如上所示, 需要準備帶有占位符的預(yù)處理查詢, 傳入變量并執(zhí)行. DELETESELECT 的處理過程是基本相同的. 僅有的不同點是( DML查詢不會返回任何數(shù)據(jù)), 你可以使用鏈式方法, 調(diào)用 execute()prepare().

$sql = "UPDATE users SET name = ? where id = ?";
$pdo->prepare($sql)->execute([$name, $id]);

然而, 你像獲得影響行數(shù), 代碼將和無聊的三行代碼相同:

$stmt = $pdo->prepare("DELETE FROM goods where category = ?");
$stmt->execute([$cat]);
$deleted = $stmt->rowCount();

更多的例子可以在respective article.找到.

從statement獲取數(shù)據(jù) foreach

我們已經(jīng)見過這個函數(shù)了, 現(xiàn)在讓我們仔細看看. 它從數(shù)據(jù)庫獲取單行數(shù)據(jù), 在結(jié)果集中移動內(nèi)部指針, 因此, 對函數(shù)的后續(xù)調(diào)用將逐個返回所有行. 這個方法和 mysql_fetch_array() 大致相同但在工作模式稍微有點不同: 代替很多不同函數(shù)( mysql_fetch_assoc() mysql_fetch_row), 這個只有一個方法, 但是它的行為可以通過一個參數(shù)改變. 在 PDO 中有很多的獲取模式, 稍后我們詳細討論, 這里有一些簡單的實例:

PDO::FETCH_NUM 返回索引數(shù)組

PDO::FETCH_ASSOC 返回關(guān)聯(lián)數(shù)組

PDO::FETCH_BOTH 以上兩者都包含

PDO::FETCH_OBJ 返回對象

PDO::FETCH_LAZY 允許三個(索引數(shù)組, 關(guān)聯(lián)數(shù)組, 對象)方法沒有內(nèi)存開銷.

從上面可以看出, 這個必須在兩種情況下使用:

當只需要一行時, 只獲取一行

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

將以關(guān)聯(lián)數(shù)組的方式從語句中獲取一行

當我們需要在使用之前處理返回數(shù)據(jù). 在這種情況下, 必須通過while循環(huán)運行, 如上所示.

另一種有用的模式是 PDO::FETCH_CLASS 可以創(chuàng)建一個特定類的對象

$news = $pdo->query("select * from news")->fetchAll(PDO::FETCH_CLASS, "News");

將生成一個News類對象的數(shù)組, 并且通過返回值設(shè)置類屬性. 注意這個模式下:

屬性會在構(gòu)造方法之前設(shè)置

所有未定義的屬性都會調(diào)用 __set魔術(shù)方法

如果沒有 __set方法, 將會創(chuàng)建新屬性

私有屬性也會被設(shè)置, 這有點意外但是非常方便

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/31055.html

相關(guān)文章

  • 我感覺這是史上最牛的防sql注入方法類

    摘要:早在年我就開始寫這個類庫了,平時在工作中,將一些好的想法,一些問題的解決方法等融合進來,歷時兩年多,經(jīng)過不斷的實踐,我感覺它已經(jīng)很成熟了,于是它來到了你面前我的倉庫地址這里假設(shè)有一個數(shù)據(jù)表,其中為主鍵。 早在2015年我就開始寫這個PHP類庫了,平時在工作中,將一些好的想法,一些問題的解決方法等融合進來,歷時兩年多,經(jīng)過不斷的實踐,我感覺它已經(jīng)很成熟了,于是它來到了你面前! 我的倉庫地...

    dockerclub 評論0 收藏0
  • 使用SAE和Gitcafe開發(fā)網(wǎng)站應(yīng)用

    摘要:原文使用和開發(fā)網(wǎng)站應(yīng)用在領(lǐng)域目前看來新浪云走的比較早,也比較成熟。新浪云需要使用新浪微博的帳號才能登錄和使用。目前,新浪云需要進行實名認證才能創(chuàng)建個以上的應(yīng)用,所以推薦進行實名認證。 原文:使用SAE和Gitcafe開發(fā)網(wǎng)站應(yīng)用 在PaaS領(lǐng)域目前看來新浪云走的比較早,也比較成熟。相比IaaS,PaaS更能為企業(yè)或個人帶來成本上的節(jié)約。本文以php為例,記錄了如何在新浪云上注冊創(chuàng)建自...

    liuhh 評論0 收藏0
  • PHP-X 系列教程:內(nèi)置函數(shù)的使用

    摘要:本文主要介紹內(nèi)置函數(shù)的使用,在擴展開發(fā)中,會經(jīng)常用到這些內(nèi)置函數(shù),的封裝,使得調(diào)用這些函數(shù)像代碼一樣簡單。的使用方法與語言的是完全一致的。包括的超全局變量和其他代碼使用關(guān)鍵詞聲明的全局變量。 本文主要介紹PHP-X內(nèi)置函數(shù)的使用,在PHP擴展開發(fā)中,會經(jīng)常用到這些內(nèi)置函數(shù),PHP-X的封裝,使得調(diào)用這些函數(shù)像PHP代碼一樣簡單。 echo 在擴展中需要輸出一些內(nèi)容,可以使用echo函數(shù)...

    _Zhao 評論0 收藏0
  • yii過濾xss代碼,防止sql注入教程

    摘要:好啦,我們看看在框架的不同版本中是怎么處理攻擊,注入等問題的。那要是,又是怎樣處理的喃考慮目前國內(nèi)網(wǎng)站大部分采集文章十分頻繁,更有甚者不注明原文出處,原作者更希望看客們查看原文,以防有任何問題不能更新所有文章,避免誤導(dǎo)繼續(xù)閱讀 作者:白狼 出處:http://www.manks.top/yii2_filter_xss_code_or_safe_to_database.html 本文版權(quán)...

    Shonim 評論0 收藏0
  • 寫一個“特殊”的查詢構(gòu)造器 - (前言)

    摘要:而在項目開發(fā)中,我們想要的是一個更好用的可維護的工具,此時,對代碼的封裝模塊化就顯得尤為重要,于是出現(xiàn)了兩種方案查詢構(gòu)造器,對象關(guān)系映射。典型環(huán)境下按照一般的查詢構(gòu)造器處理就行。 文章目錄 寫一個特殊的查詢構(gòu)造器 - (前言) 寫一個特殊的查詢構(gòu)造器 - (一、程序結(jié)構(gòu),基礎(chǔ)封裝) 寫一個特殊的查詢構(gòu)造器 - (二、第一條語句) 寫一個特殊的查詢構(gòu)造器 - (三、條件查詢) 寫一個特殊...

    GitChat 評論0 收藏0

發(fā)表評論

0條評論

sf190404

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<