Pg field type oid: примеры (PHP)
pg_field_type_oid(PgSql\Result $result, int $field): int|stringОписание функции pg_field_type_oid
Функция pg_field_type_oid является частью расширения PostgreSQL (pgsql) для PHP. Она применяется для получения идентификатора объекта (OID) типа данных конкретного поля в результате выполнения SQL-запроса. OID — это внутренний числовой идентификатор типа данных в системе каталогов PostgreSQL.
Использование функции актуально в ситуациях, когда требуется точная идентификация типа данных поля на уровне системы, например, для динамического построения запросов, анализа метаинформации о результате или для интеграции с другими системными функциями PostgreSQL, которые работают с OID.
Функция принимает два аргумента:
- $result (ресурс) — обязательный. Ресурс результата запроса, возвращаемый функциями
pg_query,pg_query_paramsилиpg_execute. - $field_number (int) — обязательный. Порядковый номер поля в результате запроса. Нумерация начинается с нуля.
Функция возвращает целое число (int), которое представляет собой OID типа поля. В случае ошибки может вернуть false.
Краткие примеры использования
Получение OID типа для первого поля в результате.
<?
$conn = pg_connect('dbname=test user=postgres');
$result = pg_query($conn, 'SELECT 123 as number, \'text\' as value');
$oid = pg_field_type_oid($result, 0);
echo 'OID первого поля: ' . $oid;
?>OID первого поля: 23
<?
$result = pg_query($conn, 'SELECT 1::int, 3.14::float, true::bool, now()::date');
for ($i = 0; $i < pg_num_fields($result); $i++) {
$fieldName = pg_field_name($result, $i);
$oid = pg_field_type_oid($result, $i);
echo "Поле {$fieldName} имеет OID: {$oid}\n";
}
?>Поле int4 имеет OID: 23 Поле float8 имеет OID: 701 Поле bool имеет OID: 16 Поле date имеет OID: 1082
Похожие функции в PHP
Для работы с метаданными полей результата запроса в расширении pgsql существуют другие функции:
- pg_field_type — возвращает имя типа поля (например, 'int4', 'varchar'), а не его OID. Используется, когда важно текстовое представление типа.
- pg_field_name — получает имя поля по его номеру.
- pg_field_num — получает номер поля по его имени.
- pg_field_size — возвращает внутренний размер хранилища для поля.
pg_field_type_oid предпочтительнее, когда требуется именно числовой идентификатор для системных операций или сравнений, так как он работает быстрее, чем сравнение строковых имен типов. pg_field_type удобнее для вывода информации пользователю или для логирования.
Аналоги в других языках и СУБД
В psycopg2 тип столбца доступен через свойство type_code объекта cursor description, который является числовым кодом, аналогичным OID.
import psycopg2
conn = psycopg2.connect('dbname=test user=postgres')
cur = conn.cursor()
cur.execute('SELECT 1::int')
oid = cur.description[0].type_code
print(f'OID поля: {oid}')
cur.close()
conn.close()OID поля: 23
В Node.js драйвер pg предоставляет информацию о типах через свойство types объекта результата, но для получения OID требуется анализ метаданных запроса, которые не всегда доступны напрямую на клиенте.
В MySQL аналогом можно считать функцию mysqli_fetch_field_direct()->type, которая возвращает числовой идентификатор типа поля. Однако это ID типа MySQL, а не OID, и архитектура типов отличается от PostgreSQL.
<?
$mysqli = new mysqli('localhost', 'user', 'pass', 'test');
$result = $mysqli->query('SELECT 1');
$field = $result->fetch_field_direct(0);
echo 'ID типа MySQL: ' . $field->type; // MYSQLI_TYPE_LONG -> 3
?>ID типа MySQL: 3
Типичные ошибки
Передача номера поля, выходящего за пределы количества полей в результате.
<?
$result = pg_query($conn, 'SELECT 1');
$oid = pg_field_type_oid($result, 5); // Поля с индексом 5 не существует
var_dump($oid);
?>bool(false)
<?
$not_a_result = null;
$oid = pg_field_type_oid($not_a_result, 0);
?>Warning: pg_field_type_oid() expects parameter 1 to be resource, null given
<?
$result = pg_query($conn, 'SELECT 1');
pg_free_result($result);
$oid = pg_field_type_oid($result, 0);
?>Warning: pg_field_type_oid(): supplied resource is not a valid PostgreSQL result resource
Изменения в последних версиях PHP
Функция pg_field_type_oid не претерпела значительных изменений в поведении или сигнатуре в последних основных версиях PHP, включая PHP 8.x. Она остается стабильной частью расширения pgsql. Однако, начиная с PHP 8.1, ресурсы (resource) постепенно заменяются на объекты. Для функций PostgreSQL, включая pg_field_type_oid, это означает, что параметр $result теперь ожидает объект PgSql\Result (ранее известный как resource). Код, написанный для PHP 7.x, продолжит работу, но тип аргумента в документации указан как объект.
Расширенные примеры использования
Использование OID для выбора функции форматирования вывода.
<?
function formatFieldByOid($value, $oid) {
switch ($oid) {
case 23: // int4
return number_format($value, 0, ',', ' ');
case 25: // text
return htmlspecialchars($value);
case 1184: // timestamptz
return date('d.m.Y H:i', strtotime($value));
default:
return $value;
}
}
$result = pg_query($conn, 'SELECT id, name, created_at FROM users LIMIT 1');
$row = pg_fetch_assoc($result);
foreach ($row as $fieldName => $value) {
$fieldNum = pg_field_num($result, $fieldName);
$oid = pg_field_type_oid($result, $fieldNum);
echo formatFieldByOid($value, $oid) . "\n";
}
?><?
$res1 = pg_query($conn, 'SELECT 1::int as col');
$res2 = pg_query($conn, 'SELECT 2::bigint as col');
$oid1 = pg_field_type_oid($res1, 0); // 23 (int4)
$oid2 = pg_field_type_oid($res2, 0); // 20 (int8)
if ($oid1 === $oid2) {
echo 'Типы полей идентичны';
} else {
echo 'Типы полей различаются';
}
?>Типы полей различаются
<?
// Предположим, что в БД существует тип mood ENUM ('sad', 'ok', 'happy')
$result = pg_query($conn, "SELECT 'happy'::mood");
$oid = pg_field_type_oid($result, 0);
echo 'OID пользовательского типа ENUM: ' . $oid . "\n";
// Можно использовать pg_typeof для получения имени типа
$typeName = pg_fetch_result($result, 0, 0);
echo 'Имя типа: ' . $typeName;
?>OID пользовательского типа ENUM: 12345 Имя типа: happy
<?
$result = pg_query($conn, 'SELECT * FROM information_schema.tables LIMIT 0');
$oids = [];
for ($i = 0; $i < pg_num_fields($result); $i++) {
$oids[pg_field_name($result, $i)] = pg_field_type_oid($result, $i);
}
print_r($oids);
?>Array
(
[table_catalog] => 25
[table_schema] => 25
[table_name] => 25
...
)