溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PDO與MySQLi各自優勢及該如何選擇

發布時間:2020-06-03 13:45:00 來源:PHP中文網 閱讀:543 作者:三月 欄目:編程語言

下文主要給大家帶來PDO與MySQLi各自優勢及該如何選擇,希望這些內容能夠帶給大家實際用處,這也是我編輯PDO與MySQLi各自優勢及該如何選擇這篇文章的主要目的。好了,廢話不多說,大家直接看下文吧。

PDO的優勢

1.有用的獲取方式

2.允許直接將變量和值傳遞給execute

3.能夠自動檢測變量類型(實際發生的情況是,發送到云服務器時,所有內容都被視為字符串,但被轉換為正確的類型。這在預處理語句中100%有效,但在某些邊緣情況下無效,比如在模擬模式中。)

4.提供一個選項,使用預處理語句自動緩沖結果

5.命名參數(盡管在PDO中關閉模擬模式是無用的,因為你只能使用相同的名稱一次)

MySQLi優勢

1.異步查詢

2.獲取有關受影響行的更多信息的能力,比如更新具有相同值的行(可以在PDO中作為構造函數設置完成,以后無法更改)

3.正確的數據庫關閉方法

4.一次多個查詢(如果在PDO中打開模擬模式,則可以)

5.使用持久連接自動清除

代碼的差異

PDO和MySQLi非常相似,但是在語法上略有不同。MySQLi遵循舊式的PHP snake_case約定,而PDO使用camelCase。此外,MySQLi的方法被用作對象屬性,而PDO對函數使用傳統語法。

PDO和MySQLi都要求你使用兩個單獨的方法來使用預處理語句,從而使事情變得復雜。不過PDO消除了使用專用綁定函數的需要。

例如,在特定于供應商的PostgreSQL API中,你可以這樣做。

下面是一個示例,演示如何執行一個“non-prepared”查詢來獲取一個包含MySQLi和PDO的關聯數組,以供參考。

$arr = $mysqli->query("SELECT * FROM myTable")->fetch_all(MYSQLI_ASSOC);
$arr = $pdo->query("SELECT * FROM myTable")->fetchAll(PDO::FETCH_ASSOC);

實際上,最好的方法是使用包裝器、查詢生成器或ORM。雖然PDO可以直接將值綁定到execute中,但它仍然不是理想的。在我創建的類中,你可以鏈接所有調用,同時傳入值作為參數參數綁定。

$arr = $mysqli->query("SELECT * FROM myTable WHERE id > ?", [12])->fetchAll('assoc');

現在,在變量中以更簡潔的方式存儲了整個關聯數組。

創建一個新的數據庫連接

PDO

