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

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

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

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

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

ravi404 28.11.2012 15:48
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
342
1
139 437
13

Ответы 13

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

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

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

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

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

MySQLi подготовил заявления.

Tower 07.07.2009 13:59

Я начал использовать PDO, потому что, на мой взгляд, поддержка операторов лучше. Я использую уровень доступа к данным в стиле ActiveRecord, и гораздо проще реализовать динамически генерируемые операторы. Связывание параметров MySQLi должно выполняться за один вызов функции / метода, поэтому, если вы не знаете до времени выполнения, сколько параметров вы хотите привязать, вы вынуждены использовать call_user_func_array() (я считаю, что это правильное имя функции) для выбирает. И забудьте о простой динамической привязке результата.

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

Возможна привязка результатов с динамически генерируемыми запросами, мы делаем это в наших приложениях. Однако это огромная боль.

Pim Jager 21.04.2009 11:50

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

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

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

Вы пробовали мануал? php.net/manual/en/mysqli-result.fetch-assoc.php

Till 24.09.2008 17:49

Реализовал более давно, но да, я проверил руководство. Работает ли с подготовленными операторами? Я сомневаюсь...

mike 24.09.2008 17:56

На самом деле, у него есть, как ни странно, частичная поддержка. Вы можете получать массивы в обычных запросах, но не в параметризованных запросах: -!

Álvaro González 30.04.2010 14:22

Почему бы не удалить заведомо неправильный ответ?

Majid Fouladpour 19.04.2012 07:04

@MajidFouladpour - Ответ не очевидно неправильно. Просто отсутствует какой-то контекст. Mysqli полностью поддерживает поиск ассоциативного массива нет.

Álvaro González 24.04.2012 15:02

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

Фактически, вы можете указать класс вручную: «объект mysqli_result :: fetch_object ([string $ class_name [, array $ params]])». stdClass используется только в том случае, если вы ничего не указываете.

Andrioid 04.09.2010 12:12

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

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

Brian Warshaw 10.11.2009 19:55

Гм, странно, я никогда не сталкивался с ошибками с PDO. И я им много пользуюсь.

NikiC 23.01.2011 13:49

В Mysqli тоже есть ошибки. Во всем софте есть ошибки.

Bill Karwin 06.05.2013 23:02

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

Действительно хорошая вещь с 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();
}

ORM: объектно-реляционное отображение en.wikipedia.org/wiki/Object-relational_mapping

sergiom 10.03.2010 12:48

Это хороший пост, но он определенно мог бы быть более понятным. Где животные входят в фрагмент с классом Person и таблицей лиц?

micmcg 18.03.2010 07:41

есть ли разница между вышеупомянутым и $mysqliResult->fetch_object("student");?

Andy Fleming 15.04.2011 11:18

Глупая особенность. Если у объекта должны быть публичные поля - это против инкапсуляции. И ключевое слово new, используемое внутри метода - плохая практика.

OZ_ 24.05.2011 16:30

@ e-satis нет, я использую PHP. Публичные поля нарушают инкапсуляцию, поэтому AS A BEST PRACTICE это просто ... lol :) Google не использует публичные поля, только методы доступа: google-styleguide.googlecode.com/svn/trunk/….

OZ_ 25.05.2011 01:08

@ e-satis, попробуйте прочитать эту книгу (я уверен, что вы можете найти ее на своем родном языке, я нашел) amazon.com/Objects-Patterns-Practice-Matt-Zandstra/dp/… - там вы можете найти очень хорошее объяснение, какова основная цель инкапсуляции, почему публичные поля не должны быть используется и почему интерфейсы так важны. Я знаю, в данный момент вы думаете, что я ваш противник - не принимайте это так близко к сердцу, просто прочтите эту книгу, и, я надеюсь, вы меня поймете.

OZ_ 25.05.2011 01:11

@ e-satis: Извините за вмешательство, но геттеры и сеттеры необходимы, если вы хотите контролировать, что происходит при изменении переменных. В противном случае вы просто не можете гарантировать внутреннее состояние вашего объекта (это особенно проблема, если у вас есть другой объект внутри). Это полностью не зависит от языка. @OZ_: Успокойся. Личная критика только заставит кого-то защищаться.

James P. 04.06.2011 21:08

Мне нравится, когда люди говорят, что публичные поля - это зло. Здесь мы используем базу данных; когда мы не захотим иметь возможность редактировать поля базы данных и получать доступ к тем же полям? Ну давай же...

alternative 06.06.2011 17:05

