2016-10-13 8 views
1

私はPHPがPostgreSQLバインディングでByteAをどのように処理するかを理解する上で問題があります。PHP PDOオブジェクトを使用してPostgreSQL ByteAに格納されたgzcompressed文字列を復元するには?

ロギングとアーカイブの目的のために私はByteAのPHP/Apache Serverで提供されるファイルを格納しています。保存のために、私はgzencode()を使用してデータを圧縮し、その後、私はpg_escape_bytea()を使用して保存する前に文字列をエスケープ:

// Compress: 
if($compress) { 
    $data = gzencode($data, 9); 
} 
// PostgreSQL ByteA Escaping: 
$data = pg_escape_bytea($data); 

私はまた、ユーザが前の務めファイルを取得できるようにするページがあります。しかし、私は、圧縮されたいずれかの成功することはできません、と私はその理由を見つけることができません:

$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT); 

/* 
$dbCur = $webConn->prepare("SET bytea_output = 'escape';"); 
$dbCur->execute(); 
//print_r($dbCur->errorinfo()); 
*/ 

$dbCur = $webConn->prepare("SELECT * FROM logs.webservice WHERE Id=?;"); 
$dbCur->bindParam(1, $id);  
$dbCur->execute(); 
//print_r($dbCur->errorinfo()); 

$row = $dbCur->fetch(PDO::FETCH_ASSOC); 

$data = stream_get_contents($row['binarydata']); 
$data = pg_unescape_bytea($data); 

if($row['gzip']) { 
    $data = gzdecode($data); 
} 

header("Content-type: ".$row['mimetype']."; charset=".$row['charset']); 
echo $data; 

私はPDOオブジェクトを使用する必要があり、私が(でもPHPのウェブサイト上で)を発見したすべての例は、専用のDBMSのAPIに基づいています。次に、の列がリソースとして返された場合、文字列を取得するためにstream_getcontents()を使用しなければなりませんでした。私は圧縮されていないファイルを格納するとき、私はそれを簡単に、今まで何を使用するかどうかから回復することができますSET bytea_output = 'escape';クエリおよび/またはpg_unescape_bytea()機能。すべての組み合わせでファイルを取得できます。

圧縮データを使用すると、pg_unescape_bytea()はほとんどすべてのバイトを劇的に食いつぶします。とにかく、すべての組み合わせで、gzdecode()は機能しません。私のバイナリ文字列には、プレーンテキストモードでブロックしない文字がありません。とにかく、事はインターネット上で十分に文書化されておらず、私は何の手がかりもなく止まっています。

PHP PDOオブジェクトを使用してPostgreSQL ByteAに格納されたgzcompressed文字列を復元するにはどうすればよいですか?

$data = stream_get_contents($row['binarydata']); 

必要に応じて、彼らは生のバイナリ形式ですでに、バイナリ内容は次のコードで$dataに入るたら

答えて

1

のみ検索の問題を解決する、挿入を想定する

作品したがって、これを使って再度デコードする必要はありません:

$data = pg_unescape_bytea($data);

そのスプリアスをエスケープ解除してください。 $dataにASCII文字のみが含まれている場合に問題が発生しない理由は、pg_unescape_byteaがこれらの文字を自分自身に変換することです(bytea_outputはエスケープに設定されています)。

しかし、バイナリストリームに実際にgzip形式のコンテンツなどの256バイトの可能な全バイトが含まれていると、pg_unescape_byteaがそのコンテキストで破損した結果を生成することが保証されます。

pg_unescape_byteaは、データベースからbytea-encoded-as-textとして直接入力される文字列でのみ使用してください。それは通常、PDOで実際に我々はPDOは、データベース・独立しているのでpg_[un]escape_bytea機能、またはpg_*で始まるの機能さえいずれかを使用することになって、その目的していないPDO

で行われていますどのように

異なるデータベース間で動作するコードを許可することです。

挿入は、PDO::PARAM_LOBでバイナリパラメータを修飾してhttp://php.net/manual/en/pdo.lobs.phpに記載されているように行う必要があります。これを行うとき、PDOは、それが接続されている種類のデータベースに適切な方法を使用して、バイナリ転送用のデータをエンコードします。

pg_escape_bytea()で明示的にエスケープすると、PDOがテキストコンテンツとみなしてそのように送信できる文字列が生成されます。これは「PDOの背後にある」バイナリを送信する方法ですが、その点ではあまり意味がありません。

間違って動作しないのは、エスケープ(テキストを生成する)です。バイナリであることをPDOに伝えます。

+0

私はこれについて本当に混乱しています。私はそれがcharsetにリンクされていることがわかります。しかし、私はそれを動作させることはできません。私はpg_escpae_byteaを使用せずにByteAにgzcompressedデータを格納することはできません。それは問題かもしれません。私は何が欠けているのですか? – jlandercy

+0

pg_escape_byteaを使用せずにgzcompressedを挿入するとエラーが表示されます:エンコーディング "UTF8"のバイトシーケンスが無効です:0x8b。機能を使用すると、データを取得すると、私が挿入したものとは異なるものが返されます。 – jlandercy

+0

このページhttp://sickel.net/blogg/?p=1365は解決策を提供しますが、それは生産的ではなく、私が働きたいのとまったく逆です。バイナリデータを16進文字列で表現するのではなく、バイナリデータを格納したい(gzip形式を変更せずに)ことができます。 – jlandercy

関連する問題