Александр Некрасов · Автономное руководство

PHP: полный мануал с примерами, функциями и ООП

Разделы этой страницы
  1. ODBC (Unified): полный справочник соединений, запросов и схемы
  2. ODBC от задачи: один PHP-код, разные драйверы, явные границы
  3. Установка и настройка: четыре слоя, которые должны совпасть
  4. Требования: библиотека ODBC — не сама база
  5. Установка: Windows DLL, unixODBC/iODBC и изменения PHP 8.5
  6. Runtime configuration: лимиты, persistent, LONG и курсоры
  7. Жизненный цикл типов: resources до PHP 8.4, opaque objects после
  8. Все предопределённые ODBC-константы по назначению
  9. Полный древовидный справочник 48 функций
  10. Odbc\Connection: opaque handle сессии
  11. Odbc\Result: statement, cursor и metadata в одном opaque handle
  12. Реальные границы: кодировка, pooling, параллельность и большие данные
  13. Функции и методы этой темы
  14. Код и руководство с собой
PHP 8.5.11149 глав4458 карточек справочника
Дерево руководства

Глава 129 · С нуля → полный справочник

ODBC (Unified): полный справочник соединений, запросов и схемы

От первого DSN и понятной ошибки до prepared statements, транзакций, LONG/binary, catalog metadata и всех 48 официальных функций PHP 8.5.

ODBC от задачи: один PHP-код, разные драйверы, явные границы

ODBC нужен, когда PHP должен говорить с источником через стандартный Driver Manager: корпоративный SQL Server, Access-файл, PostgreSQL, DB2 или другое ODBC-совместимое хранилище. Выигрыш — один набор PHP-функций. Цена — возможности, типы, SQL и ошибки всё равно зависят от конкретного драйвера и СУБД.

Что происходит между кодом и данными
  1. PHP вызывает ext/odbc и передаёт DSN
  2. ODBC Driver Manager находит драйвер той же разрядности
  3. драйвер переводит ODBC-вызов в протокол конкретной базы
  4. база возвращает строки/статус через driver и result object

DSN — именованная конфигурация источника. DSN-less строка перечисляет Driver/Server/Database прямо в конфигурации приложения. Пароль в обоих случаях хранится вне репозитория. ODBC унифицирует транспортный API, но не делает SQL-диалекты, транзакционные особенности и типы полностью одинаковыми.

Мини-проект: создать таблицу, добавить товар и прочитать егоСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_first_product');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_first_product (id INTEGER PRIMARY KEY, name VARCHAR(50), price INTEGER)');
    $insert = odbc_prepare($connection, 'INSERT INTO phpman_first_product VALUES (CAST(? AS INTEGER), ?, CAST(? AS INTEGER))');
    if ($insert === false || !@odbc_execute($insert, [1, 'Notebook', 450])) {
        throw new RuntimeException(odbc_error($connection).' '.odbc_errormsg($connection));
    }
    $select = odbc_prepare($connection, 'SELECT name, price FROM phpman_first_product WHERE id=CAST(? AS INTEGER)');
    if ($select === false || !@odbc_execute($select, [1])) {
        throw new RuntimeException(odbc_error($connection).' '.odbc_errormsg($connection));
    }
    $product = odbc_fetch_array($select);
    echo $product['name'], ':', $product['price'], "\n";
} finally {
    uodbcDrop($connection, 'phpman_first_product');
    odbc_close($connection);
}
Ожидаемый результат
Notebook:450

Один путь показывает роли всех объектов: connection — сессия; result от prepare — команда; params — данные; fetch — строка результата. Таблица удаляется в finally. На psqlODBC успешный INSERT может сопровождаться SQLSTATE 01S02 о смене cursor updatability; код отдельно проверяет bool результата, а диагностическое предупреждение в реальном приложении пишет в технический лог. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Мини-проект: превратить ошибку SQL в понятный безопасный исходСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = @odbc_exec($connection, 'SELECT * FROM phpman_table_not_created');
if ($result === false) {
    $state = odbc_error($connection);
    $diagnostic = odbc_errormsg($connection);
    echo "operation=inventory-read state={$state}\n";
    echo str_contains($diagnostic, 'phpman_table_not_created') ? "diagnostic-captured\n" : "diagnostic-empty\n";
    echo "public=Сервис временно не получил данные\n";
}
odbc_close($connection);
Ожидаемый результат
operation=inventory-read state=42P01
diagnostic-captured
public=Сервис временно не получил данные

Закрытый журнал может получить diagnostic и operation id; посетителю не раскрываются SQL, хост и схема. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Дальше можно идти по задаче: odbc_connect() → odbc_prepare() → odbc_execute() → odbc_fetch_array(). Опытный читатель открывает полный справочник функций ниже.

Установка и настройка: четыре слоя, которые должны совпасть

Рабочая цепочка состоит из четырёх отдельных частей: расширение PHP, Driver Manager, драйвер СУБД и сам источник данных. Ошибка «undefined function» относится к первому слою; IM002 — обычно к DSN/драйверу; 08001/08xxx — к соединению; 28xxx — к аутентификации. Такая локализация экономит время.

СлойПроверкаТипичный отказ
PHPextension_loaded('odbc')Call to undefined function
Driver ManagerWindows ODBC Administrator / unixODBC iODBCIM002 source/driver not found
Драйверта же x64/x86, что PHP; vendor versiondriver load/unsupported API
Источникhost/port/database/user + простой SELECTnetwork/auth/SQLSTATE

На Windows системный Driver Manager используется всегда. 64-битный PHP видит 64-битные драйверы/DSN; 32-битная панель администратора настраивает другой мир. На Linux обычно выбирают unixODBC или iODBC, затем устанавливают vendor driver и DSN.

Эта общая страница объединяет официальные подразделы ниже; каждое требование и исторический флаг сохранены в своей секции.

Требования: библиотека ODBC — не сама база

Официальный baseline краток: нужны библиотеки требуемой поддерживаемой базы. Практически это означает: PHP ext/odbc должен быть собран/загружен; Driver Manager должен работать; для каждой СУБД установлен подходящий ODBC-драйвер; сеть, TLS и учётная запись разрешают соединение.

  • Сверьте разрядность PHP и драйвера.
  • Сверьте архитектуру процесса веб-сервера, а не только интерактивного терминала.
  • Создайте отдельную минимально привилегированную роль приложения.
  • Проверьте кодировку/Unicode round-trip до импорта данных.
  • Не используйте production-базу для учебных/диагностических DDL-примеров.

ODBC-драйвер обновляется отдельно от PHP. Совместимость PHP 8.5 не доказывает совместимость старого vendor driver с TLS/сервером.

Установка: Windows DLL, unixODBC/iODBC и изменения PHP 8.5

На Windows включают php_odbc.dll в том php.ini, который реально загружает нужный SAPI, затем перезапускают PHP-worker/Apache/IIS. Изолированная CLI-проверка возможна через php -n -d extension=... -m, но она не изменяет конфигурацию сайта.

При сборке Unix официальный manual перечисляет --with-unixODBC[=DIR], --with-iodbc, --with-ibm-db2[=DIR] и --with-custom-odbc[=DIR]. Для custom ODBC нужны заголовки и корректные CUSTOM_ODBC_LIBS. Driver Manager предпочтительнее прямого связывания благодаря совместимости и смене драйверов.

С PHP 8.5 удалены flags прямой поддержки Adabas, DBMaker, Empress, Easysoft OOB, SAP DB и Solid; исторические --with-birdstep удалены ещё с PHP 7.3. Это не означает, что к продукту нельзя подключиться через современный совместимый Driver Manager/driver — проверяется его текущая документация.

После измененияКоманда/действиеЧто доказывает
Расширениеphp --ini, php -mкакой ini и загружен ли odbc
APIfunction_exists('odbc_connect')функция доступна этому SAPI
DriverODBC Administrator/odbcinstимя и архитектура драйвера
End-to-endconnect + SELECT 1DSN, сеть, auth и SQL вместе

Runtime configuration: лимиты, persistent, LONG и курсоры

ДирективаDefaultГде менятьСмысл
odbc.allow_persistent1INI_SYSTEMРазрешить persistent ODBC connections.
odbc.check_persistent1INI_SYSTEMПроверять persistent-сессию перед повторным использованием.
odbc.max_persistent-1INI_SYSTEMЛимит persistent connections на процесс; -1 без лимита.
odbc.max_links-1INI_SYSTEMЛимит всех ODBC connections на процесс.
odbc.defaultlrl4096INI_ALLБайтовый предел LONG; см. odbc_longreadlen().
odbc.defaultbinmode1INI_ALLРежим binary; см. odbc_binmode().
odbc.default_cursortype3INI_ALLМодель курсора, 3 = SQL_CURSOR_STATIC в текущей сборке.

Официальная страница также описывает historical/default_db, default_user и default_pw. В PHP 8.5.11 Windows runtime они не перечисляются ini_get_all('odbc'); комментарии php.ini отмечают default_db/user/pw как not implemented. Не стройте на них конфигурацию и не храните пароль в php.ini без строгой необходимости.

INI_SYSTEM меняется в системной конфигурации до запуска worker-а. INI_ALL технически допускает ini_set, но настройка binmode/longreadlen на конкретном result через функции делает влияние локальным и понятным. Лимит -1 не равен безопасной бесконечности: сервер и процесс всё равно ограничены.

Текущий изолированный стенд сообщает: allow/check persistent = 1, max links/persistent = -1, defaultlrl=4096, defaultbinmode=1, default_cursortype=3. Это evidence стенда, а не рекомендация копировать значения в production.

Жизненный цикл типов: resources до PHP 8.4, opaque objects после

Официальная resource-страница важна для чтения старого кода: до PHP 8.4 расширение возвращало два resource-типа — connection identifier и result identifier. С PHP 8.4 их заменили Odbc\Connection и Odbc\Result.

Владение
  1. odbc_connect создаёт Connection
  2. exec/prepare создаёт Result, связанный с connection/statement
  3. fetch двигает cursor внутри Result
  4. free_result освобождает Result; close освобождает Connection после transaction boundary

Opaque object нельзя создать через new, клонировать или сериализовать; у него нет публичных полей/методов. Это handle к нативному состоянию. Проверка is_resource() из legacy-кода после обновления перестаёт работать — используйте сигнатуры/тип объекта и не храните handle между HTTP-запросами.

Все предопределённые ODBC-константы по назначению

Константы существуют только при загруженном ext/odbc. Числа показаны для PHP 8.5.11/Windows ODBC headers; в коде пишут имя константы, а не магическое число.

КонстантаЗначение стендаГде применяется
ODBC_BINMODE_CONVERT2Режим двоичных колонок для odbc_binmode().
ODBC_BINMODE_PASSTHRU0Режим двоичных колонок для odbc_binmode().
ODBC_BINMODE_RETURN1Режим двоичных колонок для odbc_binmode().
ODBC_TYPEWin32Тип сборки/Driver Manager, строка для диагностики, не переключатель.
SQL_BEST_ROWID1Параметр odbc_specialcolumns().
SQL_BIGINT-5ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_BINARY-2ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_BIT-7ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_CHAR1ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_CONCURRENCY7Режим concurrency ODBC statement.
SQL_CONCUR_LOCK2Режим concurrency ODBC statement.
SQL_CONCUR_READ_ONLY1Режим concurrency ODBC statement.
SQL_CONCUR_ROWVER3Режим concurrency ODBC statement.
SQL_CONCUR_VALUES4Режим concurrency ODBC statement.
SQL_CURSOR_DYNAMIC2Модель/атрибут курсора. Поддержка зависит от драйвера.
SQL_CURSOR_FORWARD_ONLY0Модель/атрибут курсора. Поддержка зависит от драйвера.
SQL_CURSOR_KEYSET_DRIVEN1Модель/атрибут курсора. Поддержка зависит от драйвера.
SQL_CURSOR_STATIC3Модель/атрибут курсора. Поддержка зависит от драйвера.
SQL_CURSOR_TYPE6Модель/атрибут курсора. Поддержка зависит от драйвера.
SQL_CUR_USE_DRIVER2Кто управляет курсорами при odbc_connect()/pconnect().
SQL_CUR_USE_IF_NEEDED0Кто управляет курсорами при odbc_connect()/pconnect().
SQL_CUR_USE_ODBC1Кто управляет курсорами при odbc_connect()/pconnect().
SQL_DATE9ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_DECIMAL3ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_DOUBLE8ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_ENSURE1Фильтр/точность odbc_statistics().
SQL_FETCH_FIRST2Направление перечисления DSN для odbc_data_source().
SQL_FETCH_NEXT1Направление перечисления DSN для odbc_data_source().
SQL_FLOAT6ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_INDEX_ALL1Фильтр/точность odbc_statistics().
SQL_INDEX_UNIQUE0Фильтр/точность odbc_statistics().
SQL_INTEGER4ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_KEYSET_SIZE8Атрибут размера keyset курсора.
SQL_LONGVARBINARY-4ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_LONGVARCHAR-1ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_NO_NULLS0Параметр odbc_specialcolumns().
SQL_NULLABLE1Параметр odbc_specialcolumns().
SQL_NUMERIC2ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_ODBC_CURSORS110ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_QUICK0Фильтр/точность odbc_statistics().
SQL_REAL7ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_ROWVER2Параметр odbc_specialcolumns().
SQL_SCOPE_CURROW0Параметр odbc_specialcolumns().
SQL_SCOPE_SESSION2Параметр odbc_specialcolumns().
SQL_SCOPE_TRANSACTION1Параметр odbc_specialcolumns().
SQL_SMALLINT5ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_TIME10ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_TIMESTAMP11ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_TINYINT-6ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_TYPE_DATE91ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_TYPE_TIME92ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_TYPE_TIMESTAMP93ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_VARBINARY-3ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_VARCHAR12ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_WCHAR-8ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_WLONGVARCHAR-10ODBC SQL type code для odbc_gettypeinfo() и schema metadata.
SQL_WVARCHAR-9ODBC SQL type code для odbc_gettypeinfo() и schema metadata.

Группы: ODBC_BINMODE_* управляют binary result; SQL_CUR_USE_* выбирают менеджера курсоров; SQL_CURSOR_*/SQL_CONCUR_* и SQL_KEYSET_SIZE — низкоуровневые option values; SQL_CHAR…SQL_WLONGVARCHAR и numeric/date/binary — type codes; BEST_ROWID/ROWVER/SCOPE/NULLABLE — specialcolumns; INDEX/ENSURE/QUICK — statistics; FETCH_FIRST/NEXT — data_source.

Полный древовидный справочник 48 функций

Все 48 официальных функций представлены отдельными карточками: сигнатура PHP 8.5.11, параметры, возврат/ошибки, два практических примера, ограничения и связанные операции. Это полный ref.uodbc, а не список функций, случайно встретившихся в уроках.

ODBC: соединения и DSN

ODBC: строки подключения

ODBC: запросы и параметры

ODBC: чтение результата

ODBC: структура результата

ODBC: транзакции, ошибки и настройки

ODBC: двоичные и длинные данные

ODBC: каталог и схема

Два исторических факта вынесены явно: odbc_do — alias odbc_exec; odbc_field_precision — alias odbc_field_len; odbc_result_all deprecated с PHP 8.1.

Odbc\Connection: opaque handle сессии

Класс появился в PHP 8.4 и заменил resource connection. Синопсис пуст: методов/свойств нет. Экземпляр возвращают odbc_connect()/odbc_pconnect(); new Odbc\Connection() выбрасывает Error.

Что хранит концептуальноКак работать
Нативный ODBC connection handle и состояние driver/sessionПередавать ODBC-функциям
Режим autocommit/transactionodbc_autocommit/commit/rollback
Последнюю диагностикуodbc_error/errormsg сразу после отказа
Жизненный циклodbc_close только после завершения transaction

Не сериализуется, не переносится в другой процесс/запрос и не является безопасным глобальным singleton. В объект приложения можно завернуть фабрику/adapter, но нативный handle всё равно живёт только внутри процесса.

Odbc\Result: statement, cursor и metadata в одном opaque handle

Класс появился в PHP 8.4 и заменил resource result. Его возвращают odbc_exec()/odbc_prepare()/catalog functions. У него нет методов; действие выполняют функции odbc_fetch_*, odbc_result, odbc_num_*/field_* и odbc_free_result.

Два распространённых состояния Result
  1. odbc_exec: уже выполненный SQL и result/status
  2. odbc_prepare: подготовленный statement до execute
  3. odbc_execute: тот же object получает выполненный result
  4. fetch двигает cursor; free_result делает object непригодным

new Odbc\Result() запрещён. Result нельзя клонировать/сериализовать. После free или закрытия связанного connection не передавайте его другим функциям.

Реальные границы: кодировка, pooling, параллельность и большие данные

Проверить русский текст до реального импортаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_unicode');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_unicode (id INTEGER PRIMARY KEY, label VARCHAR(100))');
    $statement = odbc_prepare($connection, 'INSERT INTO phpman_unicode VALUES (1, ?)');
    if ($statement === false || !@odbc_execute($statement, ['Заказ №7 — готов'])) {
        throw new RuntimeException(odbc_errormsg($connection));
    }
    $result = uodbcExec($connection, 'SELECT label FROM phpman_unicode WHERE id=1');
    $row = odbc_fetch_array($result);
    echo $row['label'], "\n";
} finally {
    uodbcDrop($connection, 'phpman_unicode');
    odbc_close($connection);
}
Ожидаемый результат
Заказ №7 — готов

Round-trip проверяет PHP source, Unicode ODBC driver, client encoding и database column вместе. Один ASCII SELECT этого не доказывает. SQLSTATE класса 01 при успешном execute — диагностическое предупреждение драйвера, а не повод считать сохранённую строку потерянной. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Кодировки. Выбирайте Unicode-вариант драйвера; проверьте русский/emoji/combining characters в отдельной базе. Не лечите mojibake случайным utf8_encode/iconv после получения: сначала согласуйте client/database encoding.

Persistent/pooling. odbc_pconnect переиспользует сессию PHP-процесса. Driver Manager/vendor driver может иметь свой pooling. Это два уровня; считайте реальные backend sessions и время connect. Возвращайте autocommit/session settings, не оставляйте временные таблицы и открытые транзакции.

Параллельность. Один Odbc\Connection не переносится между PHP-процессами. Два одновременных запроса обычно имеют отдельные handles/sessions; согласованность решает СУБД блокировками/изоляцией. Не делите object через serialize/cache.

LONG/binary. defaultlrl=4096 может усечь длинные колонки; binmode меняет bytes/hex/passthru. Для крупного файла проверьте память и нативный LOB API. См. odbc_longreadlen() и odbc_binmode().

Problem signals. Старые обсуждения полезны как симптомы, но ответы могли устареть. В руководстве они сверены с текущей сигнатурой/поведением:

Упражнение: замените учебный product на таблицу заказов, добавьте transaction для order+line, умышленно нарушьте FK и сохраните SQLSTATE. Затем проверьте Unicode round-trip. Решение строится из connect → autocommit(false) → prepare/execute → commit или rollback → close.

Функции и методы этой темы

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

odbc_connectОткрывает обычное ODBC-соединение: PHP передаёт DSN, пользователя и пароль Driver Manager, тот загружает драйвер, а драйвер договаривается с конкретной базой.

