Pg lo write: примеры (PHP)
pg_lo_write(PgSql\Lob $lob, string $data, ?int $length = null): int|falseОписание функции pg_lo_write
Функция pg_lo_write предназначена для записи данных в крупный объект (large object) внутри базы данных PostgreSQL. Она используется в ситуациях, когда необходимо сохранить большие бинарные данные, такие как изображения, документы или аудиофайлы, напрямую в СУБД, а не в файловой системе.
- PgSql\Lob или resource $lob — обязательный аргумент. Дескриптор крупного объекта, полученный с помощью функции pg_lo_open().
- string $data — обязательный аргумент. Строка с данными для записи в объект.
- ?int $length — необязательный аргумент. Максимальное количество записываемых байтов. Если аргумент опущен или равен null, записываются все данные из строки.
Функция возвращает количество байтов, записанных в крупный объект, или false в случае возникновения ошибки.
Короткие примеры использования
$conn = pg_connect("dbname=test user=postgres");
$oid = pg_lo_create($conn);
$lob = pg_lo_open($conn, $oid, "w");
$data = "Пример текстовых данных.";
$bytesWritten = pg_lo_write($lob, $data);
pg_lo_close($lob);
echo "Записано байт: " . $bytesWritten;
Записано байт: 44
$lob = pg_lo_open($conn, $oid, "w");
$result = pg_lo_write($lob, "Очень длинная строка для примера.", 10);
pg_lo_close($lob);
echo $result;
10
$invalidLob = null;
$result = pg_lo_write($invalidLob, "данные");
if ($result === false) {
echo "Ошибка при записи.";
}
Ошибка при записи.
Похожие функции в PHP
Функция для чтения данных из крупного объекта. Используется вместе с pg_lo_write для реализации полного цикла работы.
Создает крупный объект из файла в локальной файловой системе. Позволяет импортировать данные без явного открытия и поэтапной записи.
Выгружает крупный объект в файл. Альтернатива последовательному чтению через pg_lo_read.
Функцию pg_lo_write предпочтительнее использовать для потоковой записи данных, генерируемых в скрипте. pg_lo_import больше подходит для загрузки готовых файлов.
Аналоги в других языках и СУБД
import psycopg2
conn = psycopg2.connect("dbname=test")
lo = conn.lobject()
data = b"Binary data"
n = lo.write(data)
print(n)
11
В Python работа с крупными объектами организована через методы объекта lobject, что ближе к объектно-ориентированному стилю.
const { LargeObject } = require('pg-large-object');
// ... получение client из 'pg'
const buffer = Buffer.from('Data');
client.query('BEGIN', (err) => {
const stream = new LargeObject(client, oid, 'w');
stream.write(buffer, (err, bytesWritten) => {
console.log(bytesWritten);
});
});
В Node.js часто используется потоковый API (Streams) для записи, что упрощает обработку больших объемов.
Pg lo write в MySQL
В MySQL нет прямого аналога крупных объектов PostgreSQL. Для хранения больших данных используются типы BLOB. Запись происходит стандартными SQL-операторами INSERT или UPDATE.
INSERT INTO files (blob_column) VALUES (LOAD_FILE('/tmp/file.bin'));
Типичные ошибки
$conn = pg_connect("dbname=test");
$fakeLob = "not a resource";
$result = pg_lo_write($fakeLob, "test");
Warning: pg_lo_write() expects parameter 1 to be resource, string given
$lob = pg_lo_open($conn, $oid, "r"); // Открыт для чтения
$bytes = pg_lo_write($lob, "data");
Запись не выполняется, функция вернет false.
В PostgreSQL операции с крупными объектами требуют нахождения внутри транзакции. В противном случае может возникнуть ошибка.
pg_query($conn, "END"); // Завершаем предыдущую транзакцию
$oid = pg_lo_create($conn); // Вызовет ошибку
Изменения в версиях PHP
Начиная с PHP 8.1.0, первый аргумент функции ($lob) ожидается как объект PgSql\Lob. Ранее он был ресурсом (resource).
В PHP 8.0.0, при неудачном выполнении, функция теперь возвращает false. В очень старых версиях мог возвращать 0. Рекомендуется всегда использовать строгое сравнение (===) для проверки на ошибку.
Расширенные примеры использования
$filePath = "/путь/к/большому/файлу.iso";
$oid = pg_lo_create($conn);
$lob = pg_lo_open($conn, $oid, "w");
$handle = fopen($filePath, "rb");
$chunkSize = 4096;
$totalWritten = 0;
while (!feof($handle)) {
$buffer = fread($handle, $chunkSize);
$written = pg_lo_write($lob, $buffer);
if ($written === false) {
// Обработка ошибки
break;
}
$totalWritten += $written;
}
fclose($handle);
pg_lo_close($lob);
echo "Всего записано: $totalWritten байт";
pg_query($conn, "BEGIN");
try {
$oid = pg_lo_create($conn);
$lob = pg_lo_open($conn, $oid, "w");
pg_lo_write($lob, "Важные данные транзакции.");
pg_lo_close($lob);
// Связываем OID с записью в таблице
pg_query($conn, "INSERT INTO documents (file_oid) VALUES ($oid)");
pg_query($conn, "COMMIT");
} catch (Exception $e) {
pg_query($conn, "ROLLBACK");
throw $e;
}
// Создаем простое изображение GD
$im = imagecreatetruecolor(100, 100);
$color = imagecolorallocate($im, 200, 100, 50);
imagefill($im, 0, 0, $color);
// Сохраняем изображение в буфер
ob_start();
imagepng($im);
$imageData = ob_get_clean();
imagedestroy($im);
// Записываем буфер в крупный объект
$oid = pg_lo_create($conn);
$lob = pg_lo_open($conn, $oid, "w");
$bytes = pg_lo_write($lob, $imageData);
pg_lo_close($lob);
echo "Изображение сохранено в БД, OID: $oid";