PDO与MySQLi:PHP数据库API之战
介绍
使用mysql_扩展的日子已经过去了,因为自PHP 5.5以来它的方法已被弃用,并且从PHP 7开始被删除。但是互联网上仍然充斥着大量的旧教程,初学者只需复制/粘贴并在共享主机平台上使用旧版本的PHP即可。
如果你在PHP中使用MySQL或MariaDB,那么你现在可以选择MySQLi或PDO。前者只是一个改进版本,支持过程化和OOP,并添加了预处理语句,而后者是一个抽象层,允许你为它支持的所有12个数据库驱动程序使用统一的API。尽管MySQL是PHP世界中最流行的数据库。
理论上,我们不需要为存在的每种数据库类型都提供特定于供应商的API,因为只使用一种数据库要简单得多。虽然对此肯定有很多道理,但问题是PDO_MYSQL并没有MySQLi所具有的所有最新和最先进的特性。老实说,我不明白为什么会这样,因为这将完全消除使用特定于供应商的API的任何理由。尽管如此,我想大多数人并不需要这些额外的功能,但肯定有一些人需要。
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')对它进行位元化,以处理在类构造函数之后调用它的默认行为。可以在MySQLi中复制这种行为,但是它依赖于省略构造函数,和魔术方法 _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;
Atas ialah kandungan terperinci PDO与MySQLi:PHP数据库API之战. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



PDOPDO ialah lapisan abstraksi akses pangkalan data berorientasikan objek yang menyediakan antara muka bersatu untuk PHP, membolehkan anda menggunakan kod yang sama untuk berinteraksi dengan pangkalan data yang berbeza (seperti Mysql, postgresql, oracle). PDO menyembunyikan kerumitan sambungan pangkalan data asas dan memudahkan operasi pangkalan data. Kebaikan dan Kelemahan Kelebihan: Antara muka bersatu, menyokong berbilang pangkalan data, memudahkan operasi pangkalan data, mengurangkan kesukaran pembangunan, menyediakan penyata yang disediakan, meningkatkan keselamatan, menyokong pemprosesan transaksi Kelemahan: prestasi mungkin lebih rendah sedikit daripada sambungan asli, bergantung pada perpustakaan luaran, mungkin meningkatkan overhed, kod demo menggunakan PDO Sambung ke pangkalan data mysql: $db=newPDO("mysql:host=localhost;dbnam

Bagaimana untuk merangkak dan memproses data dengan memanggil antara muka API dalam projek PHP? 1. Pengenalan Dalam projek PHP, kita selalunya perlu merangkak data dari tapak web lain dan memproses data ini. Banyak tapak web menyediakan antara muka API, dan kami boleh mendapatkan data dengan memanggil antara muka ini. Artikel ini akan memperkenalkan cara menggunakan PHP untuk memanggil antara muka API untuk merangkak dan memproses data. 2. Dapatkan URL dan parameter antara muka API Sebelum memulakan, kita perlu mendapatkan URL antara muka API sasaran dan parameter yang diperlukan.

Panduan Panggilan ReactAPI: Cara berinteraksi dan memindahkan data ke API bahagian belakang Gambaran Keseluruhan: Dalam pembangunan web moden, berinteraksi dengan dan memindahkan data ke API bahagian belakang adalah keperluan biasa. React, sebagai rangka kerja bahagian hadapan yang popular, menyediakan beberapa alat dan ciri yang berkuasa untuk memudahkan proses ini. Artikel ini akan memperkenalkan cara menggunakan React untuk memanggil API bahagian belakang, termasuk permintaan GET dan POST asas serta memberikan contoh kod khusus. Pasang kebergantungan yang diperlukan: Pertama, pastikan Axi dipasang dalam projek

Dalam dunia aplikasi dan analitik dipacu data, API (Antara Muka Pengaturcaraan Aplikasi) memainkan peranan penting dalam mendapatkan semula data daripada pelbagai sumber. Apabila bekerja dengan data API, anda selalunya perlu menyimpan data dalam format yang mudah diakses dan dimanipulasi. Satu format sedemikian ialah CSV (Nilai Dipisahkan Koma), yang membolehkan data jadual disusun dan disimpan dengan cekap. Artikel ini akan meneroka proses menyimpan data API ke format CSV menggunakan bahasa pengaturcaraan yang berkuasa Python. Dengan mengikut langkah-langkah yang digariskan dalam panduan ini, kami akan mempelajari cara mendapatkan semula data daripada API, mengekstrak maklumat yang berkaitan dan menyimpannya dalam fail CSV untuk analisis dan pemprosesan selanjutnya. Mari selami dunia pemprosesan data API dengan Python dan buka kunci potensi format CSV

Oracle ialah penyedia sistem pengurusan pangkalan data yang terkenal di dunia, dan APInya (Antara Muka Pengaturcaraan Aplikasi) ialah alat berkuasa yang membantu pembangun berinteraksi dan menyepadukan dengan mudah dengan pangkalan data Oracle. Dalam artikel ini, kami akan menyelidiki panduan penggunaan API Oracle, menunjukkan kepada pembaca cara menggunakan teknologi antara muka data semasa proses pembangunan dan menyediakan contoh kod khusus. 1. Oracle

Analisis strategi penyepaduan API Oracle: Untuk mencapai komunikasi yang lancar antara sistem, contoh kod khusus diperlukan Dalam era digital hari ini, sistem perusahaan dalaman perlu berkomunikasi antara satu sama lain dan berkongsi data, dan Oracle API ialah salah satu alat penting untuk membantu mencapai kelancaran. komunikasi antara sistem. Artikel ini akan bermula dengan konsep dan prinsip asas OracleAPI, meneroka strategi penyepaduan API, dan akhirnya memberikan contoh kod khusus untuk membantu pembaca memahami dan menggunakan OracleAPI dengan lebih baik. 1. API Oracle Asas

Cara menggunakan MongoDB untuk membangunkan CRUDAPI ringkas Dalam pembangunan aplikasi web moden, operasi CRUD (tambah, padam, ubah suai, pertanyaan) adalah salah satu fungsi yang paling biasa dan penting. Dalam artikel ini, kami akan memperkenalkan cara membangunkan API CRUD mudah menggunakan pangkalan data MongoDB dan menyediakan contoh kod khusus. MongoDB ialah pangkalan data NoSQL sumber terbuka yang menyimpan data dalam bentuk dokumen. Tidak seperti pangkalan data hubungan tradisional, MongoDB tidak mempunyai skema yang telah ditetapkan

Tajuk: Cara menangani pelaporan ralat API Laravel, contoh kod khusus diperlukan Semasa membangunkan Laravel, ralat API sering ditemui. Ralat ini mungkin datang daripada pelbagai sebab seperti ralat logik kod program, masalah pertanyaan pangkalan data atau kegagalan permintaan API luaran. Cara mengendalikan laporan ralat ini ialah isu utama Artikel ini akan menggunakan contoh kod khusus untuk menunjukkan cara mengendalikan laporan ralat API Laravel dengan berkesan. 1. Ralat pengendalian dalam Laravel