PHP 4+; PHP 8.4: Odbc\Connection и новые правила nullable user/password · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_connect(string $dsn, ?string $user = null, ?string $password = null, int $cursor_option = 2): Odbc\Connection|false

Открывает обычное ODBC-соединение: PHP передаёт DSN, пользователя и пароль Driver Manager, тот загружает драйвер, а драйвер договаривается с конкретной базой.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_connect(string $dsn, ?string $user = null, ?string $password = null, int $cursor_option = 2): Odbc\Connection|false

ПараметрЧто передать
string $dsnИмя системного/пользовательского DSN либо DSN-less строка драйвера. Это не PDO-DSN с префиксом odbc:.
?string $user (по умолчанию NULL)Имя пользователя источника данных. null оставляет выбор драйверу/DSN.
?string $password (по умолчанию NULL)Пароль. В PHP 8 он помечен SensitiveParameter; храните его вне исходника.
int $cursor_option (по умолчанию 2)SQL_CUR_USE_DRIVER, SQL_CUR_USE_IF_NEEDED или SQL_CUR_USE_ODBC. Обычно начинают с SQL_CUR_USE_DRIVER.

Возврат. Возвращает Odbc\Connection либо false. Начиная с PHP 8.4 user/password nullable и необязательны; UID/PWD внутри DSN перекрывают одноимённый отдельный аргумент.

Отказ и диагностика. При отказе возвращает false и обычно создаёт warning; после подавления warning немедленно прочитайте odbc_error()/odbc_errormsg() и запишите безопасный контекст. TypeError означает неверный PHP-вызов.

Путь вызова
  1. PHP получает DSN без зашитого пароля
  2. Driver Manager находит подходящий драйвер
  3. драйвер открывает сессию базы
  4. объект соединения передаётся последующим функциям
Подключиться по DSN и получить проверочное значениеСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = @odbc_connect(
    uodbcEnv('UODBC_DSN'),
    uodbcEnv('UODBC_USER'),
    uodbcEnv('UODBC_PASSWORD'),
    SQL_CUR_USE_DRIVER,
);
if ($connection === false) {
    throw new RuntimeException(odbc_error().' '.odbc_errormsg());
}
$result = uodbcExec($connection, 'SELECT 42 AS answer');
echo get_debug_type($connection), "\n";
echo odbc_result($result, 'answer'), "\n";
odbc_close($connection);
Ожидаемый результат
Odbc\Connection
42

Соединение успешно только после возврата объекта. Проверочный SELECT показывает, что доступен не просто Driver Manager, а сама база. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Отличить ошибку DSN от успешного подключенияСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = @odbc_connect('MISSING_DSN_404', null, null);
if ($connection === false) {
    echo odbc_error(), "\n";
}
Ожидаемый результат
IM002

SQLSTATE IM002 означает, что Driver Manager не нашёл источник/драйвер. Имя намеренно короче 32 символов: слишком длинный DSN в Windows даёт другой SQLSTATE S1090 (invalid string or buffer length). Пользователю не показывают полную строку подключения и пароль. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не храните UID/PWD в репозитории и не печатайте connection string в браузер.
  • DSN и DSN-less строка относятся к ODBC, а не к синтаксису PDO.
  • Успешная загрузка php_odbc.dll ещё не означает, что установлен драйвер нужной СУБД.

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

Связанные операции: odbc_pconnect(), odbc_close(), odbc_error().

odbc_pconnectОткрывает или повторно использует постоянное соединение. Это может сэкономить установление сессии, но переносит её состояние между запросами одного PHP-worker.

PHP 4+; PHP 8.4: Odbc\Connection и nullable user/password · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_pconnect(string $dsn, ?string $user = null, ?string $password = null, int $cursor_option = 2): Odbc\Connection|false

Открывает или повторно использует постоянное соединение. Это может сэкономить установление сессии, но переносит её состояние между запросами одного PHP-worker.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_pconnect(string $dsn, ?string $user = null, ?string $password = null, int $cursor_option = 2): Odbc\Connection|false

ПараметрЧто передать
string $dsnИмя системного/пользовательского DSN либо DSN-less строка драйвера. Это не PDO-DSN с префиксом odbc:.
?string $user (по умолчанию NULL)Имя пользователя источника данных. null оставляет выбор драйверу/DSN.
?string $password (по умолчанию NULL)Пароль. В PHP 8 он помечен SensitiveParameter; храните его вне исходника.
int $cursor_option (по умолчанию 2)SQL_CUR_USE_DRIVER, SQL_CUR_USE_IF_NEEDED или SQL_CUR_USE_ODBC. Обычно начинают с SQL_CUR_USE_DRIVER.

Возврат. Возвращает Odbc\Connection либо false. В CGI постоянство не даёт эффекта. PHP 8.4 изменил объектный тип возврата и правила nullable учётных данных.

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

Путь вызова
  1. PHP ищет совпадение DSN/user/password в пуле процесса
  2. при совпадении проверяется/берётся существующая сессия
  3. код выполняет запрос
  4. процесс сохраняет сессию после завершения запроса
Открыть постоянное соединение и выполнить короткий запросСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = @odbc_pconnect(
    uodbcEnv('UODBC_DSN'),
    uodbcEnv('UODBC_USER'),
    uodbcEnv('UODBC_PASSWORD'),
);
if ($connection === false) {
    throw new RuntimeException(odbc_error().' '.odbc_errormsg());
}
$result = uodbcExec($connection, "SELECT 'ready' AS state");
echo odbc_result($result, 'state'), "\n";
Ожидаемый результат
ready

Постоянство относится к рабочему процессу PHP и следующим запросам этого процесса, а не делает объект общим между всеми серверами. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Увидеть повторное использование одной серверной сессииСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$first = @odbc_pconnect(uodbcEnv('UODBC_DSN'), uodbcEnv('UODBC_USER'), uodbcEnv('UODBC_PASSWORD'));
$second = @odbc_pconnect(uodbcEnv('UODBC_DSN'), uodbcEnv('UODBC_USER'), uodbcEnv('UODBC_PASSWORD'));
if ($first === false || $second === false) {
    throw new RuntimeException(odbc_error().' '.odbc_errormsg());
}
$a = uodbcExec($first, 'SELECT pg_backend_pid() AS pid');
$b = uodbcExec($second, 'SELECT pg_backend_pid() AS pid');
echo odbc_result($a, 'pid') === odbc_result($b, 'pid') ? "same-session\n" : "different-session\n";
Ожидаемый результат
same-session

Одинаковые DSN/пользователь/пароль в одном CLI-процессе повторно используют persistent-сессию psqlODBC. В FPM состояние может жить дольше одного HTTP-запроса, поэтому настройки сессии надо возвращать в ожидаемое состояние. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Незавершённая транзакция, временные таблицы и параметры сессии могут попасть в следующий запрос worker-а.
  • Пул не заменяет лимит соединений и наблюдение за ними.
  • Не измеряйте пользу pconnect без модели PHP-процессов и нагрузки.

Когда выбрать другое. Обычный odbc_connect() проще там, где соединений мало или состояние сессии трудно безопасно сбрасывать; внешний pooler решает другую, серверную задачу.

Связанные операции: odbc_connect(), odbc_close_all().

odbc_closeЗакрывает обычное ODBC-соединение после завершения работы и освобождает связанные с ним ресурсы процесса.

PHP 4+; PHP 8.4: параметр Odbc\Connection вместо resource · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_close(Odbc\Connection $odbc): void

Закрывает обычное ODBC-соединение после завершения работы и освобождает связанные с ним ресурсы процесса.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_close(Odbc\Connection $odbc): void

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.

Возврат. Ничего не возвращает. Официальная документация говорит, что при открытой транзакции функция завершится неудачей и оставит соединение открытым; конкретная связка PHP/Driver Manager/драйвер может фактически закрыть handle и откатить транзакцию, поэтому полагаться на это нельзя.

Отказ и диагностика. Официальный contract и наблюдаемое поведение драйвера могут расходиться. Невалидный/уже закрытый объект приводит к Error/TypeError, а не к безопасному false.

Путь вызова
  1. код завершает чтение результатов
  2. открытая транзакция явно commit/rollback
  3. odbc_close освобождает соединение
  4. повторный вызов через объект запрещён
Освободить обычное соединение после отчётаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, 'SELECT COUNT(*) AS total FROM pg_catalog.pg_class');
echo ((int) odbc_result($result, 'total') > 0) ? "report-ready\n" : "empty\n";
odbc_close($connection);
try {
    odbc_exec($connection, 'SELECT 1');
} catch (Error) {
    echo "connection-closed\n";
}
Ожидаемый результат
report-ready
connection-closed

После закрытия тот же объект больше нельзя передавать ODBC-функциям. Результат читают до закрытия соединения. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Проверить поведение close при незавершённой транзакцииСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_close_tx');
uodbcExec($connection, 'CREATE TABLE phpman_close_tx (id INTEGER PRIMARY KEY)');
odbc_autocommit($connection, false);
uodbcExec($connection, 'INSERT INTO phpman_close_tx VALUES (1)');
@odbc_close($connection);
$state = 'open';
try {
    odbc_exec($connection, 'SELECT 1');
    odbc_rollback($connection);
    odbc_autocommit($connection, true);
    odbc_close($connection);
} catch (Error) {
    $state = 'closed';
}
$cleanup = uodbcConnect();
$check = uodbcExec($cleanup, 'SELECT COUNT(*) AS total FROM phpman_close_tx');
echo "connection={$state}\n";
echo "rows-after-close=", odbc_result($check, 'total'), "\n";
uodbcDrop($cleanup, 'phpman_close_tx');
odbc_close($cleanup);
Ожидаемый результат
connection=closed
rows-after-close=0

Официальный manual обещает, что odbc_close() при открытой транзакции завершится неудачей и оставит соединение открытым. Проверенный PHP 8.5.11 + psqlODBC 18.00 фактически закрыл handle и сервер откатил INSERT. В php-src 8.5.11 safe_odbc_disconnect() после ошибки SQLDisconnect вызывает SQL_ROLLBACK, повторяет disconnect и освобождает handle. Это важное расхождение runtime: приложение обязано вызвать commit/rollback до close и не использовать close как transaction control. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Всегда явно commit/rollback до close: не рассчитывайте ни на сохранение handle, ни на автоматический rollback.
  • Не закрывайте соединение до чтения нужного результата.
  • Persistent-соединение управляется иначе и предназначено для повторного использования.

Когда выбрать другое. Обычно PHP закроет обычное соединение в конце процесса/запроса, но явное закрытие делает границу владения понятной и освобождает дефицитный ресурс раньше.

Связанные операции: odbc_connect(), odbc_commit(), odbc_rollback(), odbc_close_all().

odbc_close_allЗакрывает все обычные ODBC-соединения текущего PHP-процесса; полезна главным образом в диагностическом CLI-скрипте, который целиком владеет ими.

PHP 4+; актуальная объектная сигнатура PHP 8.5 · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_close_all(): void

Закрывает все обычные ODBC-соединения текущего PHP-процесса; полезна главным образом в диагностическом CLI-скрипте, который целиком владеет ими.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_close_all(): void

ПараметрЧто передать
Аргументов нетФункция действует на ODBC-соединения текущего PHP-процесса.

Возврат. Возвращаемого значения нет. По официальной документации соединение с открытой транзакцией должно остаться открытым; проверенная psqlODBC-связка закрыла его, поэтому результат нельзя использовать как переносимую transaction guarantee.

Отказ и диагностика. Не полагайтесь на функцию как на аварийный rollback или способ сохранить транзакционное соединение. Уже закрытые объекты после вызова выбрасывают Error при использовании.

Путь вызова
  1. функция обходит известные процессу соединения
  2. драйвер решает фактическое закрытие handle
  3. сервер завершает/откатывает сессию при закрытии
  4. код не получает отчёта о результате
Закрыть два обычных соединения одной операциейСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$first = uodbcConnect();
$second = uodbcConnect();
odbc_close_all();
$closed = 0;
foreach ([$first, $second] as $connection) {
    try { odbc_exec($connection, 'SELECT 1'); } catch (Error) { $closed++; }
}
echo "closed={$closed}\n";
Ожидаемый результат
closed=2

Функция действует на соединения процесса, поэтому её редко вызывают в библиотеке: она может закрыть ресурс чужого компонента. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Сравнить обычное и транзакционное соединения после close_allСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$first = uodbcConnect();
$second = uodbcConnect();
uodbcDrop($second, 'phpman_close_all_tx');
uodbcExec($second, 'CREATE TABLE phpman_close_all_tx (id INTEGER PRIMARY KEY)');
odbc_autocommit($second, false);
uodbcExec($second, 'INSERT INTO phpman_close_all_tx VALUES (1)');
odbc_close_all();
$states = [];
foreach (['first' => $first, 'transactional' => $second] as $name => $connection) {
    try {
        odbc_exec($connection, 'SELECT 1');
        $states[$name] = 'open';
        if ($name === 'transactional') { odbc_rollback($connection); }
        odbc_close($connection);
    } catch (Error) {
        $states[$name] = 'closed';
    }
}
$cleanup = uodbcConnect();
$check = uodbcExec($cleanup, 'SELECT COUNT(*) AS total FROM phpman_close_all_tx');
echo "first={$states['first']}\n";
echo "transactional={$states['transactional']}\n";
echo "rows-after-close=", odbc_result($check, 'total'), "\n";
uodbcDrop($cleanup, 'phpman_close_all_tx');
odbc_close($cleanup);
Ожидаемый результат
first=closed
transactional=closed
rows-after-close=0

Manual обещает оставить транзакционное соединение открытым. На проверенной связке close_all закрыл оба handles и PostgreSQL откатил незавершённый INSERT; это соответствует ветке rollback/retry/free в safe_odbc_disconnect() php-src 8.5.11. Поэтому глобальное закрытие не заменяет явный rollback/commit и требует проверки на каждом драйвере. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Глобальное действие нарушает владение ресурсами в большом приложении.
  • Открытые транзакции надо завершить до close_all независимо от обещания manual.
  • Функция ничего не сообщает о числе закрытых соединений.

Когда выбрать другое. Закрывайте конкретный Odbc\Connection там, где закончился его жизненный цикл; контейнер приложения может вести явный список собственных соединений.

Связанные операции: odbc_close(), odbc_autocommit(), odbc_rollback().

odbc_cursorВозвращает имя ODBC-курсора результата. Оно нужно редким низкоуровневым SQL/драйверным сценариям; для обычного foreach-подобного чтения имя не требуется.

PHP 4+; PHP 8.4: Odbc\Result вместо resource · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_cursor(Odbc\Result $statement): string|false

Возвращает имя ODBC-курсора результата. Оно нужно редким низкоуровневым SQL/драйверным сценариям; для обычного foreach-подобного чтения имя не требуется.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_cursor(Odbc\Result $statement): string|false

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.

Возврат. Строка с именем курсора или false, если драйвер не смог его предоставить.

Отказ и диагностика. false означает отсутствие доступного имени, а не пустой набор строк. Предупреждение/SQLSTATE проверяют отдельно.

Путь вызова
  1. запрос создаёт result/cursor
  2. odbc_cursor просит у драйвера имя
  3. драйвер возвращает свою строку
  4. код использует её только там, где протокол требует positioned operation
Получить имя курсора результата SELECTСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, 'SELECT 10 AS id');
$cursor = odbc_cursor($result);
echo is_string($cursor) && $cursor !== '' ? "cursor=yes\n" : "cursor=no\n";
odbc_close($connection);
Ожидаемый результат
cursor=yes

Само имя генерирует драйвер, поэтому приложение проверяет договор string|false, а не ожидает конкретную случайную строку. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Получить курсор подготовленного отчётаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$statement = odbc_prepare($connection, 'SELECT CAST(? AS INTEGER) AS id');
if ($statement === false || !odbc_execute($statement, [7])) {
    throw new RuntimeException(odbc_error($connection).' '.odbc_errormsg($connection));
}
echo odbc_cursor($statement) === false ? "no-cursor\n" : "prepared-cursor\n";
odbc_close($connection);
Ожидаемый результат
prepared-cursor

Prepared statement после execute также представлен Odbc\Result и имеет курсор, если драйвер его предоставляет. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не делайте бизнес-логику зависимой от конкретного сгенерированного имени.
  • Имя курсора и позиция чтения — разные понятия.
  • Поддержка positioned update/delete зависит от СУБД.

Когда выбрать другое. Обычные SELECT/UPDATE с первичным ключом и параметрами понятнее и переносимее positioned-операций.

Связанные операции: odbc_exec(), odbc_prepare(), odbc_fetch_row().

odbc_data_sourceПеречисляет настроенные источники данных Driver Manager. Это диагностический инструмент для установки, а не способ выбирать рабочую базу из пользовательского ввода.

PHP 5.1.0+; PHP 8.4: Odbc\Connection и явный null в return type · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_data_source(Odbc\Connection $odbc, int $fetch_type): array|false|null

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

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_data_source(Odbc\Connection $odbc, int $fetch_type): array|false|null

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
int $fetch_typeSQL_FETCH_FIRST начинает перечисление источников данных, SQL_FETCH_NEXT продолжает его для того же соединения.

Возврат. Массив с ключами server/description при успехе, null после последнего DSN, false при ошибке.

Отказ и диагностика. false означает ошибку API/Driver Manager. Конец списка — отдельный null; SQLSTATE и сообщение читают при false.

Путь вызова
  1. SQL_FETCH_FIRST начинает перечисление
  2. Driver Manager возвращает одну запись
  3. SQL_FETCH_NEXT двигает внутреннюю позицию
  4. null завершает список, false сообщает отказ
Проверить capability перечисления независимо от рабочего соединенияСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$item = odbc_data_source($connection, SQL_FETCH_FIRST);
echo is_array($item) ? "enumeration=available\n" : "enumeration=empty\n";
$result = uodbcExec($connection, 'SELECT 1 AS alive');
echo "connection=", odbc_result($result, 'alive') == 1 ? "usable\n" : "failed\n";
odbc_close($connection);
Ожидаемый результат
enumeration=empty
connection=usable

Перечисление начинается SQL_FETCH_FIRST. В проверенной Windows/portable psqlODBC связке рабочий user DSN успешно подключается, но SQLDataSources не перечисляет ни одной записи. Это отдельная capability Driver Manager/драйвера: пустой список не доказывает, что DSN не работает. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Отличить конец перечисления от ошибкиСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$item = odbc_data_source($connection, SQL_FETCH_FIRST);
while (is_array($item)) {
    $item = odbc_data_source($connection, SQL_FETCH_NEXT);
}
echo $item === null ? "end=null\n" : "error=false\n";
odbc_close($connection);
Ожидаемый результат
end=null

В PHP 8.4 конец списка — null, а false оставлен для ошибки. Проверка while ($item) смешивает эти два исхода. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Список может отличаться у другого пользователя/разрядности процесса.
  • 64-битный PHP не видит 32-битный DSN как подходящий источник.
  • Не показывайте административный перечень DSN всем посетителям сайта.

Когда выбрать другое. Конфигурационный health-check может проверять заранее заданный DSN прямым odbc_connect(), не раскрывая весь список.

Связанные операции: odbc_connect(), odbc_error().

odbc_connection_string_is_quotedПроверяет, является ли одно значение корректно заключённым по правилам ODBC connection string.