$dsn = "mysql:host=localhost;dbname=myDatabase;charset=utf8mb4";$options = [
  PDO::ATTR_EMULATE_PREPARES   => false, // turn off emulation mode for "real" prepared statements
  PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION, //turn on errors in the form of exceptions
  PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, //make the default fetch be an associative array];try {
  $pdo = new PDO($dsn, "username", "password", $options);} catch (Exception $e) {
  error_log($e->getMessage());
  exit('Something weird happened'); //something a user can understand}

MySQLi

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);try {
  $mysqli = new mysqli("localhost", "username", "password", "databaseName");
  $mysqli->set_charset("utf8mb4");} catch(Exception $e) {
  error_log($e->getMessage());
  exit('Error connecting to database'); //Should be a message a typical user could understand}

插入、更新、刪除

PDO

$stmt = $pdo->prepare("INSERT INTO myTable (name, age) VALUES (?, ?)");
$stmt->execute([$_POST['name'], 29]);
$stmt = null;

MySQLi

$stmt = $mysqli->prepare("UPDATE myTable SET name = ? WHERE id = ?");
$stmt->bind_param("si", $_POST['name'], $_SESSION['id']);
$stmt->execute();
$stmt->close();

注意,使用PDO可以將prepare()和execute()鏈接起來。

獲取受影響的行數

PDO

$stmt->rowCount();

MySQLi

$stmt->affected_rows;

插入最新的主鍵

注意,這兩種方法都使用connection變量,而不是$stmt。

PDO

$pdo->lastInsertId();

MySQLi

$mysqli->insert_id;

得到匹配的行

PDO

在PDO中,實現這一點的唯一方法是將其設置為一個連接選項,以更改rowCount()的行為。這意味著rowCount()將為整個數據庫連接返回匹配的行或更改的行,但不能同時返回兩者。

$options = [
  PDO::MYSQL_ATTR_FOUND_ROWS => true];

MySQLi

$mysqli->info;

這將輸出整個字符串的信息,如:

Rows matched: 1 Changed: 0 Warnings: 0

可以這樣做

preg_match_all('/(\S[^:]+): (\d+)/', $mysqli->info, $matches); 
$infoArr = array_combine ($matches[1], $matches[2]);
var_export($infoArr);

現在可以很容易地訪問這些值。注意,該值是一個字符串,因此你可以將所有值轉換為int,===可以使用,也可以嚴格檢查==。

['Rows matched' => '1', 'Changed' => '0', 'Warnings' => '0']

抓取

獲取關聯數組

PDO

$stmt = $pdo->prepare("SELECT * FROM myTable WHERE id <= ?");
$stmt->execute([5]);
$arr = $stmt->fetchAll(PDO::FETCH_ASSOC);
if(!$arr) exit('No rows');
var_export($arr);
$stmt = null;

MySQLi

$stmt = $mysqli->prepare("SELECT id, name, age FROM myTable WHERE name = ?");
$stmt->bind_param("s", $_POST['name']);
$stmt->execute();
$arr = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
if(!$arr) exit('No rows');
var_export($arr);
$stmt->close();

獲取單行

PDO

$stmt = $pdo->prepare("SELECT id, name, age FROM myTable WHERE name = ?");
$stmt->execute([$_POST['name']]);
$arr = $stmt->fetch(PDO::FETCH_ASSOC);
if(!$arr) exit('No rows');
var_export($arr);
$stmt = null;

MySQLi

$stmt = $mysqli->prepare("SELECT id, name, age FROM myTable WHERE name = ?");
$stmt->bind_param("s", $_POST['name']);
$stmt->execute();
$arr = $stmt->get_result()->fetch_assoc();
if(!$arr) exit('No rows');
var_export($arr);
$stmt->close();

獲取單個值(標量)

PDO

$stmt = $pdo->prepare("SELECT id, name, age FROM myTable WHERE name = ?");
$stmt->execute([$_POST['name']]);
$arr = $stmt->fetch(PDO::FETCH_COLUMN);
if(!$arr) exit('No rows');
var_export($arr);
$stmt = null;

MySQLi

$stmt = $mysqli->prepare("SELECT id, name, age FROM myTable WHERE name = ?");
$stmt->bind_param("s", $_POST['name']);
$stmt->execute();
$arr = $stmt->get_result()->fetch_row()[0];
if(!$arr) exit('No rows');
var_export($arr);
$stmt->close();

獲取對象數組

PDO

class myClass {}
$stmt = $pdo->prepare("SELECT name, age, weight FROM myTable WHERE name = ?");
$stmt->execute(['Joe']);
$arr = $stmt->fetchAll(PDO::FETCH_CLASS, 'myClass');
if(!$arr) exit('No rows');
var_export($arr);
$stmt = null;

MySQLi

class myClass {}
$arr = [];
$stmt = $mysqli->prepare("SELECT id, name, age FROM myTable WHERE id = ?");
$stmt->bind_param("s", $_SESSION['id']);
$stmt->execute();
$result = $stmt->get_result();
while($row = $result->fetch_object('myClass')) {
  $arr[] = $row;
}
if(!$arr) exit('No rows');
var_export($arr);
$stmt->close();

正如你所看到的,PDO在這里非常出色。MySQLi沒有像$mysqli_result->fetch_all(MYSQLI_OBJ)這樣的東西。PDO甚至更進一步,通過使用fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'myClass')對它進行位元化,以處理在類構造函數之后調用它的默認行為??梢栽贛ySQLi中復制這種行為,但是它依賴于省略構造函數,和魔術方法 _set(),或者只在構造函數中設置它(如果它不等于默認值)。

PDO