@monadic: Согласен. Инкапсуляция, конечно, является допустимым аргументом при работе с основными компонентами или сложными объектами и т. д., Однако как представление записей, которые в противном случае были бы связаны с чтением и записью. массивы, это приемлемо. Кроме того, это упрощает проверку типов, поскольку записи перемещаются по системе.

Dan Lugg 16.07.2011 04:50

@Mattygabe: к сожалению, слишком много разработчиков, которые только начинают, не осознают, что есть проблемы с образцом кода, и будут копировать его, а не понимать. Если часть примера кода не следует копировать, код следует сопровождать примечанием об этом.

outis 28.08.2011 06:24

@outis Я надеюсь, что я не в меньшинстве, но я не считаю, что ответы следует оценивать с точки зрения их безопасности по отношению к новым разработчикам. Звучит жестко, но это правда. Цель ответа на SO - не просто предоставить код копирования и вставки, но также обеспечить понимание. Задача ответчика не заключается в том, чтобы убедиться, что каждая дыра в безопасности или недостаток шаблона покрыты примером, потому что давайте посмотрим правде в глаза, приложение, в которое копируется код, по своей сути отличается от любого другого приложения, использующего тот же код.

Mattygabe 01.09.2011 18:11

@Mattygabe: пожалуйста, поймите, я не спорю ни за отрицательное голосование, ни за то, чтобы были охвачены все аспекты примера кода, просто нужна небольшая заметка, когда образец кода содержит что-то, что (в производственном коде) обычно является ошибкой, или где читателям следует быть осторожными. Я полностью согласен, что ответы на SO должны содержать объяснения, а не полные решения, поэтому образец кода следует считать иллюстративным. Вот почему должно быть примечание, так как некоторые читатели не будут воспринимать код в качестве иллюстративных примеров, а будут копировать его целиком.

outis 02.09.2011 00:48

... Что касается различий между проектами, то здесь тоже есть сходства. Здесь различия не важны; общие ошибки заключаются в сходстве.

outis 02.09.2011 00:51

@outis Понятно, и я никогда не думал, что вы обязательно выступаете за отрицательный голос. Я просто утверждал, что к любым примерам на SO следует относиться с универсальной оговоркой «разработчик, будьте осторожны». Самая большая причина, по которой я испытываю чувства к этому конкретному примеру, заключается в том, что в этом примере показана особенность PDO, которая не обязательно хорошо известна и не является лучшим способом выполнения оператора select MySQL с PDO, поэтому в примере цель никоим образом не состоит в том, чтобы показать лучший способ выполнения выборки. Но мы согласны почти во всем, так что разногласия незначительны.

Mattygabe 02.09.2011 20:00

Я не тестировал это, но, IMO, очень вероятно, что аргумент инкапсуляции в значительной степени спорный, потому что PHP 5+ допускает аксессоры в виде волшебных методов __get() и __set(). Так что, к счастью, весь аргумент «Я не могу гарантировать целостность состояния моего объекта сейчас» выпадает из окна ...

toon81 15.02.2013 11:08

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

У меня все еще есть баги, но если кому-то это нужно, вот.

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

в смысле скорости, не могли бы вы дать тесты?

Julius F 28.11.2009 17:44

Джонатен Робсон провел достойное сравнение скорости этих двух на jonathanrobson.me/2010/06/mysqli-vs-pdo-benchmarks. Резюме: inserts - почти равно, selects - mysqli на ~ 2,5% быстрее для неподготовленных операторов / ~ на 6,7% быстрее для подготовленных операторов. Учитывая, насколько малы потери производительности, возможности и гибкость использования PDO обычно перевешивают снижение производительности.

Adam 08.03.2011 15:09

@Adam Спасибо за ссылку на мой блог!

jnrbsn 23.03.2012 23:33

@ daemonfire300 Это правда, в тестах нет необходимости. PDO является оболочкой для библиотеки mysqli. Я, вероятно, поразил бы поклонника, если бы кто-то смог доказать, что PDO быстрее, чем mysqli. :-D

Dyin 13.01.2013 14:05

@jnrbsn вы согласны с Адамом в том, что он сказал?

Basit 02.02.2013 18:47

@Basit Да, я согласен со всем, что он сказал. Плюсы PDO определенно перевешивают минусы. Я больше не использую MySQLi.

jnrbsn 13.03.2013 22:12

В моем тестовый скрипт каждый метод проверяется 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).

Что такое ПГО? И быстрее на 33 секунды ?! Мне очень трудно в это поверить ...

Alix Axel 26.07.2011 08:15

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

PDO::quote() places quotes around the input string (if required) and escapes special characters within the input string, using a quoting style appropriate to the underlying driver.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Наконец то, кто знает и не отрицает факты жизни ...

Ihsan 02.05.2013 11:15

Другие вопросы по теме