Hiệu suất MySQLi so với PDO

Để kết nối với cơ sở dữ liệu MySQL hoặc MariaDB, PHP cung cấp hai API. PDO với trình điều khiển PDO_MySQL và mysqli. Trước PHP 7 cũng có ext/mysql không được khuyến nghị sử dụng nữa

Sự khác biệt về tính năng giữa mysqli và PDO

Tính năngPDOMySQLiHỗ trợ cơ sở dữ liệu12 trình điều khiển khác nhauMySQL và MariaDBGiao diệnOOPOOP và thủ tụcTham số được đặt tênCóKhôngÁnh xạ đối tượngCóCóCâu lệnh chuẩn bịCóCóTruy vấn không chặn, không đồng bộ với hỗ trợ mysqlndKhôngCóHỗ trợ nhiều câu lệnhHầu hếtCóMySQL 5. 1+ chức năng hỗ trợ MostAll

Kết nối cơ sở dữ liệu

// PDO
$pdo = new PDO("mysql:host=localhost;dbname=database;charset=utf8", 'username', 'password');

// mysqli, procedural way
$mysqli = mysqli_connect('localhost', 'username', 'password', 'database');

// mysqli, object oriented way
$mysqli = new mysqli('localhost', 'username', 'password', 'database');

Hỗ trợ cơ sở dữ liệu

Ưu điểm cốt lõi của PDO so với MySQLi là hỗ trợ trình điều khiển cơ sở dữ liệu. Tại thời điểm viết bài này, PDO hỗ trợ 12 trình điều khiển khác nhau, trái ngược với MySQLi, chỉ hỗ trợ cơ sở dữ liệu MySQL và MariaDB

tham số được đặt tên

Một tính năng quan trọng khác của PDO là liên kết tham số dễ dàng hơn thay vì liên kết số

$params = [':username' => 'test', ':email' => $mail, ':last_login' => time() - 3600];