PHP 8.2+ · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_connection_string_is_quoted(string $str): bool

Проверяет, является ли одно значение корректно заключённым по правилам ODBC connection string.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_connection_string_is_quoted(string $str): bool

ПараметрЧто передать
string $strОдно значение внутри ODBC connection string, без пары Ключ=Значение.

Возврат. true только для полной корректной формы в фигурных скобках; false для обычной или повреждённой строки.

Отказ и диагностика. Функция не подключается к базе и не проверяет корректность ключей DSN; она возвращает только bool формы значения.

Путь вызова
  1. получить одно значение, не всю DSN-строку
  2. проверить внешние скобки
  3. проверить удвоение внутренних }
  4. решить: оставить либо передать quote()
Проверить корректную ODBC-кавычку с экранированной скобкойСамостоятельный пример
<?php
declare(strict_types=1);

foreach (['{plain}', '{a}}b}', 'plain', '{broken}tail'] as $value) {
    echo $value, ':', odbc_connection_string_is_quoted($value) ? 'yes' : 'no', "\n";
}
Ожидаемый результат
{plain}:yes
{a}}b}:yes
plain:no
{broken}tail:no

ODBC использует внешние фигурные скобки, а закрывающую скобку внутри удваивает. Пример выполнен в PHP 8.5.11 с изолированно загруженным ext/odbc; подключение к базе ему не требуется.

Не заключать уже обработанное значение второй разСамостоятельный пример
<?php
declare(strict_types=1);

$input = '{North;Warehouse}';
$safe = odbc_connection_string_is_quoted($input)
    ? $input
    : odbc_connection_string_quote($input);
echo $safe, "\n";
Ожидаемый результат
{North;Warehouse}

Сначала проверяем готовую форму; quote() сама не распознаёт уже заключённое значение. Пример выполнен в PHP 8.5.11 с изолированно загруженным ext/odbc; подключение к базе ему не требуется.

Частые ошибки.

  • Не передавайте целиком Driver=...;Server=... как одно значение.
  • Проверка формы не делает недоверенный DSN разрешённым.
  • Уже quoted-значение не надо повторно quote() без осознанной причины.

Когда выбрать другое. Лучше собирать разрешённые ключи connection string из конфигурации и quote() только значения; имя драйвера выбирают по allowlist.

Связанные операции: odbc_connection_string_should_quote(), odbc_connection_string_quote(), odbc_connect().

odbc_connection_string_should_quoteСообщает, содержит ли одно значение специальные символы, из-за которых Driver Manager может неверно разобрать его без фигурных скобок.

PHP 8.2+ · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_connection_string_should_quote(string $str): bool

Сообщает, содержит ли одно значение специальные символы, из-за которых Driver Manager может неверно разобрать его без фигурных скобок.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_connection_string_should_quote(string $str): bool

ПараметрЧто передать
string $strОдно значение внутри ODBC connection string, без пары Ключ=Значение.

Возврат. bool: true означает «нужно quoted-представление», но не отвечает, заключена ли строка уже.

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

Путь вызова
  1. взять исходное значение
  2. найти разделители/краевые пробелы/скобки
  3. вернуть необходимость quoted-формы
  4. is_quoted решает, готова ли форма сейчас
Определить, требуется ли значение заключитьСамостоятельный пример
<?php
declare(strict_types=1);

foreach (['warehouse', 'North;Warehouse', ' leading', 'brace}'] as $value) {
    echo json_encode($value), ':', odbc_connection_string_should_quote($value) ? 'quote' : 'plain', "\n";
}
Ожидаемый результат
"warehouse":plain
"North;Warehouse":quote
" leading":quote
"brace}":quote

Точка с запятой, крайний пробел и фигурная скобка меняют разбор connection string и требуют quote(). Пример выполнен в PHP 8.5.11 с изолированно загруженным ext/odbc; подключение к базе ему не требуется.

Отдельно распознать уже заключённое значениеСамостоятельный пример
<?php
declare(strict_types=1);

$value = '{North;Warehouse}';
echo odbc_connection_string_should_quote($value) ? "has-specials\n" : "plain\n";
echo odbc_connection_string_is_quoted($value) ? "already-quoted\n" : "needs-quote\n";
Ожидаемый результат
has-specials
already-quoted

should_quote() видит специальные скобки и потому возвращает true даже для готовой формы; нужен отдельный is_quoted(). Пример выполнен в PHP 8.5.11 с изолированно загруженным ext/odbc; подключение к базе ему не требуется.

Частые ошибки.

  • true не значит, что строка ещё не quoted.
  • false не разрешает помещать пользовательский текст в имя ключа/драйвера.
  • Пароль после обработки всё равно остаётся секретом.

Когда выбрать другое. Если значение всегда проходит quote(), предварительная should_quote-проверка не обязательна; она нужна для читаемой сборки и диагностики.

Связанные операции: odbc_connection_string_is_quoted(), odbc_connection_string_quote().

odbc_connection_string_quoteПреобразует одно значение в ODBC-quoted форму: добавляет фигурные скобки и удваивает каждую закрывающую скобку внутри.

PHP 8.2+ · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_connection_string_quote(string $str): string

Преобразует одно значение в ODBC-quoted форму: добавляет фигурные скобки и удваивает каждую закрывающую скобку внутри.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_connection_string_quote(string $str): string

ПараметрЧто передать
string $strОдно значение внутри ODBC connection string, без пары Ключ=Значение.

Возврат. Всегда возвращает строку, даже если исходное значение не требовало quoted-формы или уже было заключено.

Отказ и диагностика. Функция не открывает соединение и не валидирует адрес/права. Она решает только синтаксическую границу одного значения.

Путь вызова
  1. программа выбирает разрешённый ключ
  2. quote получает только его значение
  3. } внутри удваивается
  4. готовая {…} форма добавляется после знака =
Безопасно включить склад с разделителем и скобкойСамостоятельный пример
<?php
declare(strict_types=1);

$value = 'North;Rack}2';
echo 'Warehouse=', odbc_connection_string_quote($value), "\n";
Ожидаемый результат
Warehouse={North;Rack}}2}

Внешние скобки удерживают точку с запятой внутри значения, внутренняя } удваивается. Пример выполнен в PHP 8.5.11 с изолированно загруженным ext/odbc; подключение к базе ему не требуется.

Собрать DSN-less фрагмент из разрешённых ключейСамостоятельный пример
<?php
declare(strict_types=1);

$server = 'db01.internal;ApplicationIntent=ReadOnly';
$database = 'orders}archive';
$fragment = 'Server='.odbc_connection_string_quote($server)
    .';Database='.odbc_connection_string_quote($database).';';
echo $fragment, "\n";
Ожидаемый результат
Server={db01.internal;ApplicationIntent=ReadOnly};Database={orders}}archive};

Инъекционный разделитель остаётся частью Server, а не новым ключом. Сам набор ключей Server/Database задаёт программа. Пример выполнен в PHP 8.5.11 с изолированно загруженным ext/odbc; подключение к базе ему не требуется.

Частые ошибки.

  • Не разрешайте посетителю задавать имя драйвера или произвольные ключи connection string.
  • Не quote() целиком пару Server=value.
  • Не выводите итоговую строку, если в ней есть пароль.

Когда выбрать другое. Для стабильного приложения предпочтителен заранее настроенный DSN с секретом вне кода; DSN-less строка полезна в контейнере/автоматической конфигурации.

Связанные операции: odbc_connection_string_is_quoted(), odbc_connection_string_should_quote(), odbc_connect().

odbc_execНемедленно выполняет один SQL-текст и возвращает объект результата. Подходит DDL и полностью статическим запросам; значения пользователя передают подготовленной команде.

PHP 4+; PHP 8.4 Odbc\Connection/Odbc\Result · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_exec(Odbc\Connection $odbc, string $query): Odbc\Result|false

Немедленно выполняет один SQL-текст и возвращает объект результата. Подходит DDL и полностью статическим запросам; значения пользователя передают подготовленной команде.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_exec(Odbc\Connection $odbc, string $query): Odbc\Result|false

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
string $querySQL-текст. Данные пользователя не склеивают с ним; для значений используют ? и odbc_execute().

Возврат. Odbc\Result при успехе, false при ошибке. Для INSERT/UPDATE объект нужен для диагностики/числа затронутых строк.

Отказ и диагностика. false плюс warning и diagnostic record. Немедленно сохраните odbc_error()/odbc_errormsg(); не продолжайте fetch с false.

Путь вызова
  1. программа формирует доверенный SQL
  2. драйвер подготавливает и выполняет его
  3. сервер возвращает статус/строки
  4. код проверяет false до fetch
Создать учебную таблицу и прочитать строку статическим SQLСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_exec_product');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_exec_product (id INTEGER PRIMARY KEY, name VARCHAR(50))');
    uodbcExec($connection, "INSERT INTO phpman_exec_product VALUES (1, 'Notebook')");
    $result = odbc_exec($connection, 'SELECT name FROM phpman_exec_product WHERE id=1');
    if ($result === false) { throw new RuntimeException(odbc_errormsg($connection)); }
    echo odbc_result($result, 'name'), "\n";
} finally {
    uodbcDrop($connection, 'phpman_exec_product');
    odbc_close($connection);
}
Ожидаемый результат
Notebook

odbc_exec подходит SQL, полностью заданному программой. Значение посетителя сюда не склеивается. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Безопасно выбрать разрешённый столбец сортировкиСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_exec_sort');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_exec_sort (id INTEGER PRIMARY KEY, price INTEGER)');
    uodbcExec($connection, 'INSERT INTO phpman_exec_sort VALUES (1, 300), (2, 100)');
    $requested = 'price';
    $allowed = ['id' => 'id', 'price' => 'price'];
    $column = $allowed[$requested] ?? 'id';
    $result = odbc_exec($connection, "SELECT id FROM phpman_exec_sort ORDER BY {$column}, id");
    if ($result === false) { throw new RuntimeException(odbc_errormsg($connection)); }
    while ($row = odbc_fetch_array($result)) { echo $row['id'], "\n"; }
} finally {
    uodbcDrop($connection, 'phpman_exec_sort');
    odbc_close($connection);
}
Ожидаемый результат
2
1

Placeholder не подставляет имя столбца. Структуру SQL выбирают по allowlist, а пользовательские значения передают prepare/execute. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не склеивайте с SQL текст формы, JSON или URL.
  • Placeholder не заменяет имя таблицы/столбца.
  • Несколько SQL-команд одной строкой ухудшают переносимость и обработку результатов.

Когда выбрать другое. odbc_prepare()+odbc_execute() для динамических значений; миграционный инструмент для схемы; нативный драйвер для специфического SQL API.

Связанные операции: odbc_prepare(), odbc_execute(), odbc_do(), odbc_error().

odbc_doИсторический псевдоним odbc_exec(): немедленно выполняет SQL и имеет тот же договор.

PHP 4+; alias odbc_exec; PHP 8.4 объектные типы · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_do(Odbc\Connection $odbc, string $query): Odbc\Result|false

Исторический псевдоним odbc_exec(): немедленно выполняет SQL и имеет тот же договор.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_do(Odbc\Connection $odbc, string $query): Odbc\Result|false

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
string $querySQL-текст. Данные пользователя не склеивают с ним; для значений используют ? и odbc_execute().

Возврат. Odbc\Result либо false — полностью как odbc_exec().

Отказ и диагностика. Тот же false/warning/diagnostics, что у odbc_exec(). Отдельного поведения у alias нет.

Путь вызова
  1. вызов alias попадает в реализацию odbc_exec
  2. SQL выполняется драйвером
  3. возвращается тот же тип результата
  4. дальнейшая обработка ничем не отличается
Встретить исторический псевдоним в старом проектеСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = odbc_do($connection, "SELECT 'legacy-alias' AS label");
if ($result === false) { throw new RuntimeException(odbc_errormsg($connection)); }
echo odbc_result($result, 'label'), "\n";
odbc_close($connection);
Ожидаемый результат
legacy-alias

odbc_do — настоящий alias odbc_exec, а не отдельный способ выполнения. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Обновить учебный статус через alias и проверить число строкСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_do_status');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_do_status (id INTEGER PRIMARY KEY, state VARCHAR(20))');
    uodbcExec($connection, "INSERT INTO phpman_do_status VALUES (1, 'new')");
    $result = odbc_do($connection, "UPDATE phpman_do_status SET state='sent' WHERE id=1");
    if ($result === false) { throw new RuntimeException(odbc_errormsg($connection)); }
    echo "changed=", odbc_num_rows($result), "\n";
} finally {
    uodbcDrop($connection, 'phpman_do_status');
    odbc_close($connection);
}
Ожидаемый результат
changed=1

Пример помогает читать legacy-код; в новом коде одно название odbc_exec уменьшает лишние варианты. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не считайте do более быстрым или безопасным.
  • Не используйте alias для сокрытия склейки пользовательского SQL.
  • Смешивание двух имён усложняет поиск по проекту.

Когда выбрать другое. В новом коде используйте odbc_exec(); для значений — prepare/execute.

Связанные операции: odbc_exec(), odbc_prepare(), odbc_num_rows().

odbc_prepareСоздаёт подготовленную команду с позиционными знаками ?. Это граница между структурой SQL и данными формы/API.

PHP 4+; PHP 8.4 Odbc\Connection/Odbc\Result · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_prepare(Odbc\Connection $odbc, string $query): Odbc\Result|false

Создаёт подготовленную команду с позиционными знаками ?. Это граница между структурой SQL и данными формы/API.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_prepare(Odbc\Connection $odbc, string $query): Odbc\Result|false

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
string $querySQL-текст. Данные пользователя не склеивают с ним; для значений используют ? и odbc_execute().

Возврат. Odbc\Result при успехе, false при отказе подготовки. Сам запрос с параметрами выполняется только odbc_execute().

Отказ и диагностика. false может означать синтаксис, неподдерживаемую возможность или невозможность вывести тип параметра. Сохраните diagnostics до следующего ODBC-вызова.

Путь вызова
  1. SQL содержит ? без кавычек
  2. драйвер разбирает/готовит команду
  3. возвращается statement как Odbc\Result
  4. execute позже связывает значения
Подготовить поиск товара по идентификаторуСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_prepare_product');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_prepare_product (id INTEGER PRIMARY KEY, name VARCHAR(50))');
    uodbcExec($connection, "INSERT INTO phpman_prepare_product VALUES (1, 'Pen'), (2, 'Book')");
    $statement = odbc_prepare($connection, 'SELECT name FROM phpman_prepare_product WHERE id=CAST(? AS INTEGER)');
    if ($statement === false) { throw new RuntimeException(odbc_errormsg($connection)); }
    odbc_execute($statement, [2]);
    $row = odbc_fetch_array($statement);
    echo $row['name'], "\n";
} finally {
    uodbcDrop($connection, 'phpman_prepare_product');
    odbc_close($connection);
}
Ожидаемый результат
Book

SQL-компоновка и значение id разделены. CAST делает ожидаемый тип placeholder явным для разных драйверов. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Один раз подготовить команду и выполнить с двумя значениямиСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$statement = odbc_prepare($connection, 'SELECT CAST(? AS INTEGER) * 2 AS doubled');
if ($statement === false) { throw new RuntimeException(odbc_errormsg($connection)); }
foreach ([3, 8] as $value) {
    if (!odbc_execute($statement, [$value])) { throw new RuntimeException(odbc_errormsg($connection)); }
    $row = odbc_fetch_array($statement);
    echo $row['doubled'], "\n";
}
odbc_close($connection);
Ожидаемый результат
6
16

Повторное execute меняет данные, а SQL-контракт остаётся одним. Выигрыш зависит от драйвера и числа повторов; измеряйте. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не заключайте ? в одинарные кавычки.
  • Количество ? должно совпасть с params.
  • Идентификаторы нельзя передать placeholder-ом.

Когда выбрать другое. Для однократного полностью статического SQL достаточно odbc_exec(); PDO даёт именованные параметры на поддерживаемых драйверах.

Связанные операции: odbc_execute(), odbc_exec(), odbc_free_result().

odbc_executeВыполняет statement от odbc_prepare(), подставляя позиционные значения из массива. Один statement можно запускать повторно для пакета строк.

PHP 4+; PHP 8.0 удалён неиспользуемый flags; PHP 8.4 Odbc\Result parameter · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_execute(Odbc\Result $statement, array $params = []): bool

Выполняет statement от odbc_prepare(), подставляя позиционные значения из массива. Один statement можно запускать повторно для пакета строк.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_execute(Odbc\Result $statement, array $params = []): bool

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.
array $params (по умолчанию array ( ))Значения для знаков ? строго по порядку. Имена параметров этот API не поддерживает.

Возврат. true при успехе, false при отказе. Строки результата читают из того же объекта statement.

Отказ и диагностика. false плюс warning; diagnostics могут относиться к execute. SQLSTATE класса 01 — предупреждение при успешном true, его учитывают отдельно от класса ошибки. OUT/INOUT-параметры процедур этим API надёжно не покрываются — официальный manual предлагает нативный драйвер.

Путь вызова
  1. массив params проверен приложением
  2. значения сопоставляются ? по порядку
  3. драйвер связывает/конвертирует их
  4. сервер выполняет запрос, затем fetch читает результат
Добавить две позиции одной подготовленной командойСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_execute_item');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_execute_item (id INTEGER PRIMARY KEY, name VARCHAR(50))');
    $statement = odbc_prepare($connection, 'INSERT INTO phpman_execute_item (id, name) VALUES (CAST(? AS INTEGER), ?)');
    if ($statement === false) { throw new RuntimeException(odbc_errormsg($connection)); }
    foreach ([[1, 'Pen'], [2, 'Notebook']] as $params) {
        if (!@odbc_execute($statement, $params)) { throw new RuntimeException(odbc_errormsg($connection)); }
    }
    $result = uodbcExec($connection, 'SELECT COUNT(*) AS total FROM phpman_execute_item');
    echo "rows=", odbc_result($result, 'total'), "\n";
} finally {
    uodbcDrop($connection, 'phpman_execute_item');
    odbc_close($connection);
}
Ожидаемый результат
rows=2

Массив params идёт строго слева направо. Значения не получают SQL-кавычки в PHP. psqlODBC может дополнительно выдать SQLSTATE класса 01 (warning, например 01S02 о смене cursor updatability) при успешном true; production-код пишет такую диагностику отдельно, не превращая её автоматически в отказ. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Сохранить обычный апостроф без склейки SQLСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_execute_customer');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_execute_customer (id INTEGER PRIMARY KEY, name VARCHAR(50))');
    $statement = odbc_prepare($connection, 'INSERT INTO phpman_execute_customer VALUES (1, ?)');
    if ($statement === false || !@odbc_execute($statement, ["O'Reilly"])) {
        throw new RuntimeException(odbc_errormsg($connection));
    }
    $row = uodbcExec($connection, 'SELECT name FROM phpman_execute_customer WHERE id=1');
    echo odbc_result($row, 'name'), "\n";
} finally {
    uodbcDrop($connection, 'phpman_execute_customer');
    odbc_close($connection);
}
Ожидаемый результат
O'Reilly

