Pg lo import: примеры (PHP)
pg_lo_import(PgSql\Connection $connection, string $filename, $object_id = ?): int|falseОсновы функции pg_lo_import
Функция pg_lo_import в PHP предназначена для импорта содержимого файла в базу данных PostgreSQL в качестве большого объекта (Large Object, BLOB).
Функция имеет два варианта сигнатуры:
- pg_lo_import($connection, $pathname, $object_id = null)
- pg_lo_import($pathname, $object_id = null, $connection = null) (устаревший с PHP 8.1)
Параметры:
- $connection (ресурс или PgSql\Connection) - соединение с базой данных PostgreSQL.
- $pathname (string) - путь к файлу на сервере, содержимое которого будет загружено.
- $object_id (int) - необязательный идентификатор для создаваемого большого объекта. Если не указан, будет сгенерирован сервером.
Возвращает OID (целочисленный идентификатор) созданного большого объекта или false при ошибке.
Простые примеры использования
$conn = pg_connect("dbname=test user=postgres");
if ($conn) {
$oid = pg_lo_import($conn, '/tmp/document.pdf');
if ($oid) {
echo "Файл загружен с OID: $oid";
} else {
echo "Ошибка загрузки";
}
pg_close($conn);
}Файл загружен с OID: 123456
$conn = pg_connect("dbname=test user=postgres");
$oid = pg_lo_import($conn, '/tmp/image.jpg', 987654);
echo $oid ? "Объект создан с OID: $oid" : "Ошибка";Объект создан с OID: 987654
$oid = pg_lo_import($conn, '/nonexistent/file.txt');
if ($oid === false) {
echo "Ошибка импорта файла";
// pg_last_error($conn) можно использовать для получения деталей
}Ошибка импорта файла
Альтернативные функции в PHP
Функция pg_lo_import также может принимать строковый путь, что является основным способом.
Вместо больших объектов можно хранить данные в колонке типа BYTEA:
$data = file_get_contents('/tmp/file.pdf');
$escaped = pg_escape_bytea($conn, $data);
$result = pg_query($conn, "INSERT INTO files (content) VALUES ('$escaped')");Для больших файлов можно использовать комбинацию pg_lo_open, pg_lo_write и pg_lo_close для потоковой передачи.
Реализации в других языках
import psycopg2
conn = psycopg2.connect("dbname=test user=postgres")
with conn.cursor() as cur:
with open('/tmp/file.pdf', 'rb') as f:
oid = conn.lobject().import(f)
print(f"OID: {oid}")
conn.commit()OID: 123456
const { Client } = require('pg');
const fs = require('fs');
const client = new Client();
await client.connect();
const stream = fs.createReadStream('/tmp/file.pdf');
const oid = await client.query('BEGIN');
const lo = new LargeObject(client, oid);
await lo.write(stream);
await client.query('COMMIT');
console.log(`OID: ${oid}`);Pg lo import в MySQL
В MySQL обычно используют тип BLOB:
INSERT INTO files (data) VALUES (LOAD_FILE('/tmp/file.pdf'));INSERT INTO files (data) VALUES (pg_read_binary_file('/tmp/file.pdf'));Распространенные ошибки
// Файл отсутствует
$oid = pg_lo_import($conn, '/tmp/notfound.txt');
var_dump($oid);bool(false)
// Пользователь БД не имеет прав на создание больших объектов
$oid = pg_lo_import($conn, '/tmp/file.pdf');
if ($oid === false) {
echo "Ошибка: " . pg_last_error($conn);
}Ошибка: ERROR: permission denied for large object 123456
// В PHP 8.1+ этот вызов может вызвать предупреждение
$oid = pg_lo_import('/tmp/file.pdf', null, $conn);// Передача не ресурса и не объекта PgSql\Connection
$conn = null;
$oid = pg_lo_import($conn, '/tmp/file.pdf');Warning: pg_lo_import(): supplied resource is not a valid PostgreSQL link resource
Изменения в версиях PHP
Функция pg_lo_import стала принимать объект PgSql\Connection вместо ресурса. Сигнатура с соединением в качестве третьего параметра устарела.
Добавлена поддержка именованных аргументов при вызове функции.
Рекомендуется использовать первую сигнатуру с соединением в качестве первого параметра.
Расширенные примеры
$conn = pg_connect("dbname=test");
$file_path = '/tmp/report.pdf';
$oid = pg_lo_import($conn, $file_path);
if ($oid) {
$file_name = basename($file_path);
$file_size = filesize($file_path);
$mime_type = mime_content_type($file_path);
$result = pg_query_params(
$conn,
'INSERT INTO documents (oid, name, size, mime_type) VALUES ($1, $2, $3, $4)',
[$oid, $file_name, $file_size, $mime_type]
);
echo "Документ '$file_name' сохранен с OID: $oid";
}Документ 'report.pdf' сохранен с OID: 234567
pg_query($conn, 'BEGIN');
try {
$oid = pg_lo_import($conn, '/tmp/important.dat');
if (!$oid) {
throw new Exception('Ошибка импорта');
}
// Связываем с записью в таблице
pg_query_params($conn, 'UPDATE data SET file_oid = $1 WHERE id = 1', [$oid]);
pg_query($conn, 'COMMIT');
echo "Файл загружен в транзакции, OID: $oid";
} catch (Exception $e) {
pg_query($conn, 'ROLLBACK');
echo "Ошибка: " . $e->getMessage();
}Файл загружен в транзакции, OID: 345678
// Предположим, файл загружен через форму
if ($_FILES['userfile']['error'] === UPLOAD_ERR_OK) {
$tmp_path = $_FILES['userfile']['tmp_name'];
$conn = pg_connect("dbname=test");
$oid = pg_lo_import($conn, $tmp_path);
if ($oid) {
// Связываем OID с пользователем
$user_id = 42;
pg_query_params($conn, 'UPDATE users SET avatar_oid = $1 WHERE id = $2', [$oid, $user_id]);
}
}$files = ['/tmp/file1.pdf', '/tmp/file2.jpg', '/tmp/file3.txt'];
$conn = pg_connect("dbname=test");
$oids = [];
foreach ($files as $file) {
if (file_exists($file)) {
$oid = pg_lo_import($conn, $file);
if ($oid) {
$oids[basename($file)] = $oid;
}
}
}
print_r($oids);Array
(
[file1.pdf] => 456789
[file2.jpg] => 456790
[file3.txt] => 456791
)// PDO не имеет прямой поддержки pg_lo_import, но можно использовать так:
$pdo = new PDO('pgsql:dbname=test');
$pdo->beginTransaction();
$stmt = $pdo->query("SELECT lo_import('/tmp/file.pdf') as oid");
$oid = $stmt->fetchColumn();
$pdo->commit();
echo "OID: $oid";OID: 567890