$pdo->prepare('
    SELECT * FROM users
    WHERE username = :username
    AND email = :email
    AND last_login > :last_login');

$pdo->execute($params);

MySQLi cung cấp liên kết tham số dấu chấm hỏi và không hỗ trợ tham số được đặt tên

$query = $mysqli->prepare('
    SELECT * FROM users
    WHERE username = ?
    AND email = ?
    AND last_login > ?');

$query->bind_param('sss', 'test', $mail, time() - 3600);
$query->execute();

Liên kết tham số dấu chấm hỏi có vẻ ngắn hơn, nhưng nó gần như không linh hoạt như tham số được đặt tên, do thực tế là nhà phát triển phải luôn theo dõi thứ tự tham số;

ánh xạ đối tượng

Cả PDO và MySQLi đều có thể ánh xạ kết quả tới các đối tượng. Điều này rất hữu ích nếu bạn không muốn sử dụng lớp trừu tượng cơ sở dữ liệu tùy chỉnh, nhưng vẫn muốn hành vi giống như ORM. Hãy tưởng tượng rằng chúng ta có một lớp Người dùng với một số thuộc tính khớp với tên trường từ cơ sở dữ liệu

class User
{
    public $id;
    public $first_name;
    public $last_name;

    public function info()
    {
        return '#'.$this->id.': '.$this->first_name.' '.$this->last_name;
    }
}

Nếu không có ánh xạ đối tượng, chúng ta sẽ cần điền giá trị của từng trường (bằng tay hoặc thông qua hàm tạo) trước khi có thể sử dụng phương thức info() một cách chính xác

Điều này cho phép chúng tôi xác định trước các thuộc tính này trước khi đối tượng thậm chí được xây dựng. Ví dụ

$query = "SELECT id, first_name, last_name FROM users";

// PDO
$result = $pdo->query($query);
$result->setFetchMode(PDO::FETCH_CLASS, 'User');

while ($user = $result->fetch()) {
    echo $user->info()."\n";
}

// MySQLI, procedural way
if ($result = mysqli_query($mysqli, $query)) {
    while ($user = mysqli_fetch_object($result, 'User')) {
        echo $user->info()."\n";
    }
}

// MySQLi, object oriented way
if ($result = $mysqli->query($query)) {
    while ($user = $result->fetch_object('User')) {
        echo $user->info()."\n";
    }
}

Bảo vệ

Giả sử một hacker đang cố chèn một số SQL độc hại thông qua tham số truy vấn HTTP

$params = [':username' => 'test', ':email' => $mail, ':last_login' => time() - 3600];

$pdo->prepare('
    SELECT * FROM users
    WHERE username = :username
    AND email = :email
    AND last_login > :last_login');

$pdo->execute($params);
0 (GET)

$_GET['username'] = "'; DELETE FROM users; /*"

Nếu chúng tôi không thoát khỏi điều này, nó sẽ được đưa vào truy vấn “nguyên trạng” - xóa tất cả các hàng khỏi bảng người dùng (cả PDO và mysqli đều hỗ trợ nhiều truy vấn)

// PDO, "manual" escaping
$username = PDO::quote($_GET['username']);

$pdo->query("SELECT * FROM users WHERE username = $username");

// mysqli, "manual" escaping
$username = mysqli_real_escape_string($_GET['username']);

$mysqli->query("SELECT * FROM users WHERE username = '$username'");

Như bạn có thể thấy,

$params = [':username' => 'test', ':email' => $mail, ':last_login' => time() - 3600];

$pdo->prepare('
    SELECT * FROM users
    WHERE username = :username
    AND email = :email
    AND last_login > :last_login');

$pdo->execute($params);
1 không chỉ thoát khỏi chuỗi mà còn trích dẫn nó. Ở phía bên kia,
$params = [':username' => 'test', ':email' => $mail, ':last_login' => time() - 3600];

$pdo->prepare('
    SELECT * FROM users
    WHERE username = :username
    AND email = :email
    AND last_login > :last_login');

$pdo->execute($params);
0 sẽ chỉ thoát khỏi chuỗi. Bạn sẽ cần phải áp dụng các dấu ngoặc kép theo cách thủ công

________số 8

Khuyến nghị là luôn sử dụng các câu lệnh đã chuẩn bị với các truy vấn ràng buộc thay vì

$params = [':username' => 'test', ':email' => $mail, ':last_login' => time() - 3600];

$pdo->prepare('
    SELECT * FROM users
    WHERE username = :username
    AND email = :email
    AND last_login > :last_login');

$pdo->execute($params);
1 và
$params = [':username' => 'test', ':email' => $mail, ':last_login' => time() - 3600];

$pdo->prepare('
    SELECT * FROM users
    WHERE username = :username
    AND email = :email
    AND last_login > :last_login');

$pdo->execute($params);
0

Hiệu suất

Mặc dù cả PDO và MySQLi đều khá nhanh, MySQLi hoạt động nhanh hơn không đáng kể trong các điểm chuẩn - ~2. 5% cho báo cáo không chuẩn bị trước và ~6. 5% cho những người chuẩn bị. Tiện ích mở rộng MySQL thậm chí còn nhanh hơn

Tôi nên sử dụng MySQLi hay PDO?

PDO có an toàn hơn MySQLi không?

Sử dụng PDO được coi là phương pháp hay nhất (cả PDO và MySQLi đều hoạt động ở cùng tốc độ). Tôi cho rằng PDO giúp triển khai bảo mật dễ dàng hơn .

Lợi thế của PDO so với MySQLi là gì?

Hỗ trợ cơ sở dữ liệu . Tại thời điểm viết bài này, PDO hỗ trợ 12 trình điều khiển khác nhau, trái ngược với MySQLi, chỉ hỗ trợ MySQL. database driver support. At the time of this writing, PDO supports 12 different drivers, opposed to MySQLi, which supports MySQL only.

MySQLi có nhanh hơn MySQL không?

Tiện ích mở rộng MySQL nhanh hơn một chút so với MySQLi trong hầu hết các điểm chuẩn mà tôi đã thấy được báo cáo. Tuy nhiên, sự khác biệt rất nhỏ nên đây có lẽ không phải là tiêu chí để bạn quyết định giữa hai. Các yếu tố khác làm giảm sự khác biệt về hiệu suất giữa mysql và mysqli.