Апостроф внутри обычной строки — данные. Особая legacy-граница ext/odbc: строка, которая целиком начинается и заканчивается одинарной кавычкой, трактуется как имя файла; такие значения надо отдельно запрещать/нормализовать и не передавать из недоверенного ввода. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не заключайте ? в SQL-кавычки.
  • Все элементы params преобразуются к строкам.
  • Не путайте successful true с отсутствием diagnostics: драйвер может вернуть warning класса 01.
  • Legacy-правило: строка, начинающаяся и заканчивающаяся ', воспринимается как путь к файлу — это риск утечки локального файла.

Когда выбрать другое. Нативное расширение/драйвер для OUT-параметров, typed binding и LOB; batch/COPY для больших импортов.

Связанные операции: odbc_prepare(), odbc_fetch_array(), odbc_error().

odbc_next_resultПереводит result к следующему набору строк от batch/stored procedure. Нужна, когда один вызов осознанно возвращает несколько результатов.

PHP 5.4+; PHP 8.4 Odbc\Result · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_next_result(Odbc\Result $statement): bool

Переводит result к следующему набору строк от batch/stored procedure. Нужна, когда один вызов осознанно возвращает несколько результатов.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_next_result(Odbc\Result $statement): bool

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.

Возврат. true, если следующий result set доступен, false при завершении или отказе.

Отказ и диагностика. false объединяет нормальный конец и отказ. Если ожидался ещё один набор, прочитайте odbc_error()/odbc_errormsg().

Путь вызова
  1. полностью обработать текущий набор
  2. вызвать next_result
  3. при true читать новый набор
  4. при false завершить и проверить diagnostics при подозрении на ошибку
Прочитать два результата пакетного вызоваСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, 'SELECT 1 AS step; SELECT 2 AS step');
do {
    $row = odbc_fetch_array($result);
    echo "step=", $row['step'], "\n";
} while (odbc_next_result($result));
odbc_close($connection);
Ожидаемый результат
step=1
step=2

После полного чтения текущего результата next_result переводит тот же объект на следующий набор. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Понять завершение после одного результатаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, 'SELECT 7 AS value');
$row = odbc_fetch_array($result);
echo "value=", $row['value'], "\n";
echo odbc_next_result($result) ? "more\n" : "done\n";
odbc_close($connection);
Ожидаемый результат
value=7
done

false здесь означает, что следующего result set нет. Ошибку отличают по SQLSTATE/сообщению и контексту вызова. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не смешивайте колонки разных наборов в одну схему без проверки.
  • Не все драйверы разрешают несколько SQL-команд строкой.
  • Текущий набор надо обработать/освободить по договору драйвера.

Когда выбрать другое. Два явных запроса легче типизировать и диагностировать; stored procedure оправдана, когда граница операции находится в БД.

Связанные операции: odbc_exec(), odbc_fetch_array(), odbc_free_result().

odbc_fetch_arrayЧитает следующую (или указанную поддерживаемым курсором) строку как ассоциативный массив. Это удобный формат для шаблона, JSON-модели или последующей проверки.

PHP 4+; PHP 8.4 Odbc\Result; row nullable · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_fetch_array(Odbc\Result $statement, ?int $row = null): array|false

Читает следующую (или указанную поддерживаемым курсором) строку как ассоциативный массив. Это удобный формат для шаблона, JSON-модели или последующей проверки.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_fetch_array(Odbc\Result $statement, ?int $row = null): array|false

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.
?int $row (по умолчанию NULL)Необязательный номер строки. Поддержка произвольного позиционирования зависит от курсора и драйвера.

Возврат. Ассоциативный array либо false, когда строки закончились/операция не удалась.

Отказ и диагностика. false объединяет конец данных и отказ; если конец неожиданный, прочитайте diagnostics. Имена/регистр колонок определяются драйвером и SQL aliases.

Путь вызова
  1. result хранит набор и текущую позицию
  2. fetch двигает курсор
  3. драйвер преобразует ODBC-значения
  4. PHP получает массив по именам колонок
Перебрать каталог ассоциативными массивамиСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT * FROM (VALUES (1, 'Pen'), (2, 'Book')) AS products(id, name) ORDER BY id");
while ($row = odbc_fetch_array($result)) {
    echo $row['id'], ':', $row['name'], "\n";
}
odbc_close($connection);
Ожидаемый результат
1:Pen
2:Book

Каждый fetch возвращает новую строку как массив «имя столбца => значение»; false завершает цикл. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Перейти к третьей строке поддерживаемого курсораСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT * FROM (VALUES (10, 'A'), (20, 'B'), (30, 'C')) AS items(id, code) ORDER BY id");
$row = odbc_fetch_array($result, 3);
echo $row['id'], ':', $row['code'], "\n";
odbc_close($connection);
Ожидаемый результат
30:C

ODBC row_number начинается с 1. Произвольное позиционирование зависит от курсора/драйвера; последовательный цикл переносимее. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не обращайтесь к ключу до проверки false.
  • SELECT с одинаковыми именами колонок перезапишет смысл ключа — задайте aliases.
  • Большой fetch-all массив лучше заменить последовательной обработкой.

Когда выбрать другое. fetch_object для простого чтения свойств; fetch_row+result для поэлементного legacy-кода; PDO для более богатых fetch modes.

Связанные операции: odbc_fetch_object(), odbc_fetch_row(), odbc_result().

odbc_fetch_objectЧитает строку результата как stdClass со свойствами по именам колонок.

PHP 4+; PHP 8.4 Odbc\Result; row nullable · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_fetch_object(Odbc\Result $statement, ?int $row = null): stdClass|false

Читает строку результата как stdClass со свойствами по именам колонок.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_fetch_object(Odbc\Result $statement, ?int $row = null): stdClass|false

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.
?int $row (по умолчанию NULL)Необязательный номер строки. Поддержка произвольного позиционирования зависит от курсора и драйвера.

Возврат. stdClass или false при конце/отказе.

Отказ и диагностика. false нужно проверить до ->property. Коллизии/неудобные имена столбцов решают SQL aliases.

Путь вызова
  1. курсор выбирает строку
  2. имена колонок становятся свойствами
  3. значения конвертируются драйвером
  4. код проверяет false до доступа ->
Прочитать товар через свойства объектаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT 5 AS id, 'Cable' AS name");
$row = odbc_fetch_object($result);
if ($row === false) { throw new RuntimeException('Строка не найдена'); }
echo $row->id, ':', $row->name, "\n";
odbc_close($connection);
Ожидаемый результат
5:Cable

Возвращается stdClass, а не объект предметной модели: в нём нет валидации и методов товара. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Преобразовать строку отчёта в явный массив ответаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT 'INV-7' AS number, CAST(1250 AS INTEGER) AS total");
$row = odbc_fetch_object($result);
$payload = $row === false ? null : ['number' => $row->number, 'total' => (int) $row->total];
echo json_encode($payload, JSON_UNESCAPED_UNICODE), "\n";
odbc_close($connection);
Ожидаемый результат
{"number":"INV-7","total":1250}

Явное преобразование фиксирует внешнюю схему и тип total; не отдавайте произвольный row object напрямую как публичный API. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • stdClass не валидирует типы.
  • Регистр свойств зависит от возвращённых имён.
  • Не путайте объект строки с Odbc\Result.

Когда выбрать другое. Ассоциативный массив проще для динамических колонок; явный DTO/mapper даёт стабильный контракт приложения.

Связанные операции: odbc_fetch_array(), odbc_fetch_row(), odbc_result().

odbc_fetch_intoЗаписывает строку в переданную по ссылке переменную как числовой массив и возвращает число полей.

PHP 4+; PHP 8.4 Odbc\Result; row nullable · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_fetch_into(Odbc\Result $statement, mixed &$array, ?int $row = null): int|false

Записывает строку в переданную по ссылке переменную как числовой массив и возвращает число полей.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_fetch_into(Odbc\Result $statement, mixed &$array, ?int $row = null): int|false

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.
mixed $arrayПеременная, в которую odbc_fetch_into() запишет числовой массив текущей строки.
?int $row (по умолчанию NULL)Необязательный номер строки. Поддержка произвольного позиционирования зависит от курсора и драйвера.

Возврат. int с числом колонок или false при конце/отказе; массив изменяется как побочный эффект.

Отказ и диагностика. false не равно 0: проверяйте строго !== false. После конца не используйте старое содержимое массива как новую строку.

Путь вызова
  1. передаётся переменная &$array
  2. fetch двигает курсор
  3. значения записываются по индексам 0..n-1
  4. возвращаемое n позволяет проверить структуру
Получить числовой массив и число колонокСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT 4 AS id, 'Box' AS name");
$values = [];
$count = odbc_fetch_into($result, $values);
echo "fields={$count}\n";
echo $values[0], ':', $values[1], "\n";
odbc_close($connection);
Ожидаемый результат
fields=2
4:Box

Функция изменяет второй аргумент по ссылке и возвращает число полей; индексы массива начинаются с 0. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Переиспользовать переменную при потоковой обработкеСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT * FROM (VALUES (1, 100), (2, 250)) AS lines(id, amount) ORDER BY id");
$values = [];
$sum = 0;
while (odbc_fetch_into($result, $values) !== false) {
    $sum += (int) $values[1];
}
echo "sum={$sum}\n";
odbc_close($connection);
Ожидаемый результат
sum=350

На каждой итерации массив получает текущую строку; это не загружает весь result в один PHP-массив. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Второй аргумент обязан быть переменной.
  • Индексы массива с 0, а odbc_result field number с 1.
  • Числовые позиции хрупки при изменении SELECT.

Когда выбрать другое. fetch_array с именами колонок читается лучше; fetch_into полезен для компактного legacy/экспортного цикла.

Связанные операции: odbc_fetch_array(), odbc_num_fields(), odbc_binmode().

odbc_fetch_rowПеремещает курсор на следующую или указанную строку; данные затем читают odbc_result().

PHP 4+; PHP 8.4 Odbc\Result; row nullable · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_fetch_row(Odbc\Result $statement, ?int $row = null): bool

Перемещает курсор на следующую или указанную строку; данные затем читают odbc_result().

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_fetch_row(Odbc\Result $statement, ?int $row = null): bool

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.
?int $row (по умолчанию NULL)Необязательный номер строки. Поддержка произвольного позиционирования зависит от курсора и драйвера.

Возврат. true, если строка доступна; false при конце/отказе.

Отказ и диагностика. false обычно завершает последовательный цикл; неожиданный false проверяют по diagnostics. row_number может быть неподдержан типом курсора.

Путь вызова
  1. result имеет текущую позицию
  2. fetch_row выбирает строку
  3. true подтверждает позицию
  4. odbc_result читает поле этой строки
Двигать курсор и читать нужные поля по имениСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT * FROM (VALUES (1, 'new'), (2, 'paid')) AS orders(id, state) ORDER BY id");
while (odbc_fetch_row($result)) {
    echo odbc_result($result, 'id'), ':', odbc_result($result, 'state'), "\n";
}
odbc_close($connection);
Ожидаемый результат
1:new
2:paid

fetch_row только позиционирует курсор; каждое поле затем извлекается odbc_result(). Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Перейти ко второй строке статического курсораСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT * FROM (VALUES (10), (20), (30)) AS valueset(value) ORDER BY value");
if (!odbc_fetch_row($result, 2)) { throw new RuntimeException('Нет строки 2'); }
echo odbc_result($result, 1), "\n";
odbc_close($connection);
Ожидаемый результат
20

Номер строки начинается с 1. Некоторые драйверы/forward-only курсоры произвольный переход не поддерживают. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • После false не читайте odbc_result.
  • Нумерация строк с 1.
  • Многократный odbc_result делает код многословнее массива.

Когда выбрать другое. fetch_array/object возвращает строку одним вызовом; forward-only последовательное чтение обычно дешевле произвольного позиционирования.

Связанные операции: odbc_result(), odbc_fetch_array(), odbc_cursor().

odbc_resultЧитает одно поле текущей строки по имени или номеру. Перед этим курсор должен быть установлен fetch_row().

PHP 4+; PHP 8.4 Odbc\Result · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_result(Odbc\Result $statement, string|int $field): string|bool|null

Читает одно поле текущей строки по имени или номеру. Перед этим курсор должен быть установлен fetch_row().

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_result(Odbc\Result $statement, string|int $field): string|bool|null

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.
string|int $fieldНомер столбца с 1 либо его имя. В ODBC позиции полей начинаются с 1.

Возврат. string|bool|null по данным/режиму. Для бинарного passthru функция может отправить данные прямо в output вместо обычного возврата.

Отказ и диагностика. Неверное поле даёт warning/false-подобный исход в зависимости от версии/драйвера; проверяйте схему заранее. NULL — нормальное значение, не ошибка.

Путь вызова
  1. fetch_row выбирает строку
  2. field выбирает колонку
  3. binmode/longreadlen задают преобразование
  4. значение возвращается либо passthru идёт в output
Прочитать поле по имени и позицииСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT 12 AS id, 'Ready' AS state");
odbc_fetch_row($result);
echo odbc_result($result, 'id'), "\n";
echo odbc_result($result, 2), "\n";
odbc_close($connection);
Ожидаемый результат
12
Ready

Имя устойчивее порядка SELECT; числовая позиция ODBC начинается с 1. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Отличить SQL NULL от пустой строкиСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT CAST(NULL AS VARCHAR(20)) AS note, CAST('' AS VARCHAR(20)) AS empty_text");
odbc_fetch_row($result);
echo odbc_result($result, 'note') === null ? "note=NULL\n" : "note=value\n";
echo odbc_result($result, 'empty_text') === '' ? "empty=string\n" : "empty=other\n";
odbc_close($connection);
Ожидаемый результат
note=NULL
empty=string

SQL NULL приходит как null, пустая строка остаётся строкой: проверки должны быть строгими. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Номер поля начинается с 1.
  • Не путайте null и false.
  • PASSTHRU способен неожиданно писать байты в HTTP-ответ.

Когда выбрать другое. fetch_array/object проще, когда нужны несколько колонок; result полезен для legacy-цикла и одного поля.

Связанные операции: odbc_fetch_row(), odbc_field_num(), odbc_binmode(), odbc_longreadlen().

odbc_result_allПечатает весь результат как HTML-таблицу и возвращает число строк. Это legacy-помощник, устаревший с PHP 8.1.

PHP 4+; deprecated с PHP 8.1; PHP 8.4 Odbc\Result · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_result_all(Odbc\Result $statement, string $format = ''): int|false

Печатает весь результат как HTML-таблицу и возвращает число строк. Это legacy-помощник, устаревший с PHP 8.1.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_result_all(Odbc\Result $statement, string $format = ''): int|false

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.
string $format (по умолчанию '')Дополнительные атрибуты старого HTML-вывода; функцию odbc_result_all() не используют с недоверенным текстом.

Возврат. int количества строк либо false. Основной эффект — прямой HTML-вывод.

Отказ и диагностика. false сообщает отказ, но частичный output уже мог быть отправлен. Deprecated warning подавлять в новом коде не решение — функцию заменяют.

Путь вызова
  1. функция сама обходит строки
  2. печатает table/th/td
  3. возвращает число обработанных строк
  4. вывод уже смешан с представлением
Перехватить legacy HTML-таблицу вместо прямого выводаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT * FROM (VALUES (1, 'Pen'), (2, 'Book')) AS products(id, name) ORDER BY id");
ob_start();
$rows = @odbc_result_all($result);
$html = (string) ob_get_clean();
echo "rows={$rows}\n";
echo str_contains($html, '<table') && str_contains($html, 'Pen') ? "html=yes\n" : "html=no\n";
odbc_close($connection);
Ожидаемый результат
rows=2
html=yes

Функция печатает HTML сама; output buffering лишь позволяет увидеть это поведение. Для нового интерфейса лучше собственный шаблон с htmlspecialchars(). Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Увидеть вставку format в legacy table-тегСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT 'safe' AS value");
ob_start();
$rows = @odbc_result_all($result, 'class="report"');
$html = (string) ob_get_clean();
echo "rows={$rows}\n";
echo str_contains($html, 'class="report"') ? "class=yes\n" : "class=no\n";
odbc_close($connection);
Ожидаемый результат
rows=1
class=yes

format попадает в HTML-атрибуты без современного шаблонного контракта; недоверенный ввод сюда передавать нельзя. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Deprecated с PHP 8.1.
  • Смешивает данные и HTML.
  • format/данные требуют защиты от HTML-инъекции.

Когда выбрать другое. fetch_array в цикле + шаблон, который экранирует каждую ячейку; JSON API возвращает структуру, а UI строит таблицу отдельно.

Связанные операции: odbc_fetch_array(), odbc_num_rows().

odbc_free_resultОсвобождает курсор и другие объекты, связанные с Odbc\Result. Соединение при этом остаётся открытым.

PHP 4+; PHP 8.4 Odbc\Result; return literal true · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_free_result(Odbc\Result $statement): true

Освобождает курсор и другие объекты, связанные с Odbc\Result. Соединение при этом остаётся открытым.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_free_result(Odbc\Result $statement): true

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.

Возврат. Literal true; после вызова result непригоден.

Отказ и диагностика. Неверный/уже закрытый объект вызывает Error; повторный free не является безопасной идемпотентной операцией.

Путь вызова
  1. код закончил/прервал чтение
  2. free сообщает драйверу освободить statement/result
  3. память/курсор становятся доступными
  4. соединение можно использовать дальше
Освободить result после обработкиСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, 'SELECT 1 AS id');
$row = odbc_fetch_array($result);
echo $row['id'], "\n";
echo odbc_free_result($result) ? "freed\n" : "not-freed\n";
try { odbc_fetch_array($result); } catch (Error) { echo "unusable\n"; }
odbc_close($connection);
Ожидаемый результат
1
freed
unusable

После free тот же Odbc\Result закрыт и больше не читается. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Освободить ненужный большой отчёт до конца скриптаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, 'SELECT generate_series(1, 100) AS id');
odbc_fetch_row($result);
echo "first=", odbc_result($result, 1), "\n";
odbc_free_result($result);
echo "released-early\n";
odbc_close($connection);
Ожидаемый результат
first=1
released-early

Если остальные строки не нужны, явное освобождение снижает время владения клиентским курсором/буфером. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не читать result после free.
  • Free result не делает commit/rollback.
  • Не путать освобождение результата и закрытие connection.

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

Связанные операции: odbc_close(), odbc_exec(), odbc_prepare().

odbc_num_rowsВозвращает число строк, затронутых DML, либо доступное драйверу число строк result. Для SELECT поддержка/момент подсчёта различаются.

PHP 4+; PHP 8.4 Odbc\Result · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_num_rows(Odbc\Result $statement): int

Возвращает число строк, затронутых DML, либо доступное драйверу число строк result. Для SELECT поддержка/момент подсчёта различаются.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_num_rows(Odbc\Result $statement): int

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.

Возврат. int; -1 часто означает, что драйвер не знает число заранее.

Отказ и диагностика. Не трактуйте любое 0 как ошибку и любое -1 как пустой SELECT. Семантика зависит от команды/драйвера.

Путь вызова
  1. SQL выполняется
  2. драйвер получает affected-row count
  3. num_rows запрашивает его
  4. код интерпретирует 0/-1 по типу команды
