Меню Закрыть

Php pdo fetch assoc

Содержание

Как уже говорилось в статье Как работать с PDO?, константы, задающие режим получения данных (наряду с передачей параметров напрямую в execute() ) делают PDO по-настоящему удобной библиотекой для работы с БД, а не просто еще одним (пусть и универсальным) API для доступа к базе данных. С помощью этих констант можно значительно сократить код многих рутинных операций, поскольку они позволяют получить данные сразу в нужном формате.

Хотя интересующие нас константы частично описываются на страницах документации, посвященных методам fetch() и fetchAll() , полный список приведен только на странице с общим списком констант PDO, что не кажется мне очень удобным, и может являться той причиной, по которой некоторые особенно интересные режимы получения данных оказались вне поля зрения большинства разработчиков. Я решил выделить интересующие нас константы из общего списка и разбить для удобства на несколько категорий, поскольку их количество впечатляет — ни много ни мало, а целых 25 штук!

Классика

Для начала перечислим константы, которые дублируют стандартное поведение теплых ламповых функций mysql. Все примеры даются с использованием функции var_export() .

PDO::FETCH_BOTH

аналог mysql_fetch_array() . Все данные возвращаются в дублированном виде — и с текстовыми индексами, и с цифровыми. Этот режим включен в PDO по умолчанию.

PDO::FETCH_NUM

снова старый знакомый, аналог mysql_fetch_row() . Только цифровые индексы:

PDO::FETCH_ASSOC

то же самое, аналог mysql_fetch_assoc() , только текстовые индексы.

PDO::FETCH_OBJ

аналог mysql_fetch_object() без указания имени класса, возвращает экземпляр stdClass

PDO::FETCH_LAZY

Эта константа настолько примечательна и ни на что не похожа, что я решил вынести её в отдельный раздел. Начнем с того, что возвращаемая с её помощью переменная является экземпляром особенного класса PDORow , причем этот объект наделён целым ворохом уникальных свойств:

  • Во-первых, эта переменная не содержит сами запрошенные данные, а отдаёт их по запросу (на что намекает название)
  • Во-вторых, помимо запрошенных данных, в объекте присутствует загадочная переменная, которая называется queryString и содержит SQL запрос(!) (что намекает о родственности этого класса PDOStatement):

