mysqli или PDO - каковы плюсы и минусы?

В нашем случае мы разделяем использование mysqli и PDO для таких вещей, как подготовленные операторы и поддержка транзакций. В одних проектах используется один, в других - другой. Существует небольшая реальная вероятность того, что мы когда-нибудь перейдем на другую СУБД.

Я предпочитаю PDO по той единственной причине, что он позволяет использовать именованные параметры для подготовленных операторов, а, насколько мне известно, mysqli этого не делает.

Есть ли какие-либо другие плюсы и минусы выбора одного из них в качестве стандарта, поскольку мы объединяем наши проекты для использования только одного подхода?

Ответов (13)

PDO значительно упростит масштабирование, если ваш сайт / веб-приложение станет действительно существующим, поскольку вы можете ежедневно настраивать главные и подчиненные соединения для распределения нагрузки по базе данных, плюс PHP движется к переходу на PDO в качестве стандарта.

Информация о PDO

Масштабирование веб-приложения

Отредактированный ответ.

Имея некоторый опыт работы с обоими этими API, я бы сказал, что есть 2 функции уровня блокировки, которые делают mysqli непригодным для использования с собственными подготовленными операторами.
Они уже были упомянуты в двух отличных (но недооцененных) ответах:

  1. Привязка значений к произвольному количеству заполнителей
  2. Возврат данных в виде простого массива

(оба также упомянуты в этом ответе )

По какой-то причине mysqli не справился с обоими.
В настоящее время он получил некоторые улучшения для второго ( get_result ), но он работает только с установками mysqlnd , а это означает, что вы не можете полагаться на эту функцию в своих сценариях.

Но даже по сей день у него нет привязки по стоимости.

Итак, есть только один выбор: PDO

Все остальные причины, такие как

  • именованные заполнители (этот синтаксический сахар сильно переоценен)
  • поддержка разных баз данных (фактически никто никогда не использовал)
  • получить в объект (просто бесполезный синтаксический сахар)
  • разница в скорости (нет)

не имеют большого значения.

В то же время в обоих этих API отсутствуют некоторые действительно важные функции , такие как

  • заполнитель идентификатора
  • заполнитель для сложных типов данных, чтобы сделать динамическое связывание менее утомительным
  • более короткий код приложения.

Итак, чтобы удовлетворить реальные жизненные потребности, нужно создать свою собственную библиотеку абстракций на основе одного из этих API, реализующих вручную анализируемые заполнители. В этом случае я бы предпочел mysqli, поскольку он имеет меньший уровень абстракции.

Перемещение приложения из одной базы данных в другую не очень распространено, но рано или поздно вы можете обнаружить, что работаете над другим проектом, используя другую СУБД. Если вы дома с PDO, тогда вам будет по крайней мере на одну вещь меньше учиться.

Кроме того, я нахожу PDO API более интуитивно понятным и более объектно-ориентированным. mysqli кажется, что это просто процедурный API, который был объективирован, если вы понимаете, о чем я. Короче говоря, мне легче работать с PDO, но это, конечно, субъективно.

Лично я использую PDO, но думаю, что это в основном вопрос предпочтений.

PDO имеет некоторые функции, которые помогают против SQL-инъекций ( подготовленные операторы ), но если вы будете осторожны с вашим SQL, вы также можете добиться этого с помощью mysqli.

Переход на другую базу данных - не столько повод для использования PDO. Пока вы не используете «специальные функции SQL», вы можете переключаться с одной БД на другую. Однако, как только вы используете, например, «SELECT ... LIMIT 1», вы не сможете перейти к MS-SQL, где это «SELECT TOP 1 ...». Так что это в любом случае проблематично.

I've started using PDO because the statement support is better, in my opinion. I'm using an ActiveRecord-esque data-access layer, and it's much easier to implement dynamically generated statements. MySQLi's parameter binding must be done in a single function/method call, so if you don't know until runtime how many parameters you'd like to bind, you're forced to use call_user_func_array() (I believe that's the right function name) for selects. And forget about simple dynamic result binding.

Most of all, I like PDO because it's a very reasonable level of abstraction. It's easy to use it in completely abstracted systems where you don't want to write SQL, but it also makes it easy to use a more optimized, pure query type of system, or to mix-and-match the two.