Проверить затронутые строки UPDATEСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_num_rows');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_num_rows (id INTEGER PRIMARY KEY, state VARCHAR(20))');
    uodbcExec($connection, "INSERT INTO phpman_num_rows VALUES (1, 'new'), (2, 'new')");
    $result = uodbcExec($connection, "UPDATE phpman_num_rows SET state='sent' WHERE id=2");
    echo "changed=", odbc_num_rows($result), "\n";
} finally {
    uodbcDrop($connection, 'phpman_num_rows');
    odbc_close($connection);
}
Ожидаемый результат
changed=1

Для DML число затронутых строк помогает проверить ожидаемый эффект. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Отличить отсутствие совпадения DELETEСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_num_rows_delete');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_num_rows_delete (id INTEGER PRIMARY KEY)');
    uodbcExec($connection, 'INSERT INTO phpman_num_rows_delete VALUES (1)');
    $result = uodbcExec($connection, 'DELETE FROM phpman_num_rows_delete WHERE id=99');
    echo "deleted=", odbc_num_rows($result), "\n";
} finally {
    uodbcDrop($connection, 'phpman_num_rows_delete');
    odbc_close($connection);
}
Ожидаемый результат
deleted=0

Ноль — корректный результат «строка не найдена», а не автоматически ошибка. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • SELECT count может быть неизвестен до fetch.
  • UPDATE одинаковым значением может считаться по-разному драйверами.
  • Для существования строки надёжнее SELECT/RETURNING по возможностям СУБД.

Когда выбрать другое. Явный SELECT COUNT нужен только когда действительно требуется count; не считайте весь большой результат ради пагинации без необходимости.

Связанные операции: odbc_exec(), odbc_fetch_row().

odbc_num_fieldsВозвращает число колонок в result — ширину одной строки результата.

PHP 4+; PHP 8.4 Odbc\Result · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_num_fields(Odbc\Result $statement): int

Возвращает число колонок в result — ширину одной строки результата.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_num_fields(Odbc\Result $statement): int

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.

Возврат. int; поля затем нумеруются от 1 до этого значения.

Отказ и диагностика. Неверный result вызывает Error/TypeError. Ноль возможен для команды без набора колонок и не равен числу затронутых строк.

Путь вызова
  1. SQL формирует список SELECT
  2. драйвер описывает metadata
  3. num_fields считает descriptor columns
  4. код обходит позиции 1..n
Проверить ширину строки отчётаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT 1 AS id, 'Pen' AS name, 120 AS price");
echo "fields=", odbc_num_fields($result), "\n";
odbc_close($connection);
Ожидаемый результат
fields=3

Число колонок доступно до чтения строк и помогает построить диагностический экспорт. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Увидеть, что COUNT возвращает один столбецСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, 'SELECT COUNT(*) AS total FROM pg_catalog.pg_class');
echo odbc_num_fields($result), "\n";
odbc_close($connection);
Ожидаемый результат
1

Количество исходных строк не связано с числом колонок агрегатного result. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Нумерация field API начинается с 1.
  • SELECT * меняет ширину при эволюции схемы.
  • Не путайте fields и rows.

Когда выбрать другое. Для известного application query перечисляйте колонки явно; dynamic metadata нужна экспортёрам/админ-инструментам.

Связанные операции: odbc_field_name(), odbc_field_type(), odbc_fetch_into().

odbc_field_nameВозвращает имя/alias колонки result по позиции.

PHP 4+; PHP 8.4 Odbc\Result · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_field_name(Odbc\Result $statement, int $field): string|false

Возвращает имя/alias колонки result по позиции.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_field_name(Odbc\Result $statement, int $field): string|false

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.
int $fieldНомер столбца с 1 либо его имя. В ODBC позиции полей начинаются с 1.

Возврат. string либо false для несуществующего поля.

Отказ и диагностика. false для позиции вне диапазона; не преобразуйте его молча в пустой заголовок.

Путь вызова
  1. num_fields задаёт диапазон
  2. позиция начинается с 1
  3. драйвер возвращает descriptor name
  4. код сопоставляет имя со своей схемой
Получить имена колонок по позициямСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT 1 AS product_id, 'Pen' AS product_name");
for ($field = 1; $field <= odbc_num_fields($result); $field++) {
    echo $field, ':', odbc_field_name($result, $field), "\n";
}
odbc_close($connection);
Ожидаемый результат
1:product_id
2:product_name

SQL aliases становятся понятными заголовками результата. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Собрать технические заголовки CSV-экспортаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT 'INV-1' AS invoice_number, 500 AS total_kopecks");
$headers = [];
for ($field = 1; $field <= odbc_num_fields($result); $field++) {
    $headers[] = odbc_field_name($result, $field);
}
echo implode(',', $headers), "\n";
odbc_close($connection);
Ожидаемый результат
invoice_number,total_kopecks

Техническое имя не всегда подходит человеку: публичные подписи лучше брать из собственной карты перевода. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Регистр/усечение могут зависеть от драйвера.
  • Дубликаты имён требуют SQL aliases.
  • Имя БД не заменяет локализованную подпись UI.

Когда выбрать другое. Явная application schema стабильнее динамического metadata для публичного API.

Связанные операции: odbc_num_fields(), odbc_field_num(), odbc_fetch_array().

odbc_field_typeВозвращает имя типа колонки, сообщённое ODBC-драйвером.

PHP 4+; PHP 8.4 Odbc\Result · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_field_type(Odbc\Result $statement, int $field): string|false

Возвращает имя типа колонки, сообщённое ODBC-драйвером.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_field_type(Odbc\Result $statement, int $field): string|false

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.
int $fieldНомер столбца с 1 либо его имя. В ODBC позиции полей начинаются с 1.

Возврат. string либо false для неверной позиции.

Отказ и диагностика. false для отсутствующего поля. Текст типа не стандартизирован как единое имя между всеми драйверами.

Путь вызова
  1. result descriptor содержит SQL type
  2. драйвер даёт текстовое имя
  3. приложение нормализует семейство
  4. экспорт/диагностика выбирает обработчик
Прочитать ODBC-типы трёх колонокСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT CAST(12 AS INTEGER) AS id, CAST('abc' AS VARCHAR(20)) AS label, CAST(12.34 AS NUMERIC(8,2)) AS amount");
for ($field = 1; $field <= 3; $field++) { echo odbc_field_type($result, $field), "\n"; }
odbc_close($connection);
Ожидаемый результат
int4
varchar
numeric

Имена int4/varchar/numeric — представление psqlODBC; другой драйвер может назвать тип иначе. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Выбрать формат экспорта по семейству типаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT CAST(12.34 AS NUMERIC(8,2)) AS amount");
$type = strtolower((string) odbc_field_type($result, 1));
$kind = str_contains($type, 'numeric') || str_contains($type, 'decimal') ? 'number' : 'text';
echo "kind={$kind}\n";
odbc_close($connection);
Ожидаемый результат
kind=number

Для кросс-драйверного кода нужна карта семейств и fallback, а не один жёсткий vendor-name. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не ветвитесь только по PostgreSQL int4.
  • Тип metadata не валидирует уже полученную строку.
  • Дата/decimal всё равно могут прийти как PHP string.

Когда выбрать другое. Собственная схема запроса и явное преобразование надёжнее динамического определения для бизнес-кода.

Связанные операции: odbc_gettypeinfo(), odbc_field_len(), odbc_field_scale().

odbc_field_lenВозвращает объявленную длину/размер колонки из descriptor result, а не длину текущего значения.

PHP 4+; PHP 8.4 Odbc\Result · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_field_len(Odbc\Result $statement, int $field): int|false

Возвращает объявленную длину/размер колонки из descriptor result, а не длину текущего значения.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_field_len(Odbc\Result $statement, int $field): int|false

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.
int $fieldНомер столбца с 1 либо его имя. В ODBC позиции полей начинаются с 1.

Возврат. int либо false для неверного поля.

Отказ и диагностика. false для позиции вне диапазона. Единицы и смысл для binary/text/numeric зависят от SQL-типа и драйвера.

Путь вызова
  1. драйвер описывает column size
  2. field_len читает descriptor
  3. код отличает capacity от actual value
  4. UI/экспорт применяет собственные ограничения
Узнать объявленную длину VARCHAR и INTEGERСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT CAST(7 AS INTEGER) AS id, CAST('abc' AS VARCHAR(20)) AS label");
echo "id=", odbc_field_len($result, 1), "\n";
echo "label=", odbc_field_len($result, 2), "\n";
odbc_close($connection);
Ожидаемый результат
id=10
label=20

Для psqlODBC INTEGER сообщает display/precision 10, VARCHAR(20) — 20. Это descriptor, не strlen текущего значения. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Сравнить metadata length и фактическую строкуСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT CAST('abc' AS VARCHAR(20)) AS label");
$row = odbc_fetch_array($result);
echo "declared=", odbc_field_len($result, 1), " actual=", strlen($row['label']), "\n";
odbc_close($connection);
Ожидаемый результат
declared=20 actual=3

Поле допускает до 20 единиц по договору драйвера, но конкретное значение содержит три байта. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не используйте вместо strlen/mb_strlen.
  • Не стройте HTML maxLength слепо из DB metadata.
  • Длина UTF-8 может измеряться не как число видимых символов.

Когда выбрать другое. Валидация формы использует собственный бизнес-лимит; metadata полезна универсальному инспектору/экспортёру.

Связанные операции: odbc_field_precision(), odbc_field_scale(), odbc_field_type().

odbc_field_precisionИсторический псевдоним odbc_field_len(). Для NUMERIC значение читают как precision, для текста — как column size по драйверу.

PHP 4+; alias odbc_field_len; PHP 8.4 Odbc\Result · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_field_precision(Odbc\Result $statement, int $field): int|false

Исторический псевдоним odbc_field_len(). Для NUMERIC значение читают как precision, для текста — как column size по драйверу.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_field_precision(Odbc\Result $statement, int $field): int|false

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.
int $fieldНомер столбца с 1 либо его имя. В ODBC позиции полей начинаются с 1.

Возврат. int либо false; реализация — alias odbc_field_len().

Отказ и диагностика. false для неверного номера поля. Название precision не гарантирует numeric-тип.

Путь вызова
  1. позиция выбирает descriptor
  2. alias вызывает field_len implementation
  3. драйвер возвращает column size
  4. код трактует его по SQL-типу
Прочитать precision NUMERIC(8,2)Самостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, 'SELECT CAST(1234.56 AS NUMERIC(8,2)) AS amount');
echo "precision=", odbc_field_precision($result, 1), "\n";
odbc_close($connection);
Ожидаемый результат
precision=8

Precision 8 — общее число десятичных цифр, не число знаков после точки. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Сопоставить исторический alias с field_lenСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT CAST('abc' AS VARCHAR(20)) AS label");
$a = odbc_field_precision($result, 1);
$b = odbc_field_len($result, 1);
echo $a === $b ? "same=20\n" : "different\n";
odbc_close($connection);
Ожидаемый результат
same=20

В php-src odbc_field_precision — alias odbc_field_len; имя precision не делает отдельного вычисления. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Сначала проверьте field_type.
  • Не вычитайте scale без проверки смыслов драйвера.
  • Для текста это не фактическая длина значения.

Когда выбрать другое. Используйте odbc_field_len как каноническое имя alias; явная схема приложения лучше для бизнес-валидации.

Связанные операции: odbc_field_len(), odbc_field_scale(), odbc_field_type().

odbc_field_scaleВозвращает scale колонки — обычно число цифр дробной части для DECIMAL/NUMERIC.

PHP 4+; PHP 8.4 Odbc\Result · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_field_scale(Odbc\Result $statement, int $field): int|false

Возвращает scale колонки — обычно число цифр дробной части для DECIMAL/NUMERIC.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_field_scale(Odbc\Result $statement, int $field): int|false

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.
int $fieldНомер столбца с 1 либо его имя. В ODBC позиции полей начинаются с 1.

Возврат. int либо false для неверного поля.

Отказ и диагностика. false надо отличать строго от scale=0.

Путь вызова
  1. descriptor хранит decimal digits
  2. field_scale читает значение
  3. 0 сохраняется как валидный int
  4. форматтер выбирает нужное число знаков
Прочитать два знака дробной частиСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, 'SELECT CAST(12.34 AS NUMERIC(8,2)) AS amount');
echo "scale=", odbc_field_scale($result, 1), "\n";
odbc_close($connection);
Ожидаемый результат
scale=2

NUMERIC(8,2) разрешает две десятичные цифры справа от разделителя. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Сравнить scale целого и денежного поляСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, 'SELECT CAST(7 AS INTEGER) AS qty, CAST(7.50 AS NUMERIC(8,2)) AS price');
echo odbc_field_scale($result, 1), ':', odbc_field_scale($result, 2), "\n";
odbc_close($connection);
Ожидаемый результат
0:2

Ноль у INTEGER — нормальный scale, не ошибка. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Проверяйте === false, а не if (!$scale).
  • Metadata scale не округляет PHP-значение.
  • Деньги лучше хранить NUMERIC/целыми минимальными единицами по договору.

Когда выбрать другое. NumberFormatter/явный формат доменной модели отвечает за отображение, metadata только описывает SQL-колонку.

Связанные операции: odbc_field_precision(), odbc_field_type().

odbc_field_numНаходит 1-based позицию колонки по имени в конкретном result.

PHP 4+; PHP 8.4 Odbc\Result · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_field_num(Odbc\Result $statement, string $field): int|false

Находит 1-based позицию колонки по имени в конкретном result.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_field_num(Odbc\Result $statement, string $field): int|false

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.
string $fieldНомер столбца с 1 либо его имя. В ODBC позиции полей начинаются с 1.

Возврат. int позиции или false, если имя не найдено.

Отказ и диагностика. false означает отсутствие имени; регистр и правила сопоставления зависят от драйвера.

Путь вызова
  1. result имеет список имён
  2. field_num ищет имя
  3. возвращает позицию с 1
  4. код использует её в result/metadata API
Найти позицию колонки по имениСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT 1 AS id, 'Pen' AS name, 100 AS price");
echo "name-field=", odbc_field_num($result, 'name'), "\n";
odbc_close($connection);
Ожидаемый результат
name-field=2

Позиция ODBC начинается с 1. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Безопасно обнаружить отсутствующий столбец интеграцииСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, 'SELECT 1 AS id');
$position = odbc_field_num($result, 'external_code');
echo $position === false ? "column-missing\n" : "column={$position}\n";
odbc_close($connection);
Ожидаемый результат
column-missing

false — сигнал несовпадения ожидаемой схемы; не подменяйте его позицией 0, которой в ODBC field API нет. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не превращайте false в 0.
  • SQL alias делает ожидаемое имя явным.
  • Дубликаты имён неоднозначны.

Когда выбрать другое. fetch_array по явным aliases часто устраняет необходимость искать позиции вручную.

Связанные операции: odbc_field_name(), odbc_result(), odbc_num_fields().

odbc_autocommitЧитает или переключает автоматическую фиксацию. false начинает явную транзакцию, чтобы несколько SQL-команд стали одной единицей работы.

PHP 4+; PHP 8.3 enable nullable; PHP 8.4 Odbc\Connection · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_autocommit(Odbc\Connection $odbc, ?bool $enable = null): int|bool

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

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_autocommit(Odbc\Connection $odbc, ?bool $enable = null): int|bool

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
?bool $enable (по умолчанию NULL)true включает autocommit, false выключает; null читает текущее состояние.

Возврат. При enable=null возвращает ненулевое значение для on, 0 для off либо false при ошибке. При enable=true/false возвращает bool успеха.

Отказ и диагностика. false при чтении неоднозначен с состоянием off, поэтому различайте строго: getter может вернуть int 0 или false. После неудачного переключения прочитайте SQLSTATE.

Путь вызова
  1. прочитать исходный режим
  2. false переводит соединение в транзакцию
  3. SQL-команды накапливаются
  4. commit/rollback завершает работу, true возвращает autocommit
Прочитать и изменить режим транзакцииСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
echo "before=", odbc_autocommit($connection) ? 'on' : 'off', "\n";
odbc_autocommit($connection, false);
echo "inside=", odbc_autocommit($connection) ? 'on' : 'off', "\n";
odbc_rollback($connection);
odbc_autocommit($connection, true);
echo "after=", odbc_autocommit($connection) ? 'on' : 'off', "\n";
odbc_close($connection);
Ожидаемый результат
before=on
inside=off
after=on

null/отсутствующий enable читает состояние; false начинает явную транзакцию; после rollback режим возвращён для следующего кода. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Начать единицу работы перед созданием заказаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_autocommit_order');
uodbcExec($connection, 'CREATE TABLE phpman_autocommit_order (id INTEGER PRIMARY KEY, state VARCHAR(20))');
odbc_autocommit($connection, false);
try {
    uodbcExec($connection, "INSERT INTO phpman_autocommit_order VALUES (1, 'new')");
    uodbcExec($connection, "UPDATE phpman_autocommit_order SET state='paid' WHERE id=1");
    odbc_commit($connection);
    $row = uodbcExec($connection, 'SELECT state FROM phpman_autocommit_order WHERE id=1');
    echo odbc_result($row, 'state'), "\n";
} finally {
    if (!odbc_autocommit($connection)) { odbc_rollback($connection); }
    odbc_autocommit($connection, true);
    uodbcDrop($connection, 'phpman_autocommit_order');
    odbc_close($connection);
}
Ожидаемый результат
paid

Отключение autocommit объединяет INSERT и UPDATE. finally возвращает состояние соединения и удаляет только учебную таблицу. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не оставляйте off на persistent-соединении.
  • Внешний HTTP-вызов/sleep внутри транзакции удерживает блокировки.
  • Не все DDL/драйверы одинаково участвуют в транзакциях.

Когда выбрать другое. Для одиночной независимой записи autocommit проще; транзакция нужна при общем инварианте нескольких изменений.

Связанные операции: odbc_commit(), odbc_rollback(), odbc_close().

odbc_commitФиксирует все ожидающие изменения текущего ODBC-соединения. Практический смысл — сделать видимым целиком уже проверенный заказ, платёж или импорт.

PHP 4+; PHP 8.4 Odbc\Connection · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_commit(Odbc\Connection $odbc): bool

Фиксирует все ожидающие изменения текущего ODBC-соединения. Практический смысл — сделать видимым целиком уже проверенный заказ, платёж или импорт.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_commit(Odbc\Connection $odbc): bool

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.

Возврат. true при подтверждённой фиксации, false при отказе драйвера/СУБД.

Отказ и диагностика. false нельзя игнорировать: итог может быть не зафиксирован. Запишите SQLSTATE, выполните rollback, верните безопасную ошибку; повтор допустим только для классифицированного временного отказа и идемпотентной операции.

Путь вызова
  1. autocommit выключен
  2. несколько команд выполняют одну задачу
  3. код проверяет каждый шаг
  4. odbc_commit просит сервер зафиксировать транзакцию
Зафиксировать новую строку заказаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_commit_order');
uodbcExec($connection, 'CREATE TABLE phpman_commit_order (id INTEGER PRIMARY KEY, total INTEGER)');
odbc_autocommit($connection, false);
try {
    uodbcExec($connection, 'INSERT INTO phpman_commit_order VALUES (10, 2500)');
    echo odbc_commit($connection) ? "committed\n" : "commit-failed\n";
    $row = uodbcExec($connection, 'SELECT total FROM phpman_commit_order WHERE id=10');
    echo "total=", odbc_result($row, 'total'), "\n";
} finally {
    odbc_autocommit($connection, true);
    uodbcDrop($connection, 'phpman_commit_order');
    odbc_close($connection);
}
Ожидаемый результат
committed
total=2500