Для пытливых — да, перезаписать queryString можно 🙂

  • В-третьих, эту переменную невозможно сохранить в сессии (или, другими словами — сериализовать)
  • В-четвертых, получать из неё данные можно как угодно, любым из трёх способов: через числовой индекс, ассоциативный, или обращаясь к свойству класса через ->
  • В-пятых, обращение к несуществующим свойствам не вызывает нотис Undefined property / index. Молча возвращается NULL .
  • В-шестых, эта переменная меняет своё состояние от последующих вызовов fetch() с другими константами. Плюс ко всему, эта константа не работает с fetchAll() , а только с fetch() .
  • Проведём пару экспериментов. Попробуем запросить относительно большой объём данных, и посмотрим, как меняется потребление памяти, и заодно проверим ещё пару утверждений:

    Как видно, этот код опрашивает нашу таблицу users, добавляя к строке мегабайтное поле. После этого мы получаем строку через эту константу — объём памяти не поменялся. Только после того, как мы присваиваем значение мегабайтного поля переменной — он увеличивается. Для контроля выводим имя из таблицы users. Затем получаем ещё одну строку, уже в одном из стандартных режимов. Видим, что объем памяти тут же подскакивает, в отличие от предыдущего случая. Экономия в первом случае налицо! Так же мы видим отсутствие нотиса и смену состояния $lazy после вызова fetch() .

    Из всей этой информации можно сделать вывод, что объект PDORow — это канал прямой связи с астралом resultSet-ом драйвера БД. И, не имея собственного состояния, попросту читает данные с текущей позиции курсора. Учитывая всё вышесказанное можно только удивляться, почему эта константа до сих пор так редко используется.

    Самое полезное

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

    Примечание: здесь и далее все примеры даются при включенном по умолчанию формате вывода PDO::FETCH_ASSOC

    PDO::FETCH_COLUMN

    Вытаскивает только одну колонку из результата. Соответственно, имеет смысл только при использовании с fetchAll() — и в этом случае возвращает сразу одномерный массив. Очень удобно.

    Дополнительным параметром можно указать номер выбираемой колонки. Если этот флаг используется сам по себе, то номер указывать нет смысла (надо сразу в запросе выбирать только одну колонку, которая и будет выведена), но если в комбинации с другими, то номер может оказаться полезным.

    PDO::FETCH_KEY_PAIR

    Малоизвестный, но довольно полезный режим, когда из двух запрошенных полей содержимое первого становится ключом, а второго — значением одномерного массива.

    Требователен к количеству колонок в запросе — их должно быть строго две

    PDO::FETCH_UNIQUE

    похож на предыдущий, но в качестве значения возвращает всю оставшуюся строку. C fetch() этот режим не возвращает ничего вразумительного, а вот с fetchAll() как раз получается такой, весьма востребованный режим. Главное, чтобы первой колонкой в запросе выбиралось уникальное поле — тогда оно будет использовано в качестве индекса возвращаемого массива, вместо обычной нумерации

    PDO::FETCH_GROUP

    Группирует значения по первой колонке. К примеру, нижеследующий код разобьёт пользователей на мальчиков и девочек, и положит их в разные массивы:

    То есть, этот режим идеально подходит для классической задачи "вывести события сгруппированные по дням" (или "вывести товары, сгруппированные по категориям"). Также может комбинироваться с PDO::FETCH_COLUMN :

    Объектное ориентирование

    Разумеется, простым stdObject возможности (я бы даже сказал — аппетиты) PDO по работе с объектами не исчерпываются. Дальше идет целая серия режимов для всевозможной манипуляции ими.

    PDO::FETCH_CLASS

    Создаёт объект указанного класса, заполняя его свойства данными из БД. Однако здесь, увы, начинаются неудобства и непоследовательность в работе вызывающих функций. Если для fetchAll() можно написать красиво и компактно

    то для fetch() приходится писать такую колбасу:

    Из-за того что fetch() не позволяет передать имя класса, мы вынуждены пользоваться setFetchMode() . А учитывая, что эта функция возвращает булево значение, а не ссылку на объект, мы не можем использовать method chaining. Пичаль. Также следует помнить, что в этом режиме PDO будет вызывать магический метод __set() если свойство, совпадающее с именем поля, не найдено в объекте. Для PHP это означает, что если в объекте отсутствует такой метод, то все колонки строки, полученной из БД, будут назначены переменным класса. Если же мы хотим присвоить значения только существующим переменным, то этот момент надо контролировать с помощью метода __set() . Например

    в то время как у класса с пустым __set() будут заполнены только существующие свойства:

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

    PDO::FETCH_CLASSTYPE

    Очень интересная константа. Представляет собой не самостоятельный режим получения данных, а флаг-модификатор, изменяющий поведение других режимов. При её использовании PDO будет брать имя класса из первой колонки полученных из БД данных. То есть, с её помощью код для fetch() можно сделать короче

    PDO::FETCH_PROPS_LATE

    Ещё один флаг-модификатор. По умолчанию PDO присваивает значения свойствам класса до вызова конструктора. При помощи же данной константы это поведение можно изменить — сначала будет вызываться конструктор:

    Читайте также:  В ворде исчезла панель инструментов 2007

    PDO::FETCH_INTO

    в отличие от PDO::FETCH_CLASS не создаёт новый объект, а обновляет существующий. Соответственно, в качестве параметра передается переменная с объектом. По очевидным причинам имеет смысл только с fetch()

    Как видно, fetch() возвращает тот же объект, что представляется мне несколько избыточным. Также, с сожалением приходится констатировать, что в отличие от PDO::FETCH_CLASS , этот режим не присваивает значения приватным свойствам.

    PDO::FETCH_SERIALIZE

    ещё один флаг для PDO::FETCH_CLASS . Должен возвращать объект, который хранился в БД в сериализованном виде. Конструктор не вызывается. На данный момент не работает. Должно быть что-то вроде такого

    Этот режим попил у меня крови изрядно. Описание у него самое невинное — "то же самое, что и PDO::FETCH_INTO, но объект передается в сериализованном массиве". А куда передавать-то? В параметры что ли? пробовал и так, и сяк — ничего не получалось. Только когда нашел юнит-тест, посвященный этому режиму, стало понятно, что объект должен придти из БД. Но всё равно не получается — пишет, "cannot unserialize class".

    В общем, предполагается, что этот режим должен создавать объект из сериализованного представления, хранящегося в БД. Но это не работает, поскольку при использовании этого метода из базы возвращается не то, что туда клали! Вместо исходного объекта возвращается внонимный класс, который содержит два свойства — одно с именем объекта, и второе с исходным объектом. В общем, мы с zerkms-ом покопались, и в итоге он накатал баг-репорт, https://bugs.php.net/bug.php? >

    Разное

    PDO::FETCH_FUNC

    для любителей замыканий. Работает только внутри fetchAll() . В параметры функции PDO передаёт переменные для каждого полученного поля, что может быть неудобным — нет доступа к именам полей, а только к значениям. К примеру, эмуляция работы PDO::FETCH_COLUMN:

    PDO::FETCH_NAMED

    почти то же самое, что PDO::FETCH_ASSOC , но с одним отличием. Много раз я встречал на форумах вопросы о том, как получить значения полей с одинаковыми именами из разных таблиц при джойне. Всегда ответ был один — писать алиасы руками в запросе или использовать цифровые индексы. А вот и ответ от PDO: получение данных в этом режиме аналогично PDO::FETCH_ASSOC, но если встречаются поля с одинаковыми именами, то все значения по очереди записываются во вложенный массив. Допустим, у нас есть таблицы users и companies, причем в обеих есть поле name. Если получать данные традиционным путём, то одно из полей будет съедено:

    Если же указать это флаг, то все значения колонок с совпадающими именами будут собраны во вложенном массиве в порядке поступления:

    Уж не знаю, насколько это востребованная фича, и насколько легче разбирать массив, нежели прописать алиасы в запросе.

    PDO::FETCH_BOUND

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

    Untested

    За неимением подходящей БД я не смог проверить работу еще нескольких констант. Но, на мой взгляд, их поведение достаточно очевидно и не нуждается в особом описании.

    • PDO::ATTR_FETCH_CATALOG_NAMES — возвращает имена колонок в формате "каталог.имя_колонки". Поддерживается не всеми драйверами.
    • PDO::ATTR_FETCH_TABLE_NAMES — возвращает имена колонок в формате "имятаблицы.имяколонки". Поддерживается не всеми драйверами.
    • PDO::FETCH_ORI_* — 6 функций по управлению курсором при получении данных из БД. Пример есть в документации

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

    Все предопределенные константы здесь

    PDO::FETCH_BOTH

    Аналог mysql_fetch_array() . Все данные возвращаются в дублированном виде, с текстовыми индексами и цифровыми. Этот режим включен в PDO по умолчанию.

    PDO::FETCH_NUM

    Аналог mysql_fetch_row() . Только цифровые индексы:

    PDO::FETCH_ASSOC

    Аналог mysql_fetch_assoc() Только текстовые индексы.

    PDO::FETCH_OBJ

    Аналог mysql_fetch_object() без указания имени класса, возвращает экземпляр stdClass

    PDO::FETCH_LAZY

    В этом режиме не тратится лишняя память, и к тому же к колонкам можно обращаться любым из трех способов — через индекс, имя, или свойство (через -> ). Недостатком же данного режима является то, что он не работает с fetchAll()

    PDO::FETCH_COLUMN

    Когда необходимо получить только одну колонку из результата. Соответственно, имеет смысл только при использовании с fetchAll() — и в этом случае возвращает сразу одномерный массив.

    PDO::FETCH_KEY_PAIR

    Малоизвестный, но очень полезный режим, когда из двух запрошенных полей содержимое первого становится ключом, а второго — значением одномерного массива.

    PDO::FETCH_UNIQUE

    Похож на предыдущий, но в качестве значения возвращает всю оставшуюся строку. C fetch() этот режим не возвращает ничего вразумительного, а вот с fetchAll() как раз получается такой, весьма востребованный режим. Главное, чтобы первой колонкой в запросе выбиралось уникальное поле — тогда оно будет использовано в качестве индекса возвращаемого массива, вместо обычной нумерации

    PDO::FETCH_GROUP

    Группирует значения по первой колонке. К примеру, нижеследующий код разобьёт пользователей на мальчиков и девочек, и положит их в разные массивы:

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

    PDO::FETCH_CLASS

    Создаёт объект указанного класса, заполняя его свойства данными из БД. Однако здесь, увы, начинаются неудобства и непоследовательность в работе вызывающих функций. Если для fetchAll() можно написать красиво и компактно

    то для fetch() приходится писать такую колбасу:

    Из-за того что fetch() не позволяет передать имя класса, мы вынуждены пользоваться setFetchMode() . А учитывая, что эта функция возвращает булево значение, а не ссылку на объект, мы не можем использовать method chaining. Также следует помнить, что в этом режиме PDO будет вызывать магический метод __set() если свойство, совпадающее с именем поля, не найдено в объекте. Для PHP это означает, что если в объекте отсутствует такой метод, то все колонки строки, полученной из БД, будут назначены переменным класса. Если же мы хотим присвоить значения только существующим переменным, то этот момент надо контролировать с помощью метода __set() . Например

    в то время как у класса с пустым __set() будут заполнены только существующие свойства:

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

    PDO::FETCH_CLASSTYPE

    Очень интересная константа. Представляет собой не самостоятельный режим получения данных, а флаг-модификатор, изменяющий поведение других режимов. При её использовании PDO будет брать имя класса из первой колонки полученных из БД данных. То есть, с её помощью код для fetch() можно сделать короче

    PDO::FETCH_PROPS_LATE

    Ещё один флаг-модификатор. По умолчанию PDO присваивает значения свойствам класса до вызова конструктора. При помощи же данной константы это поведение можно изменить — сначала будет вызываться конструктор:

    Читайте также:  Сколько может храниться вода в пластиковой бутылке

    PDO::FETCH_INTO

    В отличие от PDO::FETCH_CLASS не создаёт новый объект, а обновляет существующий. Соответственно, в качестве параметра передается переменная с объектом. По очевидным причинам имеет смысл только с fetch()

    Как видно, fetch() возвращает тот же объект, что представляется мне несколько избыточным. Также, с сожалением приходится констатировать, что в отличие от PDO::FETCH_CLASS , этот режим не присваивает значения приватным свойствам.

    PDO::FETCH_SERIALIZE

    Ещё один флаг для PDO::FETCH_CLASS . Должен возвращать объект, который хранился в БД в сериализованном виде. Конструктор не вызывается. На данный момент не работает. Должно быть что-то вроде такого

    PDO::FETCH_FUNC

    Для любителей замыканий. Работает только внутри fetchAll() . В параметры функции PDO передаёт переменные для каждого полученного поля, что может быть неудобным — нет доступа к именам полей, а только к значениям. К примеру, эмуляция работы PDO::FETCH_COLUMN :

    PDO::FETCH_NAMED

    Почти то же самое, что PDO::FETCH_ASSOC , но с одним отличием. Много раз я встречал на форумах вопросы о том, как получить значения полей с одинаковыми именами из разных таблиц при джойне. Всегда ответ был один — писать алиасы руками в запросе или использовать цифровые индексы. А вот и ответ от PDO: получение данных в этом режиме аналогично PDO::FETCH_ASSOC , но если встречаются поля с одинаковыми именами, то все значения по очереди записываются во вложенный массив. Допустим, у нас есть таблицы users и companies, причем в обеих есть поле name. Если получать данные традиционным путём, то одно из полей будет съедено:

    Если же указать это флаг, то все значения колонок с совпадающими именами будут собраны во вложенном массиве в порядке поступления:

    PDO::FETCH_BOUND

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

    Материал подготовлен на основе официальной статьи .

    (PHP 5 >= 5.1.0, PHP 7, PECL pdo >= 0.1.0)

    PDOStatement::fetch — Извлечение следующей строки из результирующего набора

    Описание

    Извлекает следующую строку из результирующего набора объекта PDOStatement. Параметр fetch_style определяет, в каком виде PDO вернет эту строку.

    Список параметров

    Определяет, в каком виде следующая строка будет возвращена в вызывающий метод. Это может быть одна из констант PDO::FETCH_*. По умолчанию PDO::ATTR_DEFAULT_FETCH_MODE (что равносильно PDO::FETCH_BOTH).

    PDO::FETCH_ASSOC: возвращает массив, индексированный именами столбцов результирующего набора

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

    PDO::FETCH_BOUND: возвращает TRUE и присваивает значения столбцов результирующего набора переменным PHP, которые были привязаны к этим столбцам методом PDOStatement::bindColumn()

    PDO::FETCH_ >fetch_style включает в себя атрибут PDO::FETCH_CLASSTYPE (например, PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE), то имя класса, от которого нужно создать объект, будет взято из первого столбца.

    PDO::FETCH_INTO: обновляет существующий объект запрошенного класса, присваивая значения столбцов результирующего набора именованным свойствам объекта

    PDO::FETCH_LAZY: комбинирует PDO::FETCH_BOTH и PDO::FETCH_OBJ, создавая новый объект со свойствами, соответствующими именам столбцов результирующего набора

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

    PDO::FETCH_NUM: возвращает массив, индексированный номерами столбцов (начиная с 0)

    PDO::FETCH_OBJ: создает анонимный объект со свойствами, соответствующими именам столбцов результирующего набора

    PDO::FETCH_PROPS_LATE: если используется с PDO::FETCH_CLASS, конструктор класса будет вызван перед назначением свойств из значений столбцов.

    Для объектов PDOStatement представляющих прокручиваемый курсор, этот параметр определяет, какая строка будет возвращаться в вызывающий метод. Значением параметра должна быть одна из констант PDO::FETCH_ORI_*, по умолчанию PDO::FETCH_ORI_NEXT. Чтобы запросить прокручиваемый курсор для запроса PDOStatement, необходимо задать атрибут PDO::ATTR_CURSOR со значением PDO::CURSOR_SCROLL во время подготовки запроса методом PDO::prepare() .

    Для объектов PDOStatement, представляющих прокручиваемый курсор, параметр cursor_orientation которых принимает значение PDO::FETCH_ORI_ABS, эта величина означает абсолютный номер строки, которую необходимо извлечь из результирующего набора.

    Для объектов PDOStatement, представляющих прокручиваемый курсор, параметр cursor_orientation которых принимает значение PDO::FETCH_ORI_REL, эта величина указывает, какая строка относительно текущего положения курсора будет извлечена функцией PDOStatement::fetch() .

    Возвращаемые значения

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

    Примеры

    Пример #1 Извлечение строк в разных режимах выборки

    = $dbh -> prepare ( "SELECT name, colour FROM fruit" );
    $sth -> execute ();

    /* Примеры различных режимов работы PDOStatement::fetch */
    print( "PDO::FETCH_ASSOC: " );
    print( "Возвращаем следующую строку в виде массива, индексированного именами столбцов
    " );
    $result = $sth -> fetch ( PDO :: FETCH_ASSOC );
    print_r ( $result );
    print( "
    " );

    print( "PDO::FETCH_BOTH: " );
    print( "Возвращаем следующую строку в виде массива, индексированного как именами столбцов, так и их номерами
    " );
    $result = $sth -> fetch ( PDO :: FETCH_BOTH );
    print_r ( $result );
    print( "
    " );

    print( "PDO::FETCH_LAZY: " );
    print( "Возвращаем следующую строку в виде анонимного объекта со свойствами, соответствующими столбцам
    " );
    $result = $sth -> fetch ( PDO :: FETCH_LAZY );
    print_r ( $result );
    print( "
    " );

    print( "PDO::FETCH_OBJ: " );
    print( "Возвращаем следующую строку в виде анонимного объекта со свойствами, соответствующими столбцам
    " );
    $result = $sth -> fetch ( PDO :: FETCH_OBJ );
    print $result -> name ;
    print( "
    " );
    ?>

    Результат выполнения данного примера:

    Пример #2 Выборка строк средствами прокручиваемого курсора

    function readDataForwards ( $dbh ) <
    $sql = ‘SELECT hand, won, bet FROM mynumbers ORDER BY BET’ ;
    try <
    $stmt = $dbh -> prepare ( $sql , array( PDO :: ATTR_CURSOR => PDO :: CURSOR_SCROLL ));
    $stmt -> execute ();
    while ( $row = $stmt -> fetch ( PDO :: FETCH_NUM , PDO :: FETCH_ORI_NEXT )) <
    $data = $row [ 0 ] . " " . $row [ 1 ] . " " . $row [ 2 ] . "
    " ;
    print $data ;
    >
    $stmt = null ;
    >
    catch ( PDOException $e ) <
    print $e -> getMessage ();
    >
    >
    function readDataBackwards ( $dbh ) <
    $sql = ‘SELECT hand, won, bet FROM mynumbers ORDER BY bet’ ;
    try <
    $stmt = $dbh -> prepare ( $sql , array( PDO :: ATTR_CURSOR => PDO :: CURSOR_SCROLL ));
    $stmt -> execute ();
    $row = $stmt -> fetch ( PDO :: FETCH_NUM , PDO :: FETCH_ORI_LAST );
    do <
    $data = $row [ 0 ] . " " . $row [ 1 ] . " " . $row [ 2 ] . "
    " ;
    print $data ;
    > while ( $row = $stmt -> fetch ( PDO :: FETCH_NUM , PDO :: FETCH_ORI_PRIOR ));
    $stmt = null ;
    >
    catch ( PDOException $e ) <
    print $e -> getMessage ();
    >
    >

    print "Читаем в прямой последовательности:
    " ;
    readDataForwards ( $conn );

    print "Читаем в обратной последовательности:
    " ;
    readDataBackwards ( $conn );
    ?>

    Результат выполнения данного примера:

    Пример #3 Порядок конструкторов

    Если объекты забираются с помощью PDO::FETCH_CLASS, сначала присваиваются свойства объекта, а следом вызывается конструктор объекта. Если также задано PDO::FETCH_PROPS_LATE, этот порядок меняется на обратный.

    Читайте также:  P4pe x se драйвер

    class Person
    <
    private $name ;

    public function __construct ()
    <
    $this -> tell ();
    >

    public function tell ()
    <
    if (isset( $this -> name )) <
    echo "Я < $this ->name > .
    " ;
    > else <
    echo "У меня еще нет имени.
    " ;
    >
    >
    >

    $sth = $dbh -> query ( "SELECT * FROM people" );
    $sth -> setFetchMode ( PDO :: FETCH_CLASS , ‘Person’ );
    $person = $sth -> fetch ();
    $person -> tell ();
    $sth -> setFetchMode ( PDO :: FETCH_CLASS | PDO :: FETCH_PROPS_LATE , ‘Person’ );
    $person = $sth -> fetch ();
    $person -> tell ();
    ?>

    Результатом выполнения данного примера будет что-то подобное:

    Смотрите также

    • PDO::prepare() — Подготавливает запрос к выполнению и возвращает связанный с этим запросом объект
    • PDOStatement::execute() — Запускает подготовленный запрос на выполнение
    • PDOStatement::fetchAll() — Возвращает массив, содержащий все строки результирующего набора
    • PDOStatement::fetchColumn() — Возвращает данные одного столбца следующей строки результирующего набора
    • PDOStatement::fetchObject() — Извлекает следующую строку и возвращает ее в виде объекта
    • PDOStatement::setFetchMode() — Устанавливает режим выборки по умолчанию для объекта запроса

    User Contributed Notes 24 notes

    WARNING:
    fetch() does NOT adhere to SQL-92 SQLSTATE standard when dealing with empty datasets.

    Instead of setting the errorcode class to 20 to indicate "no data found", it returns a class of 00 indicating success, and returns NULL to the caller.

    This also prevents the exception mechainsm from firing.

    Programmers will need to explicitly code tests for empty resultsets after any fetch*() instead of relying on the default behavior of the RDBMS.

    I tried logging this as a bug, but it was dismissed as "working as intended". Just a head’s up.

    When using PDO::FETCH_COLUMN in a while loop, it’s not enough to just use the value in the while statement as many examples show:

    while ( $row = $stmt -> fetch ( PDO :: FETCH_COLUMN )) <
    print $row ;
    >
    ?>

    If there are 5 rows with values 1 2 0 4 5, then the while loop above will stop at the third row printing only 1 2. The solution is to either explicitly test for false:

    while (( $row = $stmt -> fetch ( PDO :: FETCH_COLUMN )) !== false ) <
    print $row ;
    >
    ?>

    Or use foreach with fetchAll():

    foreach ( $stmt -> fetchAll ( PDO :: FETCH_COLUMN ) as $row ) <
    print $row ;
    >
    ?>

    Both will correctly print 1 2 0 4 5.

    Someone’s already pointed out that PDO::CURSOR_SCROLL isn’t supported by the SQLite driver. It’s also worth noting that it’s not supported by the MySQL driver either.

    In fact, if you try to use scrollable cursors with a MySQL statement, the PDO::FETCH_ORI_ABS parameter and the offset given to fetch() will be silently ignored. fetch() will behave as normal, returning rows in the order in which they came out of the database.

    It’s actually pretty confusing behaviour at first. Definitely worth documenting even if only as a user-added note on this page.

    When fetching an object, the constructor of the class is called after the fields are populated by default.

    PDO::FETCH_PROPS_LATE is used to change the behaviour and make it work as expected — constructor be called _before_ the object fields will be populated with the data.

    = $PDO -> query ( ‘select id from table’ );
    $a -> setFetchMode ( PDO :: FETCH_CLASS | PDO :: FETCH_PROPS_LATE , ‘ClassName’ );
    $obj = $a -> fetch ();
    ?>

    http://bugs.php.net/bug.php? >

    A quick one liner to get the first entry returned. This is nice for very basic queries.

    = current ( $db -> query ( "select count(*) from table" )-> fetch ());
    ?> php

    Here is quick note for developers that use the PDO SQLite Driver:

    The PDO SQLite driver does not support cursors, so using the PDO::CURSOR_SCROLL Attribute, will not work when using the PDO SQLite driver. For example:

    // Assuming $Handle Is a PDO Handle.
    $Statement = $Handle -> query ( $sqlStatement , array( PDO :: ATTR_CURSOR => PDO :: CURSOR_SCROLL ) );

    ?>

    What is even worse is that PDO::prepare will NOT throw an Exception when it fails to prepare the query, even when the error mode is set to throw Exceptions, and will instead return a Boolean False!

    Not only do I consider this a poor design choice, but also its a real shame that this is not documented anywhere in the manual — in fact the manual is not clear on what Attributes are supported by which drivers and which are not so developers are left to play a classic game of guess.

    I hope this saves some developers some headaches.

    Because MySQL does not currently support the use of cursors, the $cursor_offset feature cannot work when using PDO to access a MySQL database.

    If you are tring to arbitrarily access a specific record or group of records in a MySQL database recordset, you might want to consider using the LIMIT clause of the SELECT statement to achieve this e.g. LIMIT 5,3 to return just the 6th,7th & 8th records — 3 records starting at index 5 (which is the 6th record).

    this is just On reminder note about Second parameter -cursor_oriantation-

    PDO::FETCH_ORI_NEXT :-
    Fetch the next row in the result set. Valid only for scrollable cursors.

    PDO::FETCH_ORI_PRIOR :-
    Fetch the previous row in the result set. Valid only for scrollable cursors.

    PDO::FETCH_ORI_FIRST :-
    Fetch the first row in the result set. Valid only for scrollable cursors.

    PDO::FETCH_ORI_LAST :-
    Fetch the last row in the result set. Valid only for scrollable cursors.

    PDO::FETCH_ORI_ABS :-
    Fetch the requested row by row number from the result set. Valid only for scrollable cursors.

    PDO::FETCH_ORI_REL :-
    Fetch the requested row by relative position from the current position of the cursor in the result set. Valid only for scrollable cursors.

    If you to use a new instance of a class for a record you can use:

    include_once( "user.class" );
    $sth = $db -> prepare ( "SELECT * FROM user WHERE > );

    /* create instance automatically */
    $sth -> setFetchMode ( PDO :: FETCH_CLASS , ‘user’ );
    $sth -> execute ();
    $user = $sth -> fetch ( PDO :: FETCH_CLASS );
    $sth -> closeCursor ();
    print ( $user -> id );

    /* or create an instance yourself and use it */
    $user = new user ();
    $sth -> setFetchMode ( PDO :: FETCH_INTO , $user );
    $sth -> execute ();
    $user = $sth -> fetch ( PDO :: FETCH_INTO );
    $sth -> closeCursor ();
    print ( $user -> id );
    ?>

    Рекомендуем к прочтению

    Добавить комментарий

    Ваш адрес email не будет опубликован.