Pg unescape bytea: примеры (PHP)
pg_unescape_bytea(string $string): stringФункция pg_unescape_bytea используется для преобразования строки, содержащей бинарные данные в формате bytea из PostgreSQL, в обычную строку или бинарные данные в PHP. Эта операция требуется после получения данных из колонки типа BYTEA, так как PostgreSQL возвращает их в экранированном виде.
Функция принимает один обязательный аргумент:
- $string (
string) – Строка, содержащая данные bytea, полученные из PostgreSQL. Это входные данные, которые необходимо преобразовать.
Возвращаемое значение – строка с декодированными бинарными данными или false в случае ошибки.
Предположим, в базе хранится экранированное представление бинарных данных.
<?php
$escapedString = '\\x546573742064617461'; // Экранированное представление в формате hex
$decodedData = pg_unescape_bytea($escapedString);
echo bin2hex($decodedData); // Для отображения
?>546573742064617461Пример получения данных из базы и их декодирования.
<?php
$conn = pg_connect('dbname=test');
$result = pg_query($conn, 'SELECT binary_data FROM my_table WHERE id = 1');
$row = pg_fetch_assoc($result);
$decoded = pg_unescape_bytea($row['binary_data']);
file_put_contents('image.jpg', $decoded); // Сохранение как файл
?>// Файл image.jpg создан с бинарным содержимымПрямых аналогов для работы именно с форматом bytea PostgreSQL в PHP нет. Однако для общего декодирования бинарных данных могут использоваться:
- base64_decode() – Декодирует строку, закодированную в Base64. Применяется, если данные хранятся в этом формате, а не в bytea.
- hex2bin() – Преобразует шестнадцатеричную строку в бинарные данные. Может быть полезной, если данные получены в hex-формате без префикса '\\\\x'.
Функция pg_unescape_bytea является специализированной для формата PostgreSQL и автоматически обрабатывает как старый (экранированный), так и новый (hex) формат bytea.
Декодирование происходит автоматически при получении данных. Вручную можно использовать метод tobytes().
import psycopg2
conn = psycopg2.connect('dbname=test')
cur = conn.cursor()
cur.execute('SELECT binary_data FROM my_table')
data = cur.fetchone()[0] # Уже декодированные байты
print(data[:10]) # Первые 10 байтb'\x89504e47\x0d\x0a'Данные bytea возвращаются как Buffer, не требуя дополнительного декодирования.
const { Client } = require('pg');
const client = new Client();
await client.connect();
const res = await client.query('SELECT binary_data FROM my_table');
const buffer = res.rows[0].binary_data; // Объект Buffer
console.log(buffer.toString('hex').substring(0, 20));89504e470d0a1a0a00Pg unescape bytea в MySQL
Аналогом типа BYTEA является BLOB. Данные из BLOB-поля возвращаются как есть, без специального экранирования.
SELECT blob_column FROM my_table INTO DUMPFILE 'output.dat';Функция ожидает строку. Передача другого типа может привести к неожиданному результату.
<?php
$data = null;
$result = pg_unescape_bytea($data);
var_dump($result);
?>bool(false)Двойное применение функции к данным, которые уже были преобразованы, приводит к порче данных.
<?php
$originalHex = '54657374';
$escaped = '\\\\x' . $originalHex; // Имитация формата hex из PostgreSQL
$decodedOnce = pg_unescape_bytea($escaped); // Корректно
$decodedTwice = pg_unescape_bytea($decodedOnce); // Ошибка
echo bin2hex($decodedOnce) . '\n';
echo bin2hex($decodedTwice) . '\n';
?>54657374
00Начиная с PHP 5.5.1, функция pg_unescape_bytea поддерживает оба формата bytea: старый экранированный и новый шестнадцатеричный (с префиксом '\\\\x'). В более ранних версиях поддерживался только экранированный формат.
В PHP 8.0 не было внесено критических изменений в работу этой функции. Поведение осталось стабильным. Однако, как и все расширения PostgreSQL, рекомендуется использовать последнюю версию для исправления возможных ошибок безопасности и совместимости.
Постепенное чтение и декодирование больших данных для экономии памяти.
<?php
$conn = pg_connect('dbname=test');
$handle = pg_query($conn, 'SELECT large_binary_data FROM documents WHERE id = 123');
$data = pg_fetch_result($handle, 0, 0);
$decoded = pg_unescape_bytea($data);
// Потоковая обработка или сохранение частями
$chunkSize = 8192;
for ($i = 0; $i < strlen($decoded); $i += $chunkSize) {
$chunk = substr($decoded, $i, $chunkSize);
// Обработка чанка...
}
?>Функция корректно обрабатывает оба формата.
<?php
// Шестнадцатеричный формат (новый)
$hexData = '\\\\x48656c6c6f20576f726c64';
// Экранированный формат (старый) для тех же данных
$escData = 'Hello\\\\000World';
$resultHex = pg_unescape_bytea($hexData);
$resultEsc = pg_unescape_bytea($escData);
echo $resultHex . '\n';
echo $resultEsc . '\n';
?>Hello World
Hello WorldКомбинирование преобразований, если данные хранятся в base64 внутри bytea.
<?php
// Предположим, в bytea хранится строка base64
$conn = pg_connect('dbname=test');
$result = pg_query($conn, 'SELECT encoded_data FROM files');
$row = pg_fetch_assoc($result);
$byteaData = pg_unescape_bytea($row['encoded_data']);
$finalData = base64_decode($byteaData); // Декодирование из base64
file_put_contents('restored.pdf', $finalData);
?>