$search = "%{$_POST['search']}%";
$stmt = $pdo->prepare("SELECT id, name, age FROM myTable WHERE name LIKE ?");
$stmt->execute([$search]);
$arr = $stmt->fetchAll();
if(!$arr) exit('No rows');
var_export($arr);
$stmt = null;
Copy

MySQLi

$search = "%{$_POST['search']}%";
$stmt = $mysqli->prepare("SELECT id, name, age FROM myTable WHERE name LIKE ?"); 
$stmt->bind_param("s", $search);
$stmt->execute();
$arr = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
if(!$arr) exit('No rows');
var_export($arr);
$stmt->close();

獲取模式

到目前為止,這是我最喜歡的PDO特性。PDO中的獲取模式非常有用,而MySQLi還沒有添加它們。

獲取鍵/值對

PDO

$stmt = $pdo->prepare("SELECT event_name, location FROM events WHERE id < ?");
$stmt->execute([25]);
$arr = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
if(!$arr) exit('No rows');
var_export($arr);
$stmt = null;
Copy

MySQLi

$arr = [];
$id = 25;
$stmt = $con->prepare("SELECT event_name, location FROM events WHERE id < ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$result = $stmt->get_result();
while($row = $result->fetch_row()) {
  $arr[$row[0]] = $row[1];
}
if(!$arr) exit('No rows');
var_export($arr);
$stmt->close();

輸出:

['Cool Event' => 'Seattle', 'Fun Event' => 'Dallas', 'Boring Event' => 'Chicago']

獲取組列

PDO

$stmt = $pdo->prepare("SELECT hair_color, name FROM myTable WHERE id < ?");
$stmt->execute([10]);
$arr = $stmt->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_COLUMN);
if(!$arr) exit('No rows');
var_export($arr);
$stmt = null;
Copy

MySQLi

