Что такое код sybase_fetch_row

Содержание

sybase_fetch_assoc

(PHP 4 >= 4.3.0, PHP 5)

sybase_fetch_assoc — Fetch a result row as an associative array

Эта функция УДАЛЕНА в PHP 7.0.0.

Описание

sybase_fetch_assoc() is a version of sybase_fetch_row() that uses column names instead of integers for indices in the result array. Columns from different tables with the same names are returned as name, name1, name2, . nameN.

An important thing to note is that using sybase_fetch_assoc() is NOT significantly slower than using sybase_fetch_row() , while it provides a significant added value.

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

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

Returns an array that corresponds to the fetched row, or FALSE if there are no more rows.

Примечания

Замечание: Эта функция доступна только при использовании интерфейса к Sybase библиотеки CT, но не библиотеки DB.

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

  • sybase_fetch_row() — Get a result row as an enumerated array
  • sybase_fetch_array() — Fetch row as array
  • sybase_fetch_object() — Fetch a row as an object

sybase_fetch_array не может захватить несколько строк

Я хочу захватить 5 записей из базы данных sybase. Я использую sybase_fetch_array()

Я могу запустить sql через Interactive SQL, и он работает, но когда я var_dump($value) результат получается всего одна строка. Я уже пробовал:

который тоже не работает.

$ value — это простой массив. Если вы посмотрели учебники PHP, вы увидите, что способ индексирования в массив — это смещение, а не имя хэш-поля. Например, я печатаю значения полей строки таблицы в макет таблицы, где имена полей — это event_id (0), event_name (1), event_time (2), sc_id (3) и т. Д.:

Что такое код sybase_fetch_row

(PHP 3, PHP 4 , PHP 5)

sybase_fetch_row — Get a result row as an enumerated array

Description array sybase_fetch_row ( resource result )

Returns an array that corresponds to the fetched row, or FALSE if there are no more rows.

sybase_fetch_row() fetches one row of data from the result associated with the specified result identifier. The row is returned as an array. Each result column is stored in an array offset, starting at offset 0.

Subsequent call to sybase_fetch_row() would return the next row in the result set, or FALSE if there are no more rows.

Таблица 1. Data types

PHP Sybase
string VARCHAR, TEXT, CHAR, IMAGE, BINARY, VARBINARY, DATETIME
int NUMERIC (w/o precision), DECIMAL (w/o precision), INT, BIT, TINYINT, SMALLINT
float NUMERIC (w/ precision), DECIMAL (w/ precision), REAL, FLOAT, MONEY
NULL NULL

Just a simple example modified from the sybase_fetch_array():

sybase example
= sybase_connect ( «sybtest» , «sa» , «teacher» );
$q = sybase_query ( «select name from syslogins» , $db );
while( $row = sybase_fetch_row ( $q )) <
while(list( $k , $v ) = each ( $row )) <
echo » \$ row [ $k ] => $v \n » ;
>
>
?>

$row[0] => dnld
$row[0] => edi
$row[0] => oes
$row[0] => oesuseradmin
$row[0] => rpts
$row[0] => sa
$row[0] => upld

Что такое код sybase_fetch_row

(PHP 3, PHP 4, PHP 5)

sybase_fetch_row — Get a result row as an enumerated array

Description array sybase_fetch_row ( resource result )

Returns an array that corresponds to the fetched row, or FALSE if there are no more rows.

sybase_fetch_row() fetches one row of data from the result associated with the specified result identifier. The row is returned as an array. Each result column is stored in an array offset, starting at offset 0.

Subsequent call to sybase_fetch_row() would return the next row in the result set, or FALSE if there are no more rows.

Таблица 1. Data types

PHP Sybase
string VARCHAR, TEXT, CHAR, IMAGE, BINARY, VARBINARY, DATETIME
int NUMERIC (w/o precision), DECIMAL (w/o precision), INT, BIT, TINYINT, SMALLINT
float NUMERIC (w/ precision), DECIMAL (w/ precision), REAL, FLOAT, MONEY
NULL NULL