Возврат true фиксирует pending-изменения текущего соединения; контрольный SELECT показывает сохранённое состояние. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Согласованно сохранить заказ и событие журналаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_commit_event');
uodbcDrop($connection, 'phpman_commit_invoice');
uodbcExec($connection, 'CREATE TABLE phpman_commit_invoice (id INTEGER PRIMARY KEY)');
uodbcExec($connection, 'CREATE TABLE phpman_commit_event (invoice_id INTEGER, message VARCHAR(30))');
odbc_autocommit($connection, false);
try {
    uodbcExec($connection, 'INSERT INTO phpman_commit_invoice VALUES (7)');
    uodbcExec($connection, "INSERT INTO phpman_commit_event VALUES (7, 'created')");
    if (!odbc_commit($connection)) { throw new RuntimeException(odbc_errormsg($connection)); }
    $row = uodbcExec($connection, 'SELECT (SELECT COUNT(*) FROM phpman_commit_invoice) + (SELECT COUNT(*) FROM phpman_commit_event) AS total');
    echo "rows=", odbc_result($row, 'total'), "\n";
} finally {
    odbc_autocommit($connection, true);
    uodbcDrop($connection, 'phpman_commit_event');
    uodbcDrop($connection, 'phpman_commit_invoice');
    odbc_close($connection);
}
Ожидаемый результат
rows=2

Две таблицы меняются одной транзакцией; commit расположен только после успешного выполнения обоих шагов. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Commit не проверяет бизнес-инварианты за приложение.
  • Команды другого соединения в эту транзакцию не входят.
  • После commit всё равно верните autocommit в ожидаемый режим.

Когда выбрать другое. Одна SQL-команда в autocommit уже атомарна на поддерживающей СУБД; явная транзакция нужна для нескольких связанных команд.

Связанные операции: odbc_autocommit(), odbc_rollback(), odbc_error().

odbc_rollbackОтменяет ожидающие изменения текущей транзакции. Это управляемый выход, когда один из связанных шагов заказа/импорта не выполнился.

PHP 4+; PHP 8.4 Odbc\Connection · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_rollback(Odbc\Connection $odbc): bool

Отменяет ожидающие изменения текущей транзакции. Это управляемый выход, когда один из связанных шагов заказа/импорта не выполнился.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_rollback(Odbc\Connection $odbc): bool

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.

Возврат. true при успешном откате, false при отказе.

Отказ и диагностика. false означает, что состояние соединения нельзя считать восстановленным. Его изолируют/закрывают после завершения транзакции и передают ошибку выше.

Путь вызова
  1. autocommit выключен
  2. команды меняют данные внутри транзакции
  3. проверка/зависимость сообщает отказ
  4. odbc_rollback возвращает согласованное состояние
Отменить строку после неудачной проверкиСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_rollback_order');
uodbcExec($connection, 'CREATE TABLE phpman_rollback_order (id INTEGER PRIMARY KEY)');
odbc_autocommit($connection, false);
try {
    uodbcExec($connection, 'INSERT INTO phpman_rollback_order VALUES (1)');
    echo odbc_rollback($connection) ? "rolled-back\n" : "rollback-failed\n";
    $row = uodbcExec($connection, 'SELECT COUNT(*) AS total FROM phpman_rollback_order');
    echo "rows=", odbc_result($row, 'total'), "\n";
} finally {
    odbc_autocommit($connection, true);
    uodbcDrop($connection, 'phpman_rollback_order');
    odbc_close($connection);
}
Ожидаемый результат
rolled-back
rows=0

Проверка числа строк подтверждает, что INSERT не вышел за границу транзакции. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Вернуть остаток после отменённого списанияСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_rollback_stock');
uodbcExec($connection, 'CREATE TABLE phpman_rollback_stock (id INTEGER PRIMARY KEY, qty INTEGER)');
uodbcExec($connection, 'INSERT INTO phpman_rollback_stock VALUES (1, 5)');
odbc_autocommit($connection, false);
try {
    uodbcExec($connection, 'UPDATE phpman_rollback_stock SET qty=qty-2 WHERE id=1');
    odbc_rollback($connection);
    $row = uodbcExec($connection, 'SELECT qty FROM phpman_rollback_stock WHERE id=1');
    echo "qty=", odbc_result($row, 'qty'), "\n";
} finally {
    odbc_autocommit($connection, true);
    uodbcDrop($connection, 'phpman_rollback_stock');
    odbc_close($connection);
}
Ожидаемый результат
qty=5

Rollback возвращает состояние до начала транзакции, если СУБД и таблица поддерживают транзакции. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Rollback не отменяет уже выполненный commit.
  • Файлы, письма и HTTP-вызовы вне БД он не возвращает.
  • Поддержка DDL-транзакций различается у СУБД.

Когда выбрать другое. Savepoint через SQL позволяет откатить часть большой транзакции, но его синтаксис/поддержка относятся к конкретной СУБД.

Связанные операции: odbc_autocommit(), odbc_commit(), odbc_errormsg().

odbc_errorВозвращает SQLSTATE последней ODBC-ошибки: короткий машинно-читаемый код для классификации причины.

PHP 4+; PHP 8.0 nullable connection; PHP 8.4 Odbc\Connection · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_error(?Odbc\Connection $odbc = null): string

Возвращает SQLSTATE последней ODBC-ошибки: короткий машинно-читаемый код для классификации причины.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_error(?Odbc\Connection $odbc = null): string

ПараметрЧто передать
?Odbc\Connection $odbc (по умолчанию NULL)Объект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.

Возврат. Строка SQLSTATE либо пустая строка, если подходящей последней ошибки нет. Официальное описание говорит о six-digit state, но практические SQLSTATE обычно пятисимвольные; ориентируйтесь на фактический драйвер.

Отказ и диагностика. Пустая строка не означает, что любой предыдущий бизнес-шаг успешен; функция имеет смысл непосредственно после ODBC-отказа. Без connection читается последнее состояние любого соединения процесса.

Путь вызова
  1. ODBC-вызов возвращает false
  2. драйвер сохраняет diagnostic record
  3. odbc_error читает state немедленно
  4. код выбирает безопасную реакцию по классу ошибки
Получить SQLSTATE после несуществующей таблицыСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = @odbc_exec($connection, 'SELECT * FROM phpman_missing_table');
if ($result === false) {
    echo odbc_error($connection), "\n";
}
odbc_close($connection);
Ожидаемый результат
42P01

42P01 — PostgreSQL SQLSTATE undefined_table. Другой драйвер может вернуть другой конкретный код, но класс 42 относится к синтаксису/доступу к объектам. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Не принимать старое состояние за текущую ошибкуСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
echo odbc_error($connection) === '' ? "no-error\n" : "has-error\n";
$ok = uodbcExec($connection, 'SELECT 1 AS ok');
echo odbc_result($ok, 'ok'), "\n";
odbc_close($connection);
Ожидаемый результат
no-error
1

Диагностика meaningful сразу после failed ODBC-call; на свежем соединении строка пуста. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не показывайте только код пользователю без понятного сообщения.
  • Не сравнивайте всё сообщение драйвера; классифицируйте SQLSTATE.
  • Глобальный вызов без connection может взять ошибку другого соединения.

Когда выбрать другое. Исключение-обёртка приложения может сохранить SQLSTATE, безопасный operation id и исходное Throwable, не раскрывая секреты.

Связанные операции: odbc_errormsg(), odbc_exec(), odbc_execute().

odbc_errormsgВозвращает текст последней ODBC-ошибки для диагностики драйвера, сети или SQL.

PHP 4+; PHP 8.0 nullable connection; PHP 8.4 Odbc\Connection · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_errormsg(?Odbc\Connection $odbc = null): string

Возвращает текст последней ODBC-ошибки для диагностики драйвера, сети или SQL.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_errormsg(?Odbc\Connection $odbc = null): string

ПараметрЧто передать
?Odbc\Connection $odbc (по умолчанию NULL)Объект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.

Возврат. Строка сообщения либо пустая строка. Формулировка и язык зависят от Driver Manager, драйвера и СУБД.

Отказ и диагностика. Пустая строка возможна без последней ошибки; старое сообщение может стать нерелевантным после следующих вызовов. Снимайте state/message сразу в локальные переменные.

Путь вызова
  1. ODBC-вызов возвращает false
  2. драйвер создаёт diagnostic text
  3. код читает сообщение сразу
  4. закрытый лог связывает его с operation id
Записать понятную причину в закрытый журналСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = @odbc_exec($connection, 'SELECT * FROM phpman_missing_message_table');
if ($result === false) {
    $message = odbc_errormsg($connection);
    echo str_contains($message, 'phpman_missing_message_table') ? "message-has-object\n" : "message-received\n";
}
odbc_close($connection);
Ожидаемый результат
message-has-object

Сообщение полезно разработчику и может содержать имя объекта/SQL; его пишут в закрытый лог, а не отдают посетителю целиком. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Проверить отсутствие диагностического сообщенияСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
echo odbc_errormsg($connection) === '' ? "empty\n" : "unexpected\n";
odbc_close($connection);
Ожидаемый результат
empty

На новом соединении без failed-вызова сообщение пусто; это не самостоятельная проверка доступности базы. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Сообщение нестабильно для ветвления кода.
  • Оно может раскрыть SQL, пути, хост и схему.
  • Не логируйте пароль и полный набор пользовательских данных рядом с ним.

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

Связанные операции: odbc_error(), odbc_exec(), odbc_execute().

odbc_setoptionМеняет низкоуровневую ODBC-настройку конкретного соединения или statement. Это аварийный/интеграционный инструмент для известного драйвера, а не переносимая настройка по умолчанию.

PHP 4+; PHP 8.4 Odbc\Connection|Odbc\Result · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_setoption(Odbc\Connection|Odbc\Result $odbc, int $which, int $option, int $value): bool

Меняет низкоуровневую ODBC-настройку конкретного соединения или statement. Это аварийный/интеграционный инструмент для известного драйвера, а не переносимая настройка по умолчанию.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_setoption(Odbc\Connection|Odbc\Result $odbc, int $which, int $option, int $value): bool

ПараметрЧто передать
Odbc\Connection|Odbc\Result $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
int $which1 для настройки соединения, 2 для настройки результата — исторический низкоуровневый контракт odbc_setoption().
int $optionODBC-атрибут, например SQL_CURSOR_TYPE; допустимость определяется драйвером.
int $valueЦелое значение выбранного ODBC-атрибута.

Возврат. true, если драйвер принял настройку, иначе false.

Отказ и диагностика. false означает неподдерживаемый атрибут/значение или отказ драйвера. Некоторые параметры надо задать до connect/prepare и этой функцией уже не изменить.

Путь вызова
  1. документация драйвера задаёт option/value
  2. which выбирает connection или statement API
  3. Driver Manager передаёт настройку
  4. код проверяет поддержку и фактическое поведение
Низкоуровнево выключить и вернуть autocommitСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
if (!odbc_setoption($connection, 1, 102, 0)) {
    throw new RuntimeException(odbc_errormsg($connection));
}
echo odbc_autocommit($connection) ? "on\n" : "off\n";
odbc_rollback($connection);
odbc_setoption($connection, 1, 102, 1);
echo odbc_autocommit($connection) ? "on\n" : "off\n";
odbc_close($connection);
Ожидаемый результат
off
on

which=1 вызывает SQLSetConnectOption; option 102 — SQL_AUTOCOMMIT. Для обычного кода понятнее odbc_autocommit(). Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Ограничить время подготовленного отчётаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$statement = odbc_prepare($connection, 'SELECT CAST(? AS INTEGER) AS id');
if ($statement === false) { throw new RuntimeException(odbc_errormsg($connection)); }
echo odbc_setoption($statement, 2, 0, 30) ? "timeout-set\n" : "timeout-unsupported\n";
if (!odbc_execute($statement, [9])) { throw new RuntimeException(odbc_errormsg($connection)); }
$row = odbc_fetch_array($statement);
echo "id=", $row['id'], "\n";
odbc_close($connection);
Ожидаемый результат
timeout-set
id=9

which=2 вызывает SQLSetStmtOption; option 0 задаёт SQL_QUERY_TIMEOUT в секундах, если драйвер поддерживает его для уже созданного statement. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Числа option не самодокументируются; дайте именованный wrapper и ссылку на спецификацию.
  • Эффект различается по версиям драйвера.
  • Состояние persistent-соединения нужно вернуть.

Когда выбрать другое. Используйте специализированную PHP-функцию вроде odbc_autocommit() или параметр DSN/драйвера, если он существует и понятнее.

Связанные операции: odbc_autocommit(), odbc_prepare(), odbc_execute().

odbc_binmodeЗадаёт, как один result преобразует SQL-типы BINARY/VARBINARY/LONGVARBINARY: выводит напрямую, возвращает байты или превращает каждый байт в два hex-символа.

PHP 4+; PHP 8.4 Odbc\Result; default directive odbc.defaultbinmode · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_binmode(Odbc\Result $statement, int $mode): true

Задаёт, как один result преобразует SQL-типы BINARY/VARBINARY/LONGVARBINARY: выводит напрямую, возвращает байты или превращает каждый байт в два hex-символа.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_binmode(Odbc\Result $statement, int $mode): true

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.
int $modeРежим обработки двоичных данных: ODBC_BINMODE_PASSTHRU, ODBC_BINMODE_RETURN или ODBC_BINMODE_CONVERT.

Возврат. Всегда true при корректном вызове; реальный формат значения определяется mode, longreadlen и драйвером.

Отказ и диагностика. Сигнатура возвращает literal true; неверный объект/тип режима приводит к TypeError/ошибке. Успех установки не доказывает, что драйвер классифицировал колонку ожидаемым SQL-типом.

Путь вызова
  1. запрос возвращает бинарный столбец
  2. binmode задаётся до чтения
  3. для LONGVARBINARY учитывается longreadlen
  4. fetch/result получает выбранное представление
Получить байты как есть и как hexadecimal-текстСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
foreach ([ODBC_BINMODE_RETURN, ODBC_BINMODE_CONVERT] as $mode) {
    $result = uodbcExec($connection, "SELECT decode('0001ff', 'hex') AS payload");
    odbc_longreadlen($result, 100);
    odbc_binmode($result, $mode);
    $row = odbc_fetch_array($result);
    echo $mode === ODBC_BINMODE_RETURN ? 'raw=' : 'hex-text=';
    echo bin2hex((string) $row['payload']), "\n";
}
odbc_close($connection);
Ожидаемый результат
raw=0001ff
hex-text=303030316666

RETURN отдаёт три исходных байта; CONVERT отдаёт шесть ASCII-символов 0001ff, поэтому bin2hex этой строки показывает их коды. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Увидеть границу passthru при fetch_into/arrayСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT decode('4142', 'hex') AS payload");
odbc_longreadlen($result, 10);
odbc_binmode($result, ODBC_BINMODE_PASSTHRU);
$row = odbc_fetch_array($result);
echo "array-value-length=", strlen((string) $row['payload']), "\n";
odbc_close($connection);
Ожидаемый результат
array-value-length=0

Для fetch_into/fetch_array официальный контракт passthru означает пустую строку; при odbc_result() данные отправились бы прямо в output, что опасно для JSON/HTML-ответа. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • PASSTHRU пишет байты в вывод и может повредить HTML/JSON.
  • CONVERT удваивает размер и возвращает текст hex, а не исходные байты.
  • Для LONGVARBINARY отдельно задайте longreadlen.

Когда выбрать другое. Для файлов часто удобнее отдельное объектное/файловое хранилище; нативный драйвер СУБД может дать предсказуемее LOB-stream API.

Связанные операции: odbc_longreadlen(), odbc_fetch_array(), odbc_result().

odbc_longreadlenЗадаёт для одного result максимальное число байт LONG/LONGVARCHAR/LONGVARBINARY, возвращаемых в PHP.

PHP 4+; PHP 8.4 Odbc\Result; directive odbc.defaultlrl · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_longreadlen(Odbc\Result $statement, int $length): true

Задаёт для одного result максимальное число байт LONG/LONGVARCHAR/LONGVARBINARY, возвращаемых в PHP.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_longreadlen(Odbc\Result $statement, int $length): true

ПараметрЧто передать
Odbc\Result $statementОбъект Odbc\Result: результат запроса или подготовленная команда. После odbc_free_result() его повторно не читают.
int $lengthПредельное число байт LONG-значения, читаемое для этого результата; 0 включает потоковый passthru-режим.

Возврат. Всегда true при корректном вызове. length=0 включает passthru при odbc_result(); положительное значение ограничивает возвращаемые байты.

Отказ и диагностика. Функция сообщает literal true; слишком малый предел проявляется усечёнными данными, а не false. Проверяйте длину/целостность на уровне приложения.

Путь вызова
  1. запрос создаёт result
  2. до fetch задаётся byte limit
  3. драйвер читает LONG-значение
  4. PHP получает не больше limit либо passthru-вывод
Ограничить чтение длинного текста четырьмя байтамиСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT CAST(repeat('A', 10) AS text) AS body");
odbc_longreadlen($result, 4);
$row = odbc_fetch_array($result);
echo strlen($row['body']), ':', $row['body'], "\n";
odbc_close($connection);
Ожидаемый результат
4:AAAA

Предел измеряется байтами. Для UTF-8 он может оборвать последовательность посередине, поэтому размер выбирают по договору данных, а не по числу букв. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Прочитать весь известный учебный текстСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = uodbcExec($connection, "SELECT CAST(repeat('B', 10) AS text) AS body");
odbc_longreadlen($result, 20);
$row = odbc_fetch_array($result);
echo strlen($row['body']), ':', $row['body'], "\n";
odbc_close($connection);
Ожидаемый результат
10:BBBBBBBBBB

Лимит 20 больше результата, поэтому пришли все десять байт. Для реального неизвестного размера это всё равно буферная граница, а не потоковая гарантия. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Длина в байтах, не Unicode-символах.
  • 0 с odbc_result() отправляет данные прямо в output.
  • Большой лимит может увеличить память каждого запроса.

Когда выбрать другое. Потоковый LOB API нативного драйвера подходит большим файлам лучше; для обычного VARCHAR эта настройка обычно не нужна.

Связанные операции: odbc_binmode(), odbc_result(), odbc_fetch_array().

odbc_tablesВозвращает catalog-описание таблиц, представлений и других поддерживаемых объектов. Полезна мастеру настройки и инспектору схемы.

PHP 4+; PHP 8.4 Odbc\Connection/Odbc\Result и nullable filters · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_tables(Odbc\Connection $odbc, ?string $catalog = null, ?string $schema = null, ?string $table = null, ?string $types = null): Odbc\Result|false

Возвращает catalog-описание таблиц, представлений и других поддерживаемых объектов. Полезна мастеру настройки и инспектору схемы.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_tables(Odbc\Connection $odbc, ?string $catalog = null, ?string $schema = null, ?string $table = null, ?string $types = null): Odbc\Result|false

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
?string $catalog (по умолчанию NULL)Каталог источника данных либо null. Значение и поддержка зависят от СУБД/драйвера.
?string $schema (по умолчанию NULL)Схема. Для PostgreSQL в примерах используется public; пустая строка и null имеют драйверно-зависимый смысл.
?string $table (по умолчанию NULL)Имя или шаблон таблицы по правилам соответствующей ODBC metadata-функции.
?string $types (по умолчанию NULL)Список типов таблиц для odbc_tables(), например TABLE или VIEW, в формате драйвера.

