- MYSQL vs MYSQLI vs PDO in PHP (Which One To Use!?)
- TABLE OF CONTENTS
- PHP MYSQL EXTENSIONS
- PRELUDE) DUMMY DATABASE
- PART 1) LEGACY MYSQL EXTENSION
- PART 2) MYSQLI EXTENSION
- PART 3) PDO EXTENSION
- DOWNLOAD & NOTES
- SUPPORT
- EXAMPLE CODE DOWNLOAD
- EXTRA BITS & LINKS
- WHICH ONE IS “BETTER”?
- MYSQL, MYSQLI, PDO – WHICH ONE SHOULD I USE?
- REFERENCES & LINKS
- THE END
- PDO против MySQLi. Что выбрать?
- Резюме
- СоединениеConnection
- API
- Поддержка баз данных
- Именованные параметры
- Объектное отображение
- Безопасность
- Производительность
- Заключение
- 5 последних уроков рубрики «PHP»
- Фильтрация данных с помощью zend-filter
- Контекстное экранирование с помощью zend-escaper
- Подключение Zend модулей к Expressive
- Совет: отправка информации в Google Analytics через API
- Подборка PHP песочниц
MYSQL vs MYSQLI vs PDO in PHP (Which One To Use!?)
Welcome to a quick tutorial on the difference between MySQL, MySQLi, and PDO in PHP. So you may have just started working with MySQL in PHP, and noticed that there are 3 different extensions to work with the database.
The main difference between the MySQL, MySQLi, and PDO extensions is:
- MySQL – The early PHP-MySQL extension, currently defunct and removed.
- MySQLi (MySQL Improved) – An improved version of the earlier MySQL extension.
- PHP Data Objects (PDO) – The modern database extension. Supports not just MySQL, but also other databases such as Firebird, SQLite, Postgre, and more.
Yes, the so-called “difference” is actually the development history of MySQL extensions in PHP itself. But just which one is correct, which one is “better”, and which should you use? Read on to find out!
TABLE OF CONTENTS
PHP MYSQL EXTENSIONS
All right, let us now get into the examples of using each MySQL database extension. Also, a simple “non-scientific non-professional” test to see which one performs the best.
PRELUDE) DUMMY DATABASE
-- (A) USERS TABLE CREATE TABLE `users` ( `id` bigint(20) NOT NULL, `name` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ALTER TABLE `users` ADD PRIMARY KEY (`id`); ALTER TABLE `users` MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT; -- (B) DUMMY USERS INSERT INTO `users` (`id`, `name`) VALUES (1, 'Bevis'), (2, 'Cally'), (3, 'Harrison'), .
If you are interested to run the “non-conclusive performance test”, here is the dummy table we are using, download the zip file above.
PART 1) LEGACY MYSQL EXTENSION
mysql_select_db(DB_NAME, $mysql); mysql_set_charset(DB_CHARSET, $mysql); // (C) SELECT USERS $result = mysql_query("SELECT * FROM `users`"); while ($row = mysql_fetch_array($result, MYSQL_NUM)) < print_r($row); >mysql_free_result($result); mysql_close($mysql); // (TEST) TOTAL TIME TAKEN $taken = microtime(true) - $taken; echo "Total time taken $taken";
Now, the (original) MySQL extension has been totally removed in PHP 7. As such, I will just leave this here as an example for the people who may need to support legacy systems. Otherwise, please don’t use this outdated extension anymore.
PART 2) MYSQLI EXTENSION
connect_error) < exit($mysqli->connect_error); > $mysqli->set_charset(DB_CHARSET); // (C) SELECT USERS $result = $mysqli->query("SELECT * FROM `users`"); while ($row = $result->fetch_assoc()) < print_r($row); >$result->close(); $mysqli->close(); // (TEST) TOTAL TIME TAKEN $taken = microtime(true) - $taken; echo "Total time taken $taken";
That’s right, this is pretty much the same as the traditional MySQL, the only difference is that we are using new mysqli() instead. As for the usage, just trace through the script, it is straightforward as can be.
PART 3) PDO EXTENSION
PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); // (C) SELECT USERS $stmt = $pdo->prepare("SELECT * FROM `users`"); $stmt->execute(); while ($row = $stmt->fetch()) < print_r($row); >if ($stmt !== null) < $stmt = null; >if ($pdo !== null) < $pdo = null; >// (TEST) TOTAL TIME TAKEN $taken = microtime(true) - $taken; echo "Total time taken $taken";
Now, this PDO example should be very straightforward too. But the beauty of PDO actually lies with its compatibility with a wide range of databases – That is, this extension works with many other databases apart from MySQL. Also, there are many smart ways to fetch entries using PDO – fetch() , fetchColumn() , fetchAll() , and even down to setting how the array is arranged.
DOWNLOAD & NOTES
Here is the download link to the example code, so you don’t have to copy-paste everything.
SUPPORT
600+ free tutorials & projects on Code Boxx and still growing. I insist on not turning Code Boxx into a «paid scripts and courses» business, so every little bit of support helps.
EXAMPLE CODE DOWNLOAD
Click here for the source code on GitHub gist, just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
EXTRA BITS & LINKS
That’s all for this guide, and here is a small section on some extras and links that may be useful to you.
WHICH ONE IS “BETTER”?
So yep, there is a split-second difference in performance. I personally won’t make a huge fuss out of it, but if you are into “scientific professional performance tests” – Feel free to devise your own set of tests (and let us know the results).
MYSQL, MYSQLI, PDO – WHICH ONE SHOULD I USE?
I will highly recommend using PDO. Simply for its support for a range of databases, and the abstraction it provides. We only need to enable the respective PDO extension in php.ini , and the project is ready to work with databases other than MySQL. For example, “upgrading” from MySQL to Oracle Database.
REFERENCES & LINKS
- PDO – PHP
- MySQLi – PHP
- MySQL – PHP
- phpMyAdmin – A free PHP database manager. If you installed the XAMPP package, it is already installed at http://localhost/phpmyadmin .
- MySQL Workbench – The so-called official MySQL database manager by Oracle themselves.
THE END
Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!
PDO против MySQLi. Что выбрать?
Когда возникает вопрос о доступе к базе данных из кода PHP, есть два варианта: MySQLi и PDO. Что нужно знать, прежде чем сделать выбор? Различия, поддержка баз данных, стабильность, и производительность в общих чертах описываются в данном уроке.
Резюме
PDO | MySQLi | |
Поддержка баз данных | 12 различных драйверов | Только MySQL |
API | ООП | ООП+процедурная часть |
Соединение | Просто | Просто |
Именованные параметры | Есть | Нет |
Объектное отображение | Есть | Есть |
Подготовленные выражения (сторона клиента) | Есть | Нет |
Производительность | Хорошая | Хорошая |
Хранимые процедуры | Есть | Есть |
СоединениеConnection
Оба варианта предоставляют очень простые инструменты для соединения с базой данных:
// PDO $pdo = new PDO("mysql:host=localhost;dbname=database", 'username', 'password'); // MySQLi, процедурная часть $mysqli = mysqli_connect('localhost','username','password','database'); // MySQLi, ООП $mysqli = new mysqli('localhost','username','password','database');
API
И PDO и MySQLi предлагают объектно-ориентированное API. Но MySQLi также имеет процедурную часть API, которая для новичков может показаться проще для освоения. Если вы знакомы с собственным драйвером PHP MySQL, то мигрирование на процедурную часть MySQLi будет для вас проще. Но достигнув вершин мастерства в использовании PDO, его можно будет использовать с любой базой данных без каких-либо изменений основного кода
Поддержка баз данных
Ключевым преимуществом PDO перед MySQLi является его могучая поддержка различных баз данных. На момент написания урока PDO может использовать 12 драйверов. А MySQLi — поддерживает только MySQL.
Чтобы распечатать список поддерживаемых драйверов PDO можно использовать следующий код:
var_dump(PDO::getAvailableDrivers());
Что означает разница в количестве поддерживаемых баз данных? Для ситуаций, когда в проекте надо перейти на использование другой базы данных, PDO позволит сделать процесс прозрачным. Все, что нужно будет сделать — изменить строку соединения и несколько запросов, если какие-либо методы не поддерживаются новой базой данных. В случае с MySQLi придется переписывать весь код, включая запросы.
Именованные параметры
Другой важной отличительной особенностью PDO являются именованные параметры, которые делают процедуру привязывания существенно проще:
$params = array(':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);
$query = $mysqli->prepare(' SELECT * FROM users WHERE username = ? AND email = ? AND last_login > ?'); $query->bind_param('sss', 'test', $mail, time() - 3600); $query->execute();
Знак вопроса может показаться короче, чем символьные имена. Однако, теряется гибкость и устойчивость к ошибкам, так как разработчику нужно помнить о порядке следования параметров, что в большинстве случаев представляет собой зону с очень высокой вероятностью трудно распознаваемых ошибок.
К сожалению, MySQLi не поддерживает именованные параметры.
Объектное отображение
И PDO и MySQLi могут отображать результаты как объекты. Данная особенность может быть полезна в том случае, если вы не хотите использовать уровень абстракций базы данных и желаете реализовать модель объектно-реляционного отображения. Допустим, у нас есть класс User с некоторыми свойствами, которые соответствуют именам полей в базе данных:
class User < public $id; public $first_name; public $last_name; public function info() < return '#'.$this->id.': '.$this->first_name.' '.$this->last_name; > >
Без объектного отображения нужно будет заполнять значениями каждое поле (либо вручную, либо с помощью конструктора) прежде, чем можно будет использовать метод info() корректно.
Но объектное отображение позволяет предопределять свойства даже до того, как объект будет построен. Например:
$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, процедурная часть if ($result = mysqli_query($mysqli, $query)) < while ($user = mysqli_fetch_object($result, 'User')) < echo $user->info()."\n"; > > // MySQLi, ООП if ($result = $mysqli->query($query)) < while ($user = $result->fetch_object('User')) < echo $user->info()."\n"; > >
Безопасность
Обе библиотеки предоставляют средства для защиты от SQL инъекций, которые разработчики могут использовать по своему усмотрению.
Допустим, злодей пытается встроить вредный запрос SQL через параметр ‘username’ HTTP запроса (GET):
$_GET['username'] = "'; DELETE FROM users; /*"
Если пропустить такое выражение, то оно будет включено в запрос в том виде, как есть – запрос удаляет все строки из таблицы users (и PDO и MySQLi поддерживают множественные запросы).
// PDO, "ручная" зачистка параметра $username = PDO::quote($_GET['username']); $pdo->query("SELECT * FROM users WHERE username = $username"); // MySQLi, "ручная" зачистка параметра $username = mysqli_real_escape_string($_GET['username']); $mysqli->query("SELECT * FROM users WHERE username = '$username'");
Метод PDO::quote() не только отбрасывает лишние символы в строке, но и заключает ее в кавычки. А функция mysqli_real_escape_string() только отбрасывает лишние символы в строке, а в кавычки ее надо будет помещать вручную.
// PDO, подготовленные выражения $pdo->prepare('SELECT * FROM users WHERE username = :username'); $pdo->execute(array(':username' => $_GET['username'])); // mysqli, подготовленные выражения $query = $mysqli->prepare('SELECT * FROM users WHERE username = ?'); $query->bind_param('s', $_GET['username']); $query->execute();
Лучше использовать подготовленные выражения, чем метод PDO::quote() и функцию mysqli_real_escape_string() .
Производительность
И PDO и MySQLi достаточно быстро выполняются. MySQLi имеет небольшое преимущество по результатам тестов – ~2.5% для обычных запросов и ~6.5% для подготовленных выражений. Так что стоит принять информацию во внимание, если для вас будет важно даже минимальное различие в характеристиках.
Заключение
PDO одержал сравнительно легкую победу в данном поединке. С 12 различными драйверами для баз данных (доступны 18 разных баз данных!) и именованными параметрами можно игнорировать небольшое отставание в производительности. С точки зрения безопасности обе библиотеки предоставляют разработчику равные возможности и стойкость кода зависит только от программиста.
Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: net.tutsplus.com/tutorials/php/pdo-vs-mysqli-which-should-you-use/
Перевел: Сергей Фастунов
Урок создан: 25 Февраля 2012
Просмотров: 78637
Правила перепечатки
5 последних уроков рубрики «PHP»
Фильтрация данных с помощью zend-filter
Когда речь идёт о безопасности веб-сайта, то фраза «фильтруйте всё, экранируйте всё» всегда будет актуальна. Сегодня поговорим о фильтрации данных.
Контекстное экранирование с помощью zend-escaper
Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.
Подключение Zend модулей к Expressive
Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.
Совет: отправка информации в Google Analytics через API
Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.
Подборка PHP песочниц
Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.