Пред. Начало След.
sybase_fetch_object Уровень выше sybase_field_seek

Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:

Что такое код sybase_fetch_row

sybase_affected_rows — возвращает число строк, измененных последним запросом

Описание

int sybase_affected_rows (int [link_identifier] );

Возвращает: Число строк,измененных последним запросом.

Функция sybase_affected_rows() возвращает число строк, участвовавших в запросе вида INSERT, UPDATE или DELETE к серверу, указанному с помощью идентификтора соединения (link_identifier). Если идентификатор не задан, используется соединение, открытое последним.

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

sybase_close

sybase_close — завершает соединение с Sybase

Описание

int sybase_close (int link_identifier);

возвращет: true — в случае успеха, false — в случае ошибки

Функция sybase_close() завершает соединение с базой данных Sybase, обозначенное с помощью идентификатора соединения. Если он не указан, используется соединение, открытое последним.

Отметим, что вызов этой функции не является обязательным, т.к. временные соединения закрываются автоматически после окончания выполнения скрипта.

Функция sybase_close() не завершает постоянные соединения, открытые с помощью sybase_pconnect().

sybase_connect

sybase_connect — устанавливает соединение с Sybase — сервером

Описание

int sybase_connect (string servername, string username, string password);

Возвращает: В случае успеха: идентификатор соединения (положительное число), в противном случае — false.

Функция sybase_connect() устанавливает соединение с Sybase-сервером. Параметр ‘servername’ должен содержать существующее имя сервера, определенное в файле ‘interfaces’.

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

Соединение с сервером будет закрыто после завершения скрипта или раньше, посредством явного вызова функции sybase_close().

sybase_data_seek

sybase_data_seek — перемещает внутренний указатель записей

Описание

int sybase_data_seek (int result_identifier, int row_number);

Возвращает: true -в случае успеха, иначе — false

Функция sybase_data_seek() перемещает внутренний указатель в результирующем наборе записей, заданном с помощью идентификатора result_identifier, на строку с номером row_number. При последующем вызове функции sybase_fetch_row() будет извлечена эта строка.

Смотри также: sybase_data_seek().

sybase_fetch_array

sybase_fetch_array — извлекает строку в виде массива

Описание

int sybase_fetch_array (int result);

Возвращает: Массив, содержащий извлеченную из набора данных строку или false — если строк больше нет.

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

Необходимо отметить, что функция sybase_fetch_array() работат НЕ намного МЕДЛЕННЕЕ, чем sybase_fetch_row(), и предоставляет дополнительные возможности по сравнению с последней.

sybase_fetch_field

sybase_fetch_field —получает информацию о столбце из набора данных

Description

object sybase_fetch_field (int result, int field_offset);

Возвращает объект, содержащий информацию о столбце

Функцию sybase_fetch_field() можно использовать для получения данных о столбцах результирующего набора result. Если смещение (номер) столбца в таблице (field_offset) не указано, то при каждом вызове sybase_fetch_field() будет извлекаться информация о следующем по порядку столбце.

Свойства объекта:

  • name — имя столбца. Если столбец является вычслимым, то это свойство принимает значение computed#N, где #N — это порядковый номер;
  • column_source — таблица, которой принадлежит данный столбец;
  • max_length — максимальная длина столбца;
  • numeric — 1, если столбец — числовой;

sybase_fetch_object

sybase_fetch_object —извлекает строку в виде объекта

Описание

int sybase_fetch_object (int result);

Возвращает: Объект, свойства которого соответствуют извлеченной из набора данных строке, или false — если сторк больше нет.

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

С точки зрения скорости выполнения эта функция идентична sybase_fetch_array(), и работает практически также быстро, как и sybase_fetch_row() (разница в скорости незначительна).

sybase_fetch_row

sybase_fetch_row — получает строку в виде пронумерованного массива

Описание

array sybase_fetch_row (int result);