Возврат. Odbc\Result с metadata-строками либо false.

Отказ и диагностика. false при неподдерживаемом/ошибочном catalog call. Пустой result означает отсутствие совпадений, а не обязательно ошибку.

Путь вызова
  1. передать catalog/schema/name/type filters
  2. драйвер вызывает SQLTables
  3. result содержит TABLE_CAT/SCHEM/NAME/TYPE
  4. код нормализует ключи и проверяет нужный объект
Найти таблицу интеграции через ODBC catalogСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_tables_product');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_tables_product (id INTEGER PRIMARY KEY)');
    $result = odbc_tables($connection, null, 'public', 'phpman_tables_product', 'TABLE');
    if ($result === false) { throw new RuntimeException(odbc_errormsg($connection)); }
    $found = false;
    while ($row = odbc_fetch_array($result)) {
        $row = array_change_key_case($row, CASE_LOWER);
        $found = $found || ($row['table_name'] ?? '') === 'phpman_tables_product';
    }
    echo $found ? "table-found\n" : "table-missing\n";
} finally {
    uodbcDrop($connection, 'phpman_tables_product');
    odbc_close($connection);
}
Ожидаемый результат
table-found

Catalog API переносимее запроса к pg_catalog/information_schema, но шаблоны и регистр всё равно зависят от драйвера. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Отличить VIEW от TABLEСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
@odbc_exec($connection, 'DROP VIEW IF EXISTS phpman_tables_view');
try {
    uodbcExec($connection, 'CREATE VIEW phpman_tables_view AS SELECT 1 AS id');
    $result = odbc_tables($connection, null, 'public', 'phpman_tables_view', 'VIEW');
    $row = $result === false ? false : odbc_fetch_array($result);
    $row = is_array($row) ? array_change_key_case($row, CASE_LOWER) : [];
    echo strtoupper((string) ($row['table_type'] ?? 'missing')), "\n";
} finally {
    @odbc_exec($connection, 'DROP VIEW IF EXISTS phpman_tables_view');
    odbc_close($connection);
}
Ожидаемый результат
VIEW

Тип объекта нельзя выводить только из имени; metadata возвращает TABLE_TYPE. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • null, пустая строка и % могут иметь разный смысл у драйвера.
  • Регистр шаблона важен.
  • Не показывайте полную схему неавторизованному пользователю.

Когда выбрать другое. information_schema даёт SQL-запросы, но детали всё равно зависят от СУБД; миграции лучше знают ожидаемую схему заранее.

Связанные операции: odbc_columns(), odbc_primarykeys(), odbc_statistics().

odbc_columnsПеречисляет колонки таблиц и их ODBC metadata: имя, тип, размер, nullable, ordinal position и другие поля драйвера.

PHP 4+; PHP 8.4 Odbc\Connection/Odbc\Result и nullable filters · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_columns(Odbc\Connection $odbc, ?string $catalog = null, ?string $schema = null, ?string $table = null, ?string $column = null): Odbc\Result|false

Перечисляет колонки таблиц и их ODBC metadata: имя, тип, размер, nullable, ordinal position и другие поля драйвера.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_columns(Odbc\Connection $odbc, ?string $catalog = null, ?string $schema = null, ?string $table = null, ?string $column = null): Odbc\Result|false

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
?string $catalog (по умолчанию NULL)Каталог источника данных либо null. Значение и поддержка зависят от СУБД/драйвера.
?string $schema (по умолчанию NULL)Схема. Для PostgreSQL в примерах используется public; пустая строка и null имеют драйверно-зависимый смысл.
?string $table (по умолчанию NULL)Имя или шаблон таблицы по правилам соответствующей ODBC metadata-функции.
?string $column (по умолчанию NULL)Имя или шаблон столбца по правилам metadata-функции.

Возврат. Odbc\Result либо false.

Отказ и диагностика. false при отказе catalog API; пустой набор при отсутствии совпадений. Набор полей и vendor-дополнения могут различаться.

Путь вызова
  1. фильтры выбирают таблицу/колонку
  2. драйвер вызывает SQLColumns
  3. каждая metadata-строка описывает одну колонку
  4. приложение сравнивает фактическую схему с ожидаемой
Получить список колонок таблицыСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_columns_product');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_columns_product (id INTEGER PRIMARY KEY, name VARCHAR(40), price NUMERIC(8,2))');
    $result = odbc_columns($connection, null, 'public', 'phpman_columns_product', '%');
    $names = [];
    while ($row = odbc_fetch_array($result)) {
        $row = array_change_key_case($row, CASE_LOWER);
        $names[] = $row['column_name'];
    }
    echo implode(',', $names), "\n";
} finally {
    uodbcDrop($connection, 'phpman_columns_product');
    odbc_close($connection);
}
Ожидаемый результат
id,name,price

Порядок следует ORDINAL_POSITION драйвера; мастер импорта может сопоставить входные заголовки. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Проверить тип и nullable поля APIСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_columns_contract');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_columns_contract (external_id VARCHAR(30) NOT NULL, note VARCHAR(100))');
    $result = odbc_columns($connection, null, 'public', 'phpman_columns_contract', 'external_id');
    $row = odbc_fetch_array($result);
    $row = array_change_key_case($row, CASE_LOWER);
    echo strtolower($row['type_name']), ':nullable=', $row['nullable'], "\n";
} finally {
    uodbcDrop($connection, 'phpman_columns_contract');
    odbc_close($connection);
}
Ожидаемый результат
varchar:nullable=0

NOT NULL отражается nullable=0; это описание БД, но входные данные всё равно проверяет приложение до запроса. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не создавайте пользовательскую форму автоматически без собственного allowlist/подписей.
  • Nullable БД не означает optional в бизнес-правилах.
  • Ключи result могут иметь другой регистр — нормализуйте.

Когда выбрать другое. Миграционная схема — источник ожидаемого контракта; odbc_columns полезна для проверки внешней/наследуемой базы.

Связанные операции: odbc_tables(), odbc_field_type(), odbc_primarykeys().

odbc_gettypeinfoВозвращает сведения о SQL-типах, которые сообщает источник данных: нативное имя, размер, литералы, nullable/searchable и прочие возможности.

PHP 4+; PHP 8.4 Odbc\Connection/Odbc\Result · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_gettypeinfo(Odbc\Connection $odbc, int $data_type = 0): Odbc\Result|false

Возвращает сведения о SQL-типах, которые сообщает источник данных: нативное имя, размер, литералы, nullable/searchable и прочие возможности.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_gettypeinfo(Odbc\Connection $odbc, int $data_type = 0): Odbc\Result|false

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
int $data_type (по умолчанию 0)SQL_* константа типа; 0 просит сведения обо всех типах.

Возврат. Odbc\Result либо false. data_type=0 просит все типы.

Отказ и диагностика. false при неподдерживаемом catalog call. Даже успешная строка не гарантирует одинаковый SQL-синтаксис у двух СУБД.

Путь вызова
  1. выбрать SQL_* тип или 0
  2. драйвер вызывает SQLGetTypeInfo
  3. каждая строка описывает вариант типа
  4. генератор/диагностика выбирает совместимый вариант
Проверить поддержку ODBC INTEGERСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = odbc_gettypeinfo($connection, SQL_INTEGER);
if ($result === false) { throw new RuntimeException(odbc_errormsg($connection)); }
$row = odbc_fetch_array($result);
$row = array_change_key_case($row, CASE_LOWER);
echo "type=", strtolower($row['type_name']), " data=", $row['data_type'], "\n";
odbc_close($connection);
Ожидаемый результат
type=int4 data=4

SQL_INTEGER имеет код 4; psqlODBC показывает нативное имя int4. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Узнать максимальный размер VARCHAR драйвераСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = odbc_gettypeinfo($connection, SQL_VARCHAR);
$row = $result === false ? false : odbc_fetch_array($result);
$row = is_array($row) ? array_change_key_case($row, CASE_LOWER) : [];
echo "type=", strtolower($row['type_name'] ?? 'missing'), "\n";
echo "data=", $row['data_type'] ?? 'missing', "\n";
echo "precision=", $row['precision'] ?? 'missing', "\n";
odbc_close($connection);
Ожидаемый результат
type=varchar
data=12
precision=255

Универсальный генератор схемы может проверить возможность типа, но реальный лимит и синтаксис CREATE TABLE остаются драйверно-зависимыми. psqlODBC возвращает ODBC2-совместимое имя поля PRECISION вместо COLUMN_SIZE — поэтому потребитель сначала изучает фактические ключи metadata своего драйвера. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не сравнивайте только TYPE_NAME между драйверами.
  • COLUMN_SIZE имеет смысл в контексте типа.
  • Не превращайте универсальный тип в обещание полной переносимости SQL.

Когда выбрать другое. Для одного известного backend используйте его официальную типовую систему/миграции; metadata нужна адаптеру к неизвестным источникам.

Связанные операции: odbc_field_type(), odbc_columns().

odbc_primarykeysВозвращает колонки первичного ключа таблицы и их порядок.

PHP 4+; PHP 8.4 Odbc\Connection/Odbc\Result; catalog nullable · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_primarykeys(Odbc\Connection $odbc, ?string $catalog, string $schema, string $table): Odbc\Result|false

Возвращает колонки первичного ключа таблицы и их порядок.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_primarykeys(Odbc\Connection $odbc, ?string $catalog, string $schema, string $table): Odbc\Result|false

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
?string $catalogКаталог источника данных либо null. Значение и поддержка зависят от СУБД/драйвера.
string $schemaСхема. Для PostgreSQL в примерах используется public; пустая строка и null имеют драйверно-зависимый смысл.
string $tableИмя или шаблон таблицы по правилам соответствующей ODBC metadata-функции.

Возврат. Odbc\Result либо false.

Отказ и диагностика. false при отказе catalog API; пустой result возможен у таблицы без PK или недостаточной metadata-поддержке.

Путь вызова
  1. указать точные schema/table
  2. драйвер вызывает SQLPrimaryKeys
  3. каждая строка даёт COLUMN_NAME/KEY_SEQ/PK_NAME
  4. код сортирует составной ключ по KEY_SEQ
Найти первичный ключ товараСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_pk_product');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_pk_product (id INTEGER PRIMARY KEY, name VARCHAR(40))');
    $result = odbc_primarykeys($connection, null, 'public', 'phpman_pk_product');
    $row = odbc_fetch_array($result);
    $row = array_change_key_case($row, CASE_LOWER);
    echo $row['column_name'], ':seq=', $row['key_seq'], "\n";
} finally {
    uodbcDrop($connection, 'phpman_pk_product');
    odbc_close($connection);
}
Ожидаемый результат
id:seq=1

COLUMN_NAME и KEY_SEQ дают состав ключа; имя ограничения тоже доступно в PK_NAME. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Восстановить порядок составного ключаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_pk_line');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_pk_line (order_id INTEGER, line_no INTEGER, PRIMARY KEY (order_id, line_no))');
    $result = odbc_primarykeys($connection, null, 'public', 'phpman_pk_line');
    $columns = [];
    while ($row = odbc_fetch_array($result)) {
        $row = array_change_key_case($row, CASE_LOWER);
        $columns[(int) $row['key_seq']] = $row['column_name'];
    }
    ksort($columns);
    echo implode(',', $columns), "\n";
} finally {
    uodbcDrop($connection, 'phpman_pk_line');
    odbc_close($connection);
}
Ожидаемый результат
order_id,line_no

Составной ключ — несколько metadata-строк; KEY_SEQ нельзя терять при генерации mapping. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не предполагавайте один столбец.
  • Порядок составного ключа важен.
  • Unique index не всегда является primary key.

Когда выбрать другое. Ожидаемый PK хранит миграция; introspection нужна внешней базе/генератору схемы.

Связанные операции: odbc_foreignkeys(), odbc_statistics(), odbc_columns().

odbc_foreignkeysОписывает внешние ключи между PK- и FK-таблицами: пары колонок, порядок, правила update/delete и имена ограничений.

PHP 4+; PHP 8.4 Odbc\Connection/Odbc\Result и nullable pk_catalog · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_foreignkeys(Odbc\Connection $odbc, ?string $pk_catalog, string $pk_schema, string $pk_table, string $fk_catalog, string $fk_schema, string $fk_table): Odbc\Result|false

Описывает внешние ключи между PK- и FK-таблицами: пары колонок, порядок, правила update/delete и имена ограничений.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_foreignkeys(Odbc\Connection $odbc, ?string $pk_catalog, string $pk_schema, string $pk_table, string $fk_catalog, string $fk_schema, string $fk_table): Odbc\Result|false

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
?string $pk_catalogКаталог таблицы с первичным ключом либо null.
string $pk_schemaСхема таблицы с первичным ключом.
string $pk_tableТаблица, на которую ссылается внешний ключ.
string $fk_catalogКаталог таблицы с внешним ключом либо пустая строка согласно текущей сигнатуре.
string $fk_schemaСхема таблицы с внешним ключом.
string $fk_tableТаблица, содержащая внешний ключ.

Возврат. Odbc\Result либо false.

Отказ и диагностика. false при отказе; пустой набор при отсутствии/невидимости связи. Catalog-аргументы несимметричны в текущей сигнатуре — следуйте ей буквально.

Путь вызова
  1. указать PK и FK стороны
  2. драйвер вызывает SQLForeignKeys
  3. строки связывают PKCOLUMN_NAME/FKCOLUMN_NAME
  4. код группирует составную связь и переводит rule codes
Найти связь строки заказа с заказомСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_fk_line');
uodbcDrop($connection, 'phpman_fk_order');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_fk_order (id INTEGER PRIMARY KEY)');
    uodbcExec($connection, 'CREATE TABLE phpman_fk_line (id INTEGER PRIMARY KEY, order_id INTEGER REFERENCES phpman_fk_order(id))');
    $result = odbc_foreignkeys($connection, null, 'public', 'phpman_fk_order', '', 'public', 'phpman_fk_line');
    $row = odbc_fetch_array($result);
    $row = array_change_key_case($row, CASE_LOWER);
    echo $row['fkcolumn_name'], '->', $row['pkcolumn_name'], "\n";
} finally {
    uodbcDrop($connection, 'phpman_fk_line');
    uodbcDrop($connection, 'phpman_fk_order');
    odbc_close($connection);
}
Ожидаемый результат
order_id->id

Metadata показывает направление FK→PK, а не загружает связанные данные. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Прочитать правила каскада связиСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_fk_child');
uodbcDrop($connection, 'phpman_fk_parent');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_fk_parent (id INTEGER PRIMARY KEY)');
    uodbcExec($connection, 'CREATE TABLE phpman_fk_child (id INTEGER PRIMARY KEY, parent_id INTEGER REFERENCES phpman_fk_parent(id) ON DELETE CASCADE)');
    $result = odbc_foreignkeys($connection, null, 'public', 'phpman_fk_parent', '', 'public', 'phpman_fk_child');
    $row = array_change_key_case(odbc_fetch_array($result), CASE_LOWER);
    echo "delete-rule=", $row['delete_rule'], "\n";
} finally {
    uodbcDrop($connection, 'phpman_fk_child');
    uodbcDrop($connection, 'phpman_fk_parent');
    odbc_close($connection);
}
Ожидаемый результат
delete-rule=0

ODBC SQL_CASCADE имеет код 0. В UI лучше переводить числовой код через явную карту, не показывать как самодостаточный смысл. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не путайте направление PK/FK.
  • Составная связь имеет несколько строк и KEY_SEQ.
  • Rule codes требуют карты ODBC.

Когда выбрать другое. information_schema/referential_constraints даёт SQL-представление конкретной СУБД; migrations — ожидаемый контракт.

Связанные операции: odbc_primarykeys(), odbc_columns().

odbc_proceduresПеречисляет процедуры/функции, видимые через ODBC catalog, с типом и описанием.

PHP 4+; PHP 8.4 Odbc\Connection/Odbc\Result и nullable filters · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_procedures(Odbc\Connection $odbc, ?string $catalog = null, ?string $schema = null, ?string $procedure = null): Odbc\Result|false

Перечисляет процедуры/функции, видимые через ODBC catalog, с типом и описанием.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_procedures(Odbc\Connection $odbc, ?string $catalog = null, ?string $schema = null, ?string $procedure = null): Odbc\Result|false

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
?string $catalog (по умолчанию NULL)Каталог источника данных либо null. Значение и поддержка зависят от СУБД/драйвера.
?string $schema (по умолчанию NULL)Схема. Для PostgreSQL в примерах используется public; пустая строка и null имеют драйверно-зависимый смысл.
?string $procedure (по умолчанию NULL)Имя или шаблон процедуры/функции; видимость зависит от каталога драйвера.

Возврат. Odbc\Result либо false.

Отказ и диагностика. false — отказ catalog call; пустой result — нет совпадений. Определение function/procedure различается по СУБД.

Путь вызова
  1. задать catalog/schema/name pattern
  2. драйвер вызывает SQLProcedures
  3. каждая строка описывает callable
  4. инструмент показывает только разрешённые/поддерживаемые элементы
Найти учебную функцию в catalog процедурСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
@odbc_exec($connection, 'DROP FUNCTION IF EXISTS phpman_proc_add(integer)');
try {
    uodbcExec($connection, 'CREATE FUNCTION phpman_proc_add(integer) RETURNS integer LANGUAGE sql IMMUTABLE AS $$ SELECT $1 + 1 $$');
    $result = odbc_procedures($connection, null, 'public', 'phpman_proc_add');
    $found = false;
    while ($row = odbc_fetch_array($result)) {
        $row = array_change_key_case($row, CASE_LOWER);
        $found = $found || str_contains((string) ($row['procedure_name'] ?? ''), 'phpman_proc_add');
    }
    echo $found ? "procedure-found\n" : "procedure-missing\n";
} finally {
    @odbc_exec($connection, 'DROP FUNCTION IF EXISTS phpman_proc_add(integer)');
    odbc_close($connection);
}
Ожидаемый результат
procedure-found

ODBC называет catalog entry procedure даже там, где PostgreSQL различает function/procedure. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Получить пустой набор для отсутствующего имениСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
$result = odbc_procedures($connection, null, 'public', 'phpman_proc_does_not_exist');
$count = 0;
while ($result !== false && odbc_fetch_array($result)) { $count++; }
echo "matches={$count}\n";
odbc_close($connection);
Ожидаемый результат
matches=0

Пустой catalog result — нормальный исход поиска, не false-ошибка. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Наличие в каталоге не даёт EXECUTE privilege.
  • Overload-версии могут иметь одинаковое имя.
  • Не генерируйте публичный RPC автоматически из catalog.

Когда выбрать другое. Явный adapter к известным процедурам безопаснее; нативный драйвер лучше поддерживает OUT/INOUT параметры.

Связанные операции: odbc_procedurecolumns(), odbc_execute().

odbc_procedurecolumnsВозвращает metadata параметров/результатов процедуры или функции: имя, направление, тип, размер, nullable и ordinal.