PDO - это стандарт, это то, что ожидает использовать большинство разработчиков. mysqli был, по сути, индивидуальным решением конкретной проблемы, но он имеет все проблемы других специфичных для СУБД библиотек. PDO - это то место, куда будет направлен весь тяжелый труд и умное мышление.

Следует помнить об одном.

Mysqli не поддерживает функцию fetch_assoc (), которая возвращала бы столбцы с ключами, представляющими имена столбцов. Конечно, для этого можно написать свою собственную функцию, это даже не очень долго, но мне было очень трудно ее написать (для неверующих: если вам это кажется легким, попробуйте как-нибудь самостоятельно и не делайте этого) т жульничать :))

Что мне действительно нравится в PDO, чего нет в MySQLi, так это способность PDO возвращать результат как объект определенного типа класса (например $pdo->fetchObject('MyClass') ). MySQLi fetch_object() вернет только stdClass объект.

Вот еще кое-что, о чем следует помнить: на данный момент (PHP 5.2) библиотека PDO содержит ошибки . В нем полно странных ошибок. Например: перед тем, как сохранить PDOStatement в переменной, переменная должна быть unset() в состоянии избежать множества ошибок. Большинство из них было исправлено в PHP 5.3, и они будут выпущены в начале 2009 года в PHP 5.3, в котором, вероятно, будет много других ошибок. Вам следует сосредоточиться на использовании PDO для PHP 6.1, если вы хотите стабильный выпуск, и на использовании PDO для PHP 5.3, если вы хотите помочь сообществу.

Что ж, вы можете поспорить с объектно-ориентированным аспектом, подготовленными утверждениями, тем фактом, что он становится стандартом, и т. Д. Но я знаю, что в большинстве случаев убедить кого-то лучше работает с помощью убойной функции. Итак, вот оно:

Действительно приятная вещь с PDO - это то, что вы можете извлекать данные, автоматически вставляя их в объект. Если вы не хотите использовать ORM (потому что это просто быстрый сценарий), но вам нравится сопоставление объектов, это ДЕЙСТВИТЕЛЬНО круто:

class Student {

    public $id;
    public $first_name;
    public $last_name

    public function getFullName() {
        return $this->first_name.' '.$this->last_name
    }
}

try 
{
    $dbh = new PDO("mysql:host=$hostname;dbname=school", $username, $password)

    $stmt = $dbh->query("SELECT * FROM students");

    /* MAGIC HAPPENS HERE */

    $stmt->setFetchMode(PDO::FETCH_INTO, new Student);


    foreach($stmt as $student)
    {
        echo $student->getFullName().'<br />';
    } 

    $dbh = null;
}
catch(PDOException $e)
{
    echo $e->getMessage();
}

В смысле скорости выполнения MySQLi выигрывает, но если у вас нет хорошей оболочки, использующей MySQLi, его функции, работающие с подготовленными операторами, ужасны.

В моем все еще есть ошибки, но если кому-то это нужно, то вот они .

Короче говоря, если вы ищете увеличения скорости, то MySQLi; если хотите простоты использования, то PDO.

В моем тестовом сценарии каждый метод тестируется 10000 раз, и печатается разница общего времени для каждого метода. Вы должны сделать это в своей конфигурации, я уверен, что результаты будут другими!

Вот мои результаты:

  • " SELECT NULL" -> PGO()быстрее на ~ 0,35 секунды
  • " SHOW TABLE STATUS" -> mysqli()быстрее на ~ 2,3 секунды
  • " SELECT * FROM users" -> mysqli()быстрее на ~ 33 секунды

Примечание: при использовании -> fetch_row () для mysqli имена столбцов не добавляются в массив, я не нашел способа сделать это в PGO. Но даже если я использую -> fetch_array (), mysqli будет немного медленнее, но все же быстрее, чем PGO (за исключением SELECT NULL).

Еще одно заметное (хорошее) отличие PDO заключается в том, что этот PDO::quote()метод автоматически добавляет заключительные кавычки, тогда как mysqli::real_escape_string()(и аналогичные) этого не делают:

PDO :: quote () помещает кавычки вокруг входной строки (если требуется) и экранирует специальные символы внутри входной строки, используя стиль кавычек, соответствующий базовому драйверу.