$arr = [];
$id = 10;
$stmt = $con->prepare("SELECT hair_color, name FROM myTable WHERE id < ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$result = $stmt->get_result();
while($row = $result->fetch_row()) {
  $arr[$row[0]][] = $row[1];
}
if(!$arr) exit('No rows');
var_export($arr);
$stmt->close();
Copy

輸出:

[
  'blonde' => ['Patrick', 'Olivia'],
  'brunette' => ['Kyle', 'Ricky'],
  'red' => ['Jordan', 'Eric']
]

獲取鍵/值對數組

PDO

$stmt = $pdo->prepare("SELECT id, max_bench, max_squat FROM myTable WHERE weight < ?");
$stmt->execute([200]);
$arr = $stmt->fetchAll(PDO::FETCH_UNIQUE);
if(!$arr) exit('No rows');
var_export($arr);
$stmt = null;
Copy

MySQLi

$arr = [];
$weight = 200;
$stmt = $con->prepare("SELECT id, max_bench, max_squat FROM myTable WHERE weight < ?");
$stmt->bind_param("i", $weight);
$stmt->execute();
$result = $stmt->get_result();
$firstColName = $result->fetch_field_direct(0)->name;
while($row = $stmtResult->fetch_assoc()) {
  $firstColVal = $row[$firstColName];
  unset($row[$firstColName]);
  $arr[$firstColVal] = $row;
}
if(!$arr) exit('No rows');
var_export($arr);
$stmt->close();
Copy

輸出:

[
  17 => ['max_bench' => 230, 'max_squat' => 175],
  84 => ['max_bench' => 195, 'max_squat' => 235],
  136 => ['max_bench' => 135, 'max_squat' => 285]
]

獲取組

PDO

$stmt = $pdo->prepare("SELECT hair_color, name, age FROM myTable WHERE id < ?");
$stmt->execute([12]);
$arr = $stmt->fetchAll(PDO::FETCH_GROUP);
if(!$arr) exit('No rows');
var_export($arr);
$stmt = null;
Copy

MySQLi

$arr = [];
$id = 12;
$stmt = $con->prepare("SELECT hair_color, name, age FROM myTable WHERE id < ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$result = $stmt->get_result();
$firstColName = $result->fetch_field_direct(0)->name;
while($row = $stmtResult->fetch_assoc()) {
  $firstColVal = $row[$firstColName];
  unset($row[$firstColName]);
  $arr[$firstColVal][] = $row;
}
if(!$arr) exit('No rows');
var_export($arr);
$stmt->close();
Copy

輸出:

[
  'blonde' => [
    ['name' => 'Patrick', 'age' => 22],
    ['name' => 'Olivia', 'age' => 18]
  ],
  'brunette'  => [
    ['name' => 'Kyle', 'age'=> 25],
    ['name' => 'Ricky', 'age' => 34]
  ],
   'red'  => [
    ['name' => 'Jordan', 'age' => 17],
    ['name' => 'Eric', 'age' => 52]
  ]
]

在數組中的位置

PDO

$inArr = [1, 3, 5];
$clause = implode(',', array_fill(0, count($inArr), '?')); 
$stmt = $pdo->prepare("SELECT * FROM myTable WHERE id IN ($clause)");
$stmt->execute($inArr);
$resArr = $stmt->fetchAll();
if(!$resArr) exit('No rows');
var_export($resArr);
$stmt = null;
Copy

MySQLi

$inArr = [12, 23, 44];
$clause = implode(',', array_fill(0, count($inArr), '?')); /
$types = str_repeat('i', count($inArr)); /
$stmt = $mysqli->prepare("SELECT id, name FROM myTable WHERE id IN ($clause)");
$stmt->bind_param($types, ...$inArr);
$stmt->execute();
$resArr = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
if(!$resArr) exit('No rows');
var_export($resArr);
$stmt->close();

與其他占位符一起排列的位置

PDO

$inArr = [1, 3, 5];
$clause = implode(',', array_fill(0, count($inArr), '?')); 
$stmt = $pdo->prepare("SELECT * FROM myTable WHERE id IN ($clause) AND id < ?");
$fullArr = array_merge($inArr, [5]); 
$stmt->execute($fullArr);
$resArr = $stmt->fetchAll();
if(!$resArr) exit('No rows');
var_export($resArr);
$stmt = null;
Copy

MySQLi

$inArr = [12, 23, 44];
$clause = implode(',', array_fill(0, count($inArr), '?'));
$types = str_repeat('i', count($inArr));
$types .= 'i'; //add 1 more int type
$fullArr = array_merge($inArr, [26]); 
$stmt = $mysqli->prepare("SELECT id, name FROM myTable WHERE id IN ($clause) AND age > ?");
$stmt->bind_param($types, ...$fullArr); 
$stmt->execute();
$resArr = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
if(!$resArr) exit('No rows');
var_export($resArr);
$stmt->close();

交易

PDO

try {
  $pdo->beginTransaction();
  $stmt1 = $pdo->prepare("INSERT INTO myTable (name, state) VALUES (?, ?)");
  $stmt2 = $pdo->prepare("UPDATE myTable SET age = ? WHERE id = ?");
  if(!$stmt1->execute(['Rick', 'NY'])) throw new Exception('Stmt 1 Failed');
  else if(!$stmt2->execute([27, 139])) throw new Exception('Stmt 2 Failed');
  $stmt1 = null;
  $stmt2 = null;
  $pdo->commit();
} catch(Exception $e) {
  $pdo->rollback();
  throw $e;
}

MySQLi

try {
  $mysqli->autocommit(FALSE);
  $stmt1 = $mysqli->prepare("INSERT INTO myTable (name, age) VALUES (?, ?)");
  $stmt2 = $mysqli->prepare("UPDATE myTable SET name = ? WHERE id = ?");
  $stmt1->bind_param("si", $_POST['name'], $_POST['age']);
  $stmt2->bind_param("si", $_POST['name'], $_SESSION['id']);
  $stmt1->execute();
  $stmt2->execute();
  $stmt1->close();
  $stmt2->close();
  $mysqli->autocommit(TRUE);
} catch(Exception $e) {
  $mysqli->rollback(); 
  throw $e;
}

MySQLi有一個問題,但是解決方案是使用全局處理程序將錯誤轉換為異常。

命名為Paramters

$stmt = $pdo->prepare("UPDATE myTable SET name = :name WHERE id = :id");
$stmt->execute([':name' => 'David', ':id' => 3]);
$stmt = null;

對于以上關于PDO與MySQLi各自優勢及該如何選擇,大家是不是覺得非常有幫助。如果需要了解更多內容,請繼續關注我們的行業資訊,相信你會喜歡上這些內容的。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女