PHP 4+; PHP 8.4 Odbc\Connection/Odbc\Result и nullable filters · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_procedurecolumns(Odbc\Connection $odbc, ?string $catalog = null, ?string $schema = null, ?string $procedure = null, ?string $column = null): Odbc\Result|false

Возвращает metadata параметров/результатов процедуры или функции: имя, направление, тип, размер, nullable и ordinal.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_procedurecolumns(Odbc\Connection $odbc, ?string $catalog = null, ?string $schema = null, ?string $procedure = null, ?string $column = null): Odbc\Result|false

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
?string $catalog (по умолчанию NULL)Каталог источника данных либо null. Значение и поддержка зависят от СУБД/драйвера.
?string $schema (по умолчанию NULL)Схема. Для PostgreSQL в примерах используется public; пустая строка и null имеют драйверно-зависимый смысл.
?string $procedure (по умолчанию NULL)Имя или шаблон процедуры/функции; видимость зависит от каталога драйвера.
?string $column (по умолчанию NULL)Имя или шаблон столбца по правилам metadata-функции.

Возврат. Odbc\Result либо false.

Отказ и диагностика. false при отказе; пустой набор может означать неизвестный callable либо неполную поддержку SQLProcedureColumns — сравните с odbc_procedures и известным тестовым объектом.

Путь вызова
  1. выбрать callable
  2. драйвер вызывает SQLProcedureColumns
  3. несколько строк описывают return/input/output
  4. adapter строит явный контракт
Проверить, раскрывает ли драйвер параметры функцииСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
@odbc_exec($connection, 'DROP FUNCTION IF EXISTS phpman_proc_param(integer)');
try {
    uodbcExec($connection, 'CREATE FUNCTION phpman_proc_param(value integer) RETURNS integer LANGUAGE sql IMMUTABLE AS $$ SELECT value * 2 $$');
    $result = odbc_procedurecolumns($connection, null, 'public', 'phpman_proc_param', '%');
    $count = 0;
    while (odbc_fetch_array($result)) { $count++; }
    echo "parameter-rows={$count}\n";
    echo $count > 0 ? "source=odbc-catalog\n" : "source=explicit-contract\n";
} finally {
    @odbc_exec($connection, 'DROP FUNCTION IF EXISTS phpman_proc_param(integer)');
    odbc_close($connection);
}
Ожидаемый результат
parameter-rows=0
source=explicit-contract

psqlODBC 18.00 видит созданную функцию через odbc_procedures(), но не выдаёт строки SQLProcedureColumns. Пустой result — проверенная capability-граница, поэтому adapter хранит явный контракт параметров либо читает нативный каталог PostgreSQL. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Сравнить видимость callable и его параметровСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
@odbc_exec($connection, 'DROP FUNCTION IF EXISTS phpman_proc_pair(integer, integer)');
try {
    uodbcExec($connection, 'CREATE FUNCTION phpman_proc_pair(left_value integer, right_value integer) RETURNS integer LANGUAGE sql IMMUTABLE AS $$ SELECT left_value + right_value $$');
    $procedures = odbc_procedures($connection, null, 'public', 'phpman_proc_pair');
    $procedureFound = false;
    while ($procedures !== false && odbc_fetch_array($procedures)) { $procedureFound = true; }
    $columns = odbc_procedurecolumns($connection, null, 'public', 'phpman_proc_pair', '%');
    $count = 0;
    while ($columns !== false && odbc_fetch_array($columns)) { $count++; }
    echo "procedure=", $procedureFound ? "yes\n" : "no\n";
    echo "parameter-rows={$count}\n";
} finally {
    @odbc_exec($connection, 'DROP FUNCTION IF EXISTS phpman_proc_pair(integer, integer)');
    odbc_close($connection);
}
Ожидаемый результат
procedure=yes
parameter-rows=0

Callable присутствует в SQLProcedures, однако SQLProcedureColumns остаётся пустым. Такое сравнение отличает «объекта нет» от «драйвер не раскрывает параметры»; при поддержке код дополнительно читает COLUMN_TYPE и ORDINAL_POSITION, а не только count. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Пустой result не доказывает отсутствие параметров.
  • COUNT строк не равен числу только входных параметров.
  • OUT/INOUT выполнение ext/odbc ограничено.
  • Overload требует учёта типов/специфичного имени.

Когда выбрать другое. Явно описанный client adapter и нативный catalog/драйвер надёжнее для процедурных API.

Связанные операции: odbc_procedures(), odbc_prepare(), odbc_execute().

odbc_specialcolumnsЗапрашивает special columns: лучший идентификатор строки (SQL_BEST_ROWID) либо автоматически меняемую row-version (SQL_ROWVER).

PHP 4+; PHP 8.4 Odbc\Connection/Odbc\Result и nullable catalog · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_specialcolumns(Odbc\Connection $odbc, int $type, ?string $catalog, string $schema, string $table, int $scope, int $nullable): Odbc\Result|false

Запрашивает special columns: лучший идентификатор строки (SQL_BEST_ROWID) либо автоматически меняемую row-version (SQL_ROWVER).

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_specialcolumns(Odbc\Connection $odbc, int $type, ?string $catalog, string $schema, string $table, int $scope, int $nullable): Odbc\Result|false

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
int $typeSQL_BEST_ROWID или SQL_ROWVER для odbc_specialcolumns().
?string $catalogКаталог источника данных либо null. Значение и поддержка зависят от СУБД/драйвера.
string $schemaСхема. Для PostgreSQL в примерах используется public; пустая строка и null имеют драйверно-зависимый смысл.
string $tableИмя или шаблон таблицы по правилам соответствующей ODBC metadata-функции.
int $scopeSQL_SCOPE_CURROW, SQL_SCOPE_TRANSACTION или SQL_SCOPE_SESSION.
int $nullableSQL_NO_NULLS исключает nullable-кандидатов, SQL_NULLABLE разрешает их.

Возврат. Odbc\Result либо false.

Отказ и диагностика. false при отказе; пустой набор означает, что драйвер не сообщает подходящую special column.

Путь вызова
  1. выбрать type/scope/nullability
  2. драйвер вызывает SQLSpecialColumns
  3. строки описывают кандидатные колонки
  4. optimistic update использует только подтверждённый контракт
Запросить лучшую колонку идентификации строкиСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_special_product');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_special_product (id INTEGER PRIMARY KEY, name VARCHAR(20))');
    $result = odbc_specialcolumns($connection, SQL_BEST_ROWID, null, 'public', 'phpman_special_product', SQL_SCOPE_SESSION, SQL_NO_NULLS);
    if ($result === false) { throw new RuntimeException(odbc_errormsg($connection)); }
    $found = false;
    while ($row = odbc_fetch_array($result)) {
        $row = array_change_key_case($row, CASE_LOWER);
        $found = $found || ($row['column_name'] ?? '') === 'id';
    }
    echo $found ? "best=id\n" : "best-not-reported\n";
} finally {
    uodbcDrop($connection, 'phpman_special_product');
    odbc_close($connection);
}
Ожидаемый результат
best=id

SQL_BEST_ROWID просит ODBC определить набор колонок, уникально идентифицирующий строку в заданном scope. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Проверить наличие row-version колонокСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_special_version');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_special_version (id INTEGER PRIMARY KEY, changed_at TIMESTAMP)');
    $result = odbc_specialcolumns($connection, SQL_ROWVER, null, 'public', 'phpman_special_version', SQL_SCOPE_SESSION, SQL_NULLABLE);
    $row = $result === false ? false : odbc_fetch_array($result);
    $row = is_array($row) ? array_change_key_case($row, CASE_LOWER) : [];
    echo "rowver=", $row['column_name'] ?? 'none', "\n";
    echo "pseudo=", $row['pseudo_column'] ?? 'none', "\n";
} finally {
    uodbcDrop($connection, 'phpman_special_version');
    odbc_close($connection);
}
Ожидаемый результат
rowver=xmin
pseudo=2

Обычный changed_at не становится rowversion. psqlODBC сообщает системную pseudo-column xmin (PSEUDO_COLUMN=2). Это backend-specific идентификатор версии строки: его используют только после изучения семантики PostgreSQL и не выдают за переносимый timestamp. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • BEST_ROWID не обязательно равен объявленному PK.
  • Обычная дата не является rowversion.
  • xmin — системная PostgreSQL pseudo-column, а не универсальный счётчик приложения.
  • Scope/nullability меняют список.

Когда выбрать другое. Явный PK и version counter/timestamp с проверяемым UPDATE дают понятнее optimistic locking в приложении.

Связанные операции: odbc_primarykeys(), odbc_columns().

odbc_statisticsВозвращает индексную/statistics metadata таблицы: уникальность, имя индекса, колонки, порядок и оценочные показатели.

PHP 4+; PHP 8.4 Odbc\Connection/Odbc\Result и nullable catalog · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_statistics(Odbc\Connection $odbc, ?string $catalog, string $schema, string $table, int $unique, int $accuracy): Odbc\Result|false

Возвращает индексную/statistics metadata таблицы: уникальность, имя индекса, колонки, порядок и оценочные показатели.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_statistics(Odbc\Connection $odbc, ?string $catalog, string $schema, string $table, int $unique, int $accuracy): Odbc\Result|false

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
?string $catalogКаталог источника данных либо null. Значение и поддержка зависят от СУБД/драйвера.
string $schemaСхема. Для PostgreSQL в примерах используется public; пустая строка и null имеют драйверно-зависимый смысл.
string $tableИмя или шаблон таблицы по правилам соответствующей ODBC metadata-функции.
int $uniqueSQL_INDEX_UNIQUE возвращает только уникальные индексы, SQL_INDEX_ALL — все.
int $accuracySQL_ENSURE просит актуальную статистику, SQL_QUICK допускает приблизительную.

Возврат. Odbc\Result либо false.

Отказ и диагностика. false при отказе; пустой результат при отсутствии доступной metadata.

Путь вызова
  1. указать table и unique/accuracy
  2. драйвер вызывает SQLStatistics
  3. строки описывают индекс/колонки
  4. инструмент группирует их по INDEX_NAME/ORDINAL_POSITION
Найти индекс первичного ключаСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_stats_product');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_stats_product (id INTEGER PRIMARY KEY, name VARCHAR(20))');
    $result = odbc_statistics($connection, null, 'public', 'phpman_stats_product', SQL_INDEX_ALL, SQL_ENSURE);
    $found = false;
    while ($row = odbc_fetch_array($result)) {
        $row = array_change_key_case($row, CASE_LOWER);
        $found = $found || ($row['column_name'] ?? '') === 'id';
    }
    echo $found ? "id-indexed\n" : "id-not-indexed\n";
} finally {
    uodbcDrop($connection, 'phpman_stats_product');
    odbc_close($connection);
}
Ожидаемый результат
id-indexed

Metadata показывает наличие индексной записи, но не доказывает, что конкретный запрос выберет этот индекс. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Отфильтровать только уникальные индексыСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_stats_customer');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_stats_customer (id INTEGER PRIMARY KEY, email VARCHAR(80) UNIQUE)');
    $result = odbc_statistics($connection, null, 'public', 'phpman_stats_customer', SQL_INDEX_UNIQUE, SQL_QUICK);
    $columns = [];
    while ($row = odbc_fetch_array($result)) {
        $row = array_change_key_case($row, CASE_LOWER);
        if (($row['column_name'] ?? '') !== '') { $columns[] = $row['column_name']; }
    }
    sort($columns);
    echo implode(',', array_unique($columns)), "\n";
} finally {
    uodbcDrop($connection, 'phpman_stats_customer');
    odbc_close($connection);
}
Ожидаемый результат
email,id

UNIQUE email и PRIMARY KEY id оба попадают в фильтр уникальных индексов. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Один индекс занимает несколько строк.
  • Наличие индекса не равно плану запроса.
  • SQL_QUICK может вернуть приблизительную статистику.

Когда выбрать другое. EXPLAIN конкретной СУБД отвечает, как выполнится запрос; migrations отвечают, какие индексы должны существовать.

Связанные операции: odbc_primarykeys(), odbc_columns().

odbc_tableprivilegesПеречисляет права на таблицу, видимые через ODBC catalog: grantee, privilege и is_grantable.

PHP 4+; PHP 8.4 Odbc\Connection/Odbc\Result и nullable catalog · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_tableprivileges(Odbc\Connection $odbc, ?string $catalog, string $schema, string $table): Odbc\Result|false

Перечисляет права на таблицу, видимые через ODBC catalog: grantee, privilege и is_grantable.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_tableprivileges(Odbc\Connection $odbc, ?string $catalog, string $schema, string $table): Odbc\Result|false

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
?string $catalogКаталог источника данных либо null. Значение и поддержка зависят от СУБД/драйвера.
string $schemaСхема. Для PostgreSQL в примерах используется public; пустая строка и null имеют драйверно-зависимый смысл.
string $tableИмя или шаблон таблицы по правилам соответствующей ODBC metadata-функции.

Возврат. Odbc\Result либо false.

Отказ и диагностика. false при отказе; пустой набор может означать отсутствие metadata/прав видимости.

Путь вызова
  1. указать точную таблицу
  2. драйвер вызывает SQLTablePrivileges
  3. строки перечисляют grants
  4. диагностика сравнивает их с ожидаемой ролью
Увидеть право SELECT владельца таблицыСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_priv_table');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_priv_table (id INTEGER PRIMARY KEY)');
    $result = odbc_tableprivileges($connection, null, 'public', 'phpman_priv_table');
    $found = false;
    while ($row = odbc_fetch_array($result)) {
        $row = array_change_key_case($row, CASE_LOWER);
        $found = $found || strtoupper((string) ($row['privilege'] ?? '')) === 'SELECT';
    }
    echo $found ? "select=yes\n" : "select=no\n";
} finally {
    uodbcDrop($connection, 'phpman_priv_table');
    odbc_close($connection);
}
Ожидаемый результат
select=yes

Catalog отражает grants, видимые драйверу. Приложение всё равно проверяет свою авторизацию пользователя отдельно. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Прочитать признак возможности передавать правоСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_priv_grant');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_priv_grant (id INTEGER PRIMARY KEY)');
    $result = odbc_tableprivileges($connection, null, 'public', 'phpman_priv_grant');
    $rows = 0;
    $hasField = false;
    while ($row = odbc_fetch_array($result)) {
        $row = array_change_key_case($row, CASE_LOWER);
        $rows++;
        $hasField = $hasField || array_key_exists('is_grantable', $row);
    }
    echo $rows > 0 && $hasField ? "grant-metadata=yes\n" : "grant-metadata=no\n";
} finally {
    uodbcDrop($connection, 'phpman_priv_grant');
    odbc_close($connection);
}
Ожидаемый результат
grant-metadata=yes

IS_GRANTABLE — metadata администратора, не кнопка для автоматической выдачи прав из веб-интерфейса. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Права БД и авторизация пользователя сайта — разные уровни.
  • Не показывайте grants публично.
  • Vendor roles/inherited privileges могут отображаться неполно.

Когда выбрать другое. Нативные системные каталоги СУБД дают больше деталей; infrastructure-as-code хранит ожидаемые GRANT отдельно.

Связанные операции: odbc_columnprivileges(), odbc_tables().

odbc_columnprivilegesПеречисляет grants для колонок выбранной таблицы.

PHP 4+; PHP 8.4 Odbc\Connection/Odbc\Result и nullable catalog · odbc; требуется ODBC Driver Manager и драйвер конкретной СУБД

odbc_columnprivileges(Odbc\Connection $odbc, ?string $catalog, string $schema, string $table, string $column): Odbc\Result|false

Перечисляет grants для колонок выбранной таблицы.

Как прочитать вызов. Имя до круглых скобок выбирает операцию; аргументы внутри передаются слева направо. Результат можно сохранить справа от =. Объекты Odbc\Connection и Odbc\Result создаёт расширение, а не пользовательский new. Разбор вызова функции; сравнение с PDO.

Сигнатура PHP 8.5.11. odbc_columnprivileges(Odbc\Connection $odbc, ?string $catalog, string $schema, string $table, string $column): Odbc\Result|false

ПараметрЧто передать
Odbc\Connection $odbcОбъект Odbc\Connection, который вернул odbc_connect() или odbc_pconnect(). Он привязан к одному драйверу и одной сессии базы.
?string $catalogКаталог источника данных либо null. Значение и поддержка зависят от СУБД/драйвера.
string $schemaСхема. Для PostgreSQL в примерах используется public; пустая строка и null имеют драйверно-зависимый смысл.
string $tableИмя или шаблон таблицы по правилам соответствующей ODBC metadata-функции.
string $columnИмя или шаблон столбца по правилам metadata-функции.

Возврат. Odbc\Result либо false.

Отказ и диагностика. false при отказе, пустой набор при отсутствии совпадений/metadata.

Путь вызова
  1. указать catalog/schema/table/column
  2. драйвер вызывает SQLColumnPrivileges
  3. каждая строка связывает column/grantee/privilege
  4. аудит сравнивает с минимально необходимыми правами
Проверить права на конкретную колонкуСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_column_priv');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_column_priv (id INTEGER PRIMARY KEY, secret VARCHAR(20))');
    $result = odbc_columnprivileges($connection, null, 'public', 'phpman_column_priv', 'secret');
    $found = false;
    while ($row = odbc_fetch_array($result)) {
        $row = array_change_key_case($row, CASE_LOWER);
        $found = $found || ($row['column_name'] ?? '') === 'secret';
    }
    echo $found ? "secret-metadata=yes\n" : "secret-metadata=no\n";
} finally {
    uodbcDrop($connection, 'phpman_column_priv');
    odbc_close($connection);
}
Ожидаемый результат
secret-metadata=yes

Даже если роль БД может SELECT колонку, приложение не обязано включать её в API-ответ. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Получить пустой набор для отсутствующей колонкиСамостоятельный пример
<?php
declare(strict_types=1);

require __DIR__ . '/uodbc-bootstrap.php';

$connection = uodbcConnect();
uodbcDrop($connection, 'phpman_column_priv_missing');
try {
    uodbcExec($connection, 'CREATE TABLE phpman_column_priv_missing (id INTEGER PRIMARY KEY)');
    $result = odbc_columnprivileges($connection, null, 'public', 'phpman_column_priv_missing', 'unknown_column');
    $count = 0;
    while ($result !== false && odbc_fetch_array($result)) { $count++; }
    echo "matches={$count}\n";
} finally {
    uodbcDrop($connection, 'phpman_column_priv_missing');
    odbc_close($connection);
}
Ожидаемый результат
matches=0

Пустой набор — нормальный результат фильтра, а false означал бы отказ API. Пример выполнен через PHP 8.5.11/ext/odbc и psqlODBC 18.00 на отдельной локальной учебной базе PostgreSQL 18.6. Реквизиты передаются переменными окружения; рабочие пароли и данные в пример не входят. Таблицы с префиксом phpman_ создаются только для этого запуска и удаляются в finally.

Частые ошибки.

  • Не подменяет field-level authorization приложения.
  • Inherited/vendor privileges могут отображаться иначе.
  • Шаблоны имён/регистр зависят от драйвера.

Когда выбрать другое. Явный SELECT нужных колонок и отдельная policy-модель приложения остаются основной защитой.

Связанные операции: odbc_tableprivileges(), odbc_columns().

Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.