Что такое PDO?
Во-первых, подумайте о том, почему вы выбираете PDO
PDO
Это уровень Абстракции доступа к данным. Абстракция двояка: одна хорошо известна, но не очень важна. Другое неясно, но самое важное. Как всем известно PDO
Он обеспечивает единый интерфейс для различных баз данных. Хотя сама функция огромна, она не слишком важна для фиксированных программ. Почти все программы используют единую внутреннюю базу данных. Хотя ходят некоторые слухи, они меняют отдельные строки. PDO
Конфигурация для переключения внутренних баз данных невозможна-из – за другого SQL
Стиля (для этой цели вам нужно использовать образы, подобные DQL
Такому среднему языку запросов). Так что для обычных языков запросов LAMP
Для разработчика это тривиально, и для него PDO знаком только с этим. mysql(i)_query()
Еще одна более сложная версия функции. Но на самом деле это не так. Он богат другими функциями. DO
Не только абстрагирует API базы данных, но и абстрагирует основные операции. В противном случае это должно быть
- Безопасность (имеются подготовленные заявления)
- Доступность (многие вспомогательные функции могут автоматически выполнять рутинные операции)
- Возможность повторного использования (Унифицированный API для доступа к большому количеству баз данных, от SQLITE до oracle)
Пожалуйста, обратите внимание, что, хотя PDO
Это лучший собственный драйвер базы данных, но для современных веб-приложений рассмотрите возможность использования построителя запросов ORM
Или используйте его с другими библиотеками на более высоком уровне абстракции, только иногда с собственными PDO. Хорошие ПЗУ, например Доктрина
, Красноречивый
, Красная фасоль
и Yii::AR
. Aura.SQL
Это хороший пример использования оболочек PDO со многими дополнительными функциями. В любом случае, хорошо сначала разобраться в основных инструментах. Так что давайте начнем.
подключение DSN
PDO
Есть звонок. DSN
Это не сложно – PDO требует, чтобы вы вводили разные конфигурации в трех разных местах, а не простой список опций.
драйвер базы данных
,хост
,имя бд(схемы)
икодировка
И редко используетсяпорт
иunix_socket
НастройкаDSN
имя пользователя
ипароль
Настройка метода построения- Все остальные конфигурации находятся в массиве опций
среди DSN
Строки, разделенной точкой с запятой, разделенной точкой с запятой параметр=значение
Пары Ключ-значение состоят из имени драйвера и двоеточия:
mysql:host=localhost;dbname=test;port=3306;charset=utf8mb4 driver^ ^colon ^param=value pair ^semicolon
Обратите внимание, что важно соблюдать правильный формат – вы не можете использовать пробелы, кавычки и другие символы в DSN, вы можете использовать только параметры, значения и разделители. Как показано в руководстве.
Вот пример:
$host = '127.0.0.1'; $db = 'test'; $pass = 'root'; $charset = 'utf8mb4'; $dsn = "mysql:host={$host};dbnamej={$db};charset={$charset}"; $options = [ PDO::ATR_ERRMODE => PDO::ERRMODE_EXECPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]; try { $pdo = new \PDO($dsn, $user, $pass, $options); } catch (\PDOException $e) { }
Установив все вышеперечисленные атрибуты переменной, мы будем в $pdo
Получать правильный в переменной PDO
Пример. Расширение Важного уведомления пользователя с помощью старого Mysql
- Отличается
mysql_*
Функцией, которую можно использовать в любом месте кода.pdo
Экземпляры хранятся в переменной, что означает, что доступ к ним возможен только внутри функции. Поэтому они должны передаваться через параметры функций или использовать более продвинутые методы, такие как контейнеры IOC. - Соединения создаются только один раз. Не создавайте соединения в функциях, конструкторах классов, иначе будет создано несколько соединений, что приведет к простою службы базы данных. Поэтому необходимо создать уникальное соединение.
PDO
Экземпляры для использования всего сценария. (Для режима FPM) - Настройка наборов символов через DSN очень важна – это единственно правильный способ, потому что он сообщает PDO, какие наборы символов будут использоваться. Поэтому забудьте передать
Запрос
ФункциюИМЕНА НАБОРОВ
Или черезPDO::MYSQL_ATTR_INIT_COMMAND
Только когда версия PHP слишком низкая (ниже 5.3.6), ее можно использоватьИМЕНА НАБОРОВ
Запрос и закрыть режим моделирования.
Более подробную информацию о соединениях можно посмотреть в разделе подключение MySQL
Выполните запрос PDO:: query ()
Используйте PDO
Есть два способа выполнить запрос. Если в запросе не используются переменные, вы можете использовать их PDO::query
Метод. Он запускает запрос и возвращает PDOStatement
Объекты класса и mysql_query
Возвращаемые ресурсы примерно одинаковы, особенно операции, из которых получены фактические записи:
$stmt = $pdo->query('SELECT name FROM users'); while ($row = $stmt->fetch()) { echo $row['name'] . "\n"; }
также query()
Метод позволяет нам аккуратно подключаться ВЫБРАТЬ
Запрос, как показано ниже.
Предварительная обработка для предотвращения внедрения SQL
Откажитесь от привычного mysql_query()
Основной причиной объединения функций в домен строгих объектов данных является PDO
Операторы предварительной обработки готовы к использованию из коробки. Если переменные должны использоваться в операторах, то операторы предварительной обработки являются единственным способом правильного выполнения. Причина, по которой они так важны, подробно объясняется в Руководстве Автостопщика по предотвращению инъекций SQL. Для выполнения запросов, если вы используете хотя бы одну переменную, вы должны заменить ее заполнителями. Подготовьтесь к выполнению инструкций, а затем передайте переменные для выполнения отдельно. Короче говоря, это не так сложно, как кажется. В большинстве случаев вам просто нужно использовать функции. подготовьте
и выполните
. Во-первых, вам нужно изменить запрос, чтобы добавить заполнители, в которых используются переменные, например
$sql = "SELECT * FROM users WHERE email = '{$email}' AND status = '{$status}'";
Изменить на
$sql = "SELECT * FROM users where email = ? and status = ?";
возможно
$sql = "SELECT * FROM users where email = :email AND status = :status";
Будьте осторожны ДЛЯ
Позиции (?) и именования (: электронная почта) поддерживаются заполнители, которые всегда начинаются с двоеточия и могут использовать только буквы, цифры и подчеркивания. Примечание также Кавычки нельзя использовать вокруг заполнителей . Когда запрос использует заполнители, он должен использовать их PDO::prepare()
Предварительная обработка метода. Этот метод возвращает то же самое, что и тот, который мы обсуждали выше. PDOStatement
Объект, но данные не привязаны. Наконец, вы должны использовать PDOStatement
Object execute()
Метод выполняет запрос и передает параметры в виде массива. После этого данные о результатах могут быть получены из заявления (если применимо).
$stmt = $pdo->prepare("SELECT * FROM users WHERES email = ? AND status = ?"); $stmt->execute([$email, $status]) $user = $stmt->fetch(); // or $stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email AND status = :status"); $stmt->execute(['email' => $email, 'status' => $status]); $user = $stmt->fetch();
Как вы можете видеть, заполнители, вам нужно предоставить массив индексов. Именованные заполнители, вам необходимо предоставить ассоциативный массив, а ключи должны соответствовать заполнителям в запросах. Вы не можете смешивать заполнители и именованные заполнители в одном запросе. Заполнители местоположения позволяют писать более короткий код, но они чувствительны к порядку параметров (который должен соответствовать порядку параметров в запросе). Хотя имена заполнителей делают код более длинным, они допускают привязку случайных параметров. Также обратите внимание, что, хотя существуют распространенные недоразумения, существуют массивы ключей :
В этом нет необходимости. После выполнения результаты могут быть получены с помощью поддерживаемых методов.
Дополнительные примеры доступны [https://php delusions.net/pdo_…].
Привязка параметров
Передайте данные в execute()
(Как показано выше) По умолчанию этот метод следует считать наиболее удобным способом. Если вы используете этот метод, все параметры будут привязаны к строкам (если вы используете нулевые значения, вы будете использовать SQL NULL для отправки запросов), и в большинстве случаев проблем не возникает. Иногда, однако, лучше указать тип. Может быть, следующим образом:
- Откройте ПРЕДЕЛЬНЫЕ предложения в режиме эмуляции (или другие предложения SQL, которые не принимают строковые операнды)
- Сложные специальные запросы со специальными планами запросов, на которые могут повлиять неправильные типы операндов
- Определенные типы столбцов, такие как
bigint
логическое значение
Точные операнды должны быть привязаны (для того, чтобыBIGINT
Привязать кPDO::PARAM_INT
Должны основываться наmysqlnd
)
В этом случае необходимо использовать явные привязки, которые можно использовать из bindvalue()
и bindParam()
Выберите одну из двух функций. Рекомендуется первое. Это не похоже на bindParam()
У него есть некоторые побочные эффекты.
Часть запроса, которая может быть привязана
Важно знать, какие части запроса можно связать с параметрами, а какие нельзя использовать. На самом деле этот список очень короткий: могут быть связаны только строки и числовые литералы. Пока ваши данные могут быть представлены в запросе в виде чисел или строк в кавычках, они могут быть связаны. Во всех остальных случаях вы не можете его использовать. PDO
Предварительно обработанные операторы: ни идентификаторы, ни списки, разделенные запятыми, ни часть текстовой строки в кавычках, ни любая другая часть запроса не могут быть связаны с предварительно обработанными операторами Наиболее распространенные варианты использования можно просмотреть в разделе ответов этой главы ()
Предварительная обработка, многократное выполнение
Иногда вы можете использовать предварительную обработку для выполнения готовых запросов много раз, быстрее, чем выполнять одни и те же запросы снова и снова, потому что она анализирует запросы только один раз. Если вы можете выполнять инструкции предварительной обработки в другом экземпляре PHP, эта функция очень полезна, но это не так. Он только повторяет один и тот же запрос в одном и том же экземпляре, что очень полезно в обычных PHP-скриптах. Меньше используется и ограничивает эту функцию для повторных вставок и обновлений.
$data = [ 1 => 1000, 2 => 200, 3 => 200, ]; $stmt = $pdo->prepare('UPDATE users SET bonus = bonus + ? where id = ?'); foreach ($data as $id => $bonus) { $stmt->execute([$bonus, $id]); }
Обратите внимание, что эта функция несколько завышена. Это не только обсуждается, но и повышение производительности не очень существенно – иногда это происходит при анализе запросов. Быстрый. А повышение производительности может быть достигнуто только при отключении режима моделирования.
Выполните команду ВЫБРАТЬ ВСТАВИТЬ ОБНОВИТЬ УДАЛИТЬ
В этих запросах нет ничего особенного. Они одинаковы для PDO. Не имеет значения, какой запрос запускать. Как показано выше, предварительно обработанные запросы с заполнителями необходимо подготовить, передать в переменных и выполнить. УДАЛИТЬ
и ВЫБРАТЬ
Процесс в основном один и тот же. Единственное отличие состоит в том, что( DML
Запросы не возвращают никаких данных), вы можете использовать метод цепочки, вызвать выполнить()
и подготовить()
.
$sql = "UPDATE users SET name = ? where id = ?"; $pdo->prepare($sql)->execute([$name, $id]);
Однако, как только вы получите количество влиятельных строк, код будет таким же, как и три скучные строки кода:
$stmt = $pdo->prepare("DELETE FROM goods where category = ?"); $stmt->execute([$cat]); $deleted = $stmt->rowCount();
Дополнительные примеры можно найти в отдельной статье.
Получение данных для каждого из состояний
Теперь, когда мы увидели эту функцию, давайте рассмотрим ее поближе. Он берет одну строку данных из базы данных и перемещает внутренний указатель в результирующем наборе. Поэтому последующие вызовы функции будут возвращать все строки одну за другой. mysql_fetch_array()
Почти то же самое, но немного отличается в рабочем режиме: вместо множества различных функций( mysql_fetch_assoc ()
| mysql_fetch_row Есть только один способ сделать это, но его поведение может быть изменено параметром.
PDO Существует множество моделей приобретения, которые мы подробно обсудим позже. Вот несколько простых примеров:
PDO::FETCH_NUM
Возвращает массив индексовPDO::FETCH_ASSOC
Возвращает ассоциативный массивPDO::FETCH_BOTH
Оба вышеперечисленных параметра включаютPDO::FETCH_OBJ
Возвращаемый объектPDO::FETCH_LAZY
Разрешите три метода (массив индексов, ассоциативный массив, объект) без дополнительных затрат памяти.
Как видно из вышесказанного, это необходимо использовать в двух ситуациях:
Когда требуется только одна строка, извлекается только одна строка
Получите строку из оператора в виде ассоциативного массива
- Когда нам нужно обработать возвращенные данные перед их использованием, в этом случае мы должны выполнить цикл while, как показано выше.
Другим полезным шаблоном является PDO::FETCH_CLASS
Вы можете создать объект определенного класса
$news = $pdo->query("select * from news")->fetchAll(PDO::FETCH_CLASS, 'News');
Будет сгенерирован массив объектов класса новостей, а свойства класса будут заданы путем возврата значений. Обратите внимание, что в этом режиме:
- Свойство задается до построения метода
- Все неопределенные свойства вызываются
__set
Магическими методами - Без метода
__set
будут созданы новые свойства - Частная собственность также установлена, что немного удивительно, но очень удобно.