Возвращает: Массив, соответствующий извлеченной строку, или false — если строк больше нет.

Функция sybase_fetch_row() извлекает строку данных из результирующего набора, заданного идентификатором result .Строка возвращается в виде массива. Каждый столбец хранится в виде элемента массива. Нумерация элементов начинается с 0.

Последующий вызов функции sybase_fetch_rows() вернет следующую строку запроса, или false, если строк больше нет.

sybase_field_seek

sybase_field_seek — указывает смещение (номер) столбца в строке

Описание

int sybase_field_seek (int result, int field_offset);

Переходит к указанному столбцу. Если при следующем вызове sybase_fetch_field() не будет указан конкретный номер столбца, то будет возвращен этот столбец.

sybase_free_result

sybase_free_result —освобождает память, занятую результирующим набором данных

Описание

int sybase_free_result (int result);

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

sybase_num_fields

sybase_num_fields — получает число столбцов в результирующем наборе данных

Описание

int sybase_num_fields (int result);

sybase_num_fields() возвращает число столбцов в результирующем наборе

sybase_num_rows

sybase_num_rows — получает число столбцов в результирующем наборе данных

Описание

int sybase_num_rows (string result);

sybase_num_rows() rвозвращает число строк в результирующем наборе

sybase_pconnect

sybase_pconnect — открывает постоянное соединение с Sybase-сервером

Описание

int sybase_pconnect (string servername, string username, string password);

Возвращает: Идентификатор соединения с Sybase-сервером (положительное число) или false в случае ошибки

Функция sybase_pconnect() выполняется практически аналогично sybase_connect() с двумя главными отличиями:

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

Во-вторых, соединение с SQL-сервером не завершается после выполнения скрипта. Вместо этого, оно остается открытым для последующего использования. (Функция sybase_close() не закрывает соединения, установленные с помощью sybase_pconnect()).

Поэтому этот тип соединений называется ‘постоянным’.

sybase_query

sybase_query — посылает запрос на Sybase-сервер

Описание

int sybase_query (string query, int link_identifier);

Возвращает: в случае успеха- идентификатор результирующего набора данных (положительное число), или false- в случае ошибки.

Функция sybase_query() посылает запрос к текущей открытой базе данных на сервере, заданном иденитификатором link_identifier. Если этот идентификатор не указан, то используется соединение, открытое последним. Если нет ни одного соединения, то функция пытается установить новое ( как если бы была вызвана sybase_connect()), и затем его использовать.

sybase_result

sybase_result —получает результирующие данные

Описание

int sybase_result (int result, int i, mixed field);

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

Функция sybase_result() возвращает содержимое одной ячейки данных из результирующего набора Sybase. В качестве параметра field может быть указано смещение (номер) столбца, его имя или имя столбца и имя таблицы, указанные через точку. (имя_столбца.имя_таблицы). Если для столбца был указан псевдоним (‘select foo as bar from. ‘), то вместо имени столбца следует использовать этот псевдоним.

При работе с большими наборами данных следует использовать функции (перечисленные ниже), которые извлекают из таблицы всю строку целиком. Поскольку эти функции за один вызов возвращают несколько ячеек данных, они работают ГОРАЗДО быстрее, чем sybase_result(). Кроме того, надо отметить, что скорость выполнения будет гораздо выше, если указывать числовое смещение столбца, а не параметр вида имя_столбца.имя_таблицы.

sybase_select_db

sybase_select_db — выбирает базу данных Sybase

Описание

int sybase_select_db (string database_name, int link_identifier);

Возвращает: true — в случае успеха, false — в случае ошибки

Функция sybase_select_db() устаналивает активную базу данных на сервере, заданном идентификатором link_identifier. Если это идентификатор не указан, то используется соединение, открытое последним. Если нет открытых соединений, то функция попытается установить новое (как если бы была вызвана sybase_connect()) и затем его использовать.

Все последующие вызовы sybase_query() будут работать с данной активной базой данных.

Что такое код sybase_fetch_row

sybase_fetch_row — получает ряд как перечислимый массив.

Описание

array sybase_fetch_row (int result)

Возвращает массив, соответствующий извлечённому ряду, или FALSE , если рядов больше нет.

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

Последующий вызов sybase_fetch_row() возвратит следующий ряд результирующего набора или FALSE , если рядов больше нет.

Ошибка с fetch_assoc()

17.10.2013, 14:43

Fetch_assoc — ошибка
Здравствуйте, происходит ошибка в этом коде(Fatal error), при чем на локалхосте все ок, а на сайте.

Ошибка Function fetch_assoc() on a non-object
Навеяло отсюда http://www.cyberforum.ru/php-database/thread774682.html Как исправить данную.

17.10.2013, 15:29 2 17.10.2013, 15:33 [ТС] 3 17.10.2013, 15:34 4
17.10.2013, 15:34
17.10.2013, 15:37 [ТС] 5
17.10.2013, 15:47 6
17.10.2013, 16:15 [ТС] 7
17.10.2013, 16:36 8
17.10.2013, 19:38 [ТС] 9
18.10.2013, 05:42 10

Вам же написали что в объекте нет данных, вернулось 0 строк, ничего нельзя сфетчить. Перед фетчами надо проверять количество. В циклах типа while($res=$result->fetch_arr())<> это делается неявно, но именно благодаря облому с чтением следующей строки можно выйти из такого цикла. У вас сразу строк 0. То есть запрос вернул 0 строк. Скорее всего потому что локальная база не такая же как на сервере. Нет некоторых записей к которым вы привыкли.

Походу критика. На этом форуме запрещена ссылка на пщмтщсщв.ру? Я бы послал.

Логика непостижима. Коннект это всего лишь function __construct($options) инстанси объекта которую вы можете назвать хоть mysqli, хоть yoursqli и наделать их сколько требуется. Допустим работать с несколькими бд условно одновременно.

Вытекает что инстансь уже сделана и передана в функцию глобально. Можно юзать. Что в таком случае делает функция connectDB() и что делает closeDB()?

Размножив такой код вы увидите что отличия только в названии функций. Так не делают. Делают хотя бы так:

Добавлено через 44 минуты
Но самая косточка в отсутствии смысла такого рода функций. Если они у вас есть, значит что-то неправильно в идее скрипта. Потому что множество простых запросов очень легко написать и тут же получить результ, сложных запросов много быть не должно и написать под них правильный компилятор задача не из легких.

Что проверяет и что возвращает функция в цитате? Сравните инлайновое решение

if(!$result = $mysqli->query(«SELECT * FROM `articles`»)) die(‘bad query’);
if($result->num_rows > 1) <
// сразу работаем с результом
>

Скажете в чем прикол? В том что не надо передавать аргументы особенно в условиях когда контекст заранее известен. Вызов же функции и возврат могучего результа в массиве поедает ресурсы и все такое.

Если никак без засасывания результа в массив нельзя обойтись, то вполне логично засунуть эту функцию прямо в запрос. Расширить класс result.

Fetch

JavaScript может отправлять сетевые запросы на сервер и подгружать новую информацию по мере необходимости.

Например, мы можем использовать сетевой запрос, чтобы:

  • Отправить заказ,
  • Загрузить информацию о пользователе,
  • Запросить последние обновления с сервера,
  • …и т.п.

Для сетевых запросов из JavaScript есть широко известный термин «AJAX» (аббревиатура от Asynchronous JavaScript And XML). XML мы использовать не обязаны, просто термин старый, поэтому в нём есть это слово. Возможно, вы его уже где-то слышали.

Есть несколько способов делать сетевые запросы и получать информацию с сервера.

Метод fetch() — современный и очень мощный, поэтому начнём с него. Он не поддерживается старыми (можно использовать полифил), но поддерживается всеми современными браузерами.

  • url – URL для отправки запроса.
  • options – дополнительные параметры: метод, заголовки и так далее.

Без options это простой GET-запрос, скачивающий содержимое по адресу url .

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

Процесс получения ответа обычно происходит в два этапа.

Во-первых, promise выполняется с объектом встроенного класса Response в качестве результата, как только сервер пришлёт заголовки ответа.

На этом этапе мы можем проверить статус HTTP-запроса и определить, выполнился ли он успешно, а также посмотреть заголовки, но пока без тела ответа.

Промис завершается с ошибкой, если fetch не смог выполнить HTTP-запрос, например при ошибке сети или если нет такого сайта. HTTP-статусы такие как 404 или 500, не являются ошибкой.

Мы можем увидеть HTTP-статус в свойствах ответа:

  • status – код статуса HTTP-запроса, например 200.
  • ok – логическое значение: будет true , если код HTTP-статуса в диапазоне 200-299.

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

Response предоставляет несколько методов, основанных на промисах, для доступа к телу ответа в различных форматах:

  • response.text() – читает ответ и возвращает как обычный текст,
  • response.json() – декодирует ответ в формате JSON,
  • response.formData() – возвращает ответ как объект FormData (разберём его в следующей главе),
  • response.blob() – возвращает объект как Blob (бинарные данные с типом),
  • response.arrayBuffer() – возвращает ответ как ArrayBuffer (низкоуровневое представление бинарных данных),
  • помимо этого, response.body – это объект ReadableStream, с помощью которого можно считывать тело запроса по частям. Мы рассмотрим и такой пример несколько позже.

Например, получим JSON-объект с последними коммитами из репозитория на GitHub:

То же самое без await , с использованием промисов:

Для получения ответа в виде текста используем await response.text() вместо .json() :

В качестве примера работы с бинарными данными, давайте запросим и выведем на экран логотип спецификации «fetch» (см. главу Blob, чтобы узнать про операции с Blob ):

Мы можем выбрать только один метод чтения ответа.

Если мы уже получили ответ с response.text() , тогда response.json() не сработает, так как данные уже были обработаны.

Заголовки ответа

Заголовки ответа хранятся в похожем на Map объекте response.headers .

Это не совсем Map , но мы можем использовать такие же методы, как с Map , чтобы получить заголовок по его имени или перебрать заголовки в цикле:

Заголовки запроса

Для установки заголовка запроса в fetch мы можем использовать опцию headers . Она содержит объект с исходящими заголовками, например:

Есть список запрещённых HTTP-заголовков, которые мы не можем установить:

  • Accept-Charset , Accept-Encoding
  • Access-Control-Request-Headers
  • Access-Control-Request-Method
  • Connection
  • Content-Length
  • Cookie , Cookie2
  • Date
  • DNT
  • Expect
  • Host
  • Keep-Alive
  • Origin
  • Referer
  • TE
  • Trailer
  • Transfer-Encoding
  • Upgrade
  • Via
  • Proxy-*
  • Sec-*

Эти заголовки обеспечивают достоверность данных и корректную работу протокола HTTP, поэтому они контролируются исключительно браузером.

POST-запросы

Для отправки POST -запроса или запроса с другим методом, нам необходимо использовать fetch параметры:

  • method – HTTP метод, например POST ,
  • body – тело запроса, одно из списка:
    • строка (например, в формате JSON),
    • объект FormData для отправки данных как form/multipart ,
    • Blob / BufferSource для отправки бинарных данных,
    • URLSearchParams для отправки данных в кодировке x-www-form-urlencoded , используется редко.

Чаще всего используется JSON.

Например, этот код отправляет объект user как JSON:

Заметим, что так как тело запроса body – строка, то заголовок Content-Type по умолчанию будет text/plain;charset=UTF-8 .

Но, так как мы посылаем JSON, то используем параметр headers для отправки вместо этого application/json , правильный Content-Type для JSON.

Отправка изображения

Мы можем отправить бинарные данные при помощи fetch , используя объекты Blob или BufferSource .

В этом примере есть элемент , на котором мы можем рисовать движением мыши. При нажатии на кнопку «Отправить» изображение отправляется на сервер:

Заметим, что здесь нам не нужно вручную устанавливать заголовок Content-Type , потому что объект Blob имеет встроенный тип ( image/png , заданный в toBlob ). При отправке объектов Blob он автоматически становится значением Content-Type .

Функция submit() может быть переписана без async/await , например, так:

Итого

Типичный запрос с помощью fetch состоит из двух операторов await :

  • response.status – HTTP-код ответа,
  • response.ok – true , если статус ответа в диапазоне 200-299.
  • response.headers – похожий на Map объект с HTTP-заголовками.

Методы для получения тела ответа:

  • response.text() – возвращает ответ как обычный текст,
  • response.json() – преобразовывает ответ в JSON-объект,
  • response.formData() – возвращает ответ как объект FormData (кодировка form/multipart, см. следующую главу),
  • response.blob() – возвращает объект как Blob (бинарные данные с типом),
  • response.arrayBuffer() – возвращает ответ как ArrayBuffer (низкоуровневые бинарные данные),

Опции fetch , которые мы изучили на данный момент:

  • method – HTTP-метод,
  • headers – объект с запрашиваемыми заголовками (не все заголовки разрешены),
  • body – данные для отправки (тело запроса) в виде текста, FormData , BufferSource , Blob или UrlSearchParams .

В следующих главах мы рассмотрим больше параметров и вариантов использования fetch .

Задачи

Получите данные о пользователях GitHub

Создайте асинхронную функцию getUsers(names) , которая получает на вход массив логинов пользователей GitHub, запрашивает у GitHub информацию о них и возвращает массив объектов-пользователей.

Информация о пользователе GitHub с логином USERNAME доступна по ссылке: https://api.github.com/users/USERNAME .

В песочнице есть тестовый пример.

  1. На каждого пользователя должен приходиться один запрос fetch .
  2. Запросы не должны ожидать завершения друг друга. Надо, чтобы данные приходили как можно быстрее.
  3. Если какой-то запрос завершается ошибкой или оказалось, что данных о запрашиваемом пользователе нет, то функция должна возвращать null в массиве результатов.

Чтобы получить сведения о пользователе, нам нужно вызвать fetch(‘https://api.github.com/users/USERNAME’) .

Если ответ приходит cо статусом 200 , то вызываем метод .json() , чтобы прочитать JS-объект.

А если запрос завершается ошибкой или код статуса в ответе отличен от 200, то мы просто возвращаем null в массиве результатов.

Пожалуйста, обратите внимание: вызов .then прикреплён к fetch , чтобы, когда ответ получен, сразу начинать считывание данных с помощью .json() , не дожидаясь завершения других запросов.

Если бы мы использовали await Promise.all(names.map(name => fetch(. ))) и вызывали бы .json() на результатах запросов, то пришлось бы ждать, пока завершатся все из них. Вызывая .json() сразу после каждого fetch , мы добились того, что считывание присланных по каждому запросу данных происходит независимо от других запросов.

Это пример того, как относительно низкоуровневое Promise API может быть полезным, даже если мы в основном используем async/await в коде.

sybase_fetch_row

Get a result row as an enumerated array ( PHP 4, PHP 5 )

sybase_fetch_row() fetches one row of data from the result associated with the specified result identifier.

Subsequent call to sybase_fetch_row() would return the next row in the result set, or FALSE if there are no more rows.

Parameters

Return Values

Returns an array that corresponds to the fetched row, or FALSE if there are no more rows. Each result column is stored in an array offset, starting at offset 0.

Описание констант PDO::FETCH_*.

Как уже говорилось в статье Как работать с 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 присваивает значения свойствам класса до вызова конструктора. При помощи же данной константы это поведение можно изменить — сначала будет вызываться конструктор:

    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 функций по управлению курсором при получении данных из БД. Пример есть в документации
    Илон Маск рекомендует:  Cookie в PHP
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL