質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

5009閲覧

32bit → 64bit環境へ移行する際、PostgreSQL内のbytea型データに対してエラーがでます。

ssall

総合スコア30

CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2017/02/27 05:56

編集2017/02/27 06:45
  • 概要

CentOS5 32bit の環境をバージョンアップするためにCentOS6 64bitへ移行しようとしております。
PostgreSQLのデータをdumpallして64bitの新環境にデータを移したのですが、
その中のデータに画像をbytea型というバイナリデータにして格納されているカラムがあり、
中身自体は64bit仕様に書き換えられているように見えるのですが、ブラウザ表示でエラーとなります。
さらに、64bit環境で新規に登録したデータについても同様のエラーが発生しており、それについても対処法がわからず困っております。

  • 質問内容

後述の詳細欄にて対処したことや、32bitが関係ないように思える64bit内での動きを書いておりますが、質問内容としては以下のことがメインです。

32bitから64bitのOSへ移行したときのPostgres内bytea型のデータは、dumpallしてそのままphpで扱えるデータなのか。使えない場合はどうしたら64bit版のデータに変換できるのか。

  • 詳細

■アプリについて
・webサーバ:apacheとphp
・DBサーバ:postgres
・OS:どちらもCentOSで今回5の32bitから6の64bitにアップグレードする
となっており、ブラウザ上で操作するとphpからpostgresを操作してデータをとり、表示するといった構成です。

■bytea型でpostgreに保存されているデータについて
・画像データ
・画像に付随する情報データ
の2種類が別カラムで保存されている状態です。32bitのOSのときにphpPgAdminにて確認したデータ形式は32bit仕様のものでしたが、dumpall後に64bitのOSに移したときには中身が変わっていて、一見すると64bit仕様の形式になっているように見えます。(すみません、調査してもこれ以上のことはよくわかりませんでした。)

■エラーについて
ブラウザ上でbytea型で保存されている画像を表示させるときに下記のエラーがでます。

Warning : pack() [<a href='function.pack'>function.pack</a>]: Type H:illegal hex digit x in ○○○←対象phlファイル名

■行った対処法
64bit環境に移行した後で、新規に登録した画像データについても上記エラーが発生することがわかり、エラーにて表示されているファイルの場所から調査しました。
すると、既に別のプログラムでデコード処理は行われていたのですが、pack()関数だとバイナリデータの0~f以外の文字列を変換できないためエラーが発生することまでわかりました。
その回避方法として、pack()関数の前にpg_unescape_byea()関数を使用してバイナリデータをアンエスケープしたのですが、ローカル検証機(32bitデータは入っていない)ではこの対処法でエラーが消えたにもかかわらず、本環境ではエラーが消えませんでした。

■上記対処法に対して調査した結果
ローカル環境ではbytea型の中身は¥xから始まる文字列であるのに対し、本環境では16進数で表示されていることがわかりました。しかし、このデータをvar_dump()で表示した場合は¥xで始まる文字列で表示されていて、正直どういったことが起きているのかよくわかりません。

■行った対処法2
DBのデータ型をbytea型からtext型に変更したところ、phpのコードの変更なく、pack()関数だけでうまくいきました。しかし、データ型を変更すると以前のデータを表示できなくなる可能性があるため、あくまで最悪の手段としてできればこの方法は使いたくありません。

以上です。
少しまとまりが悪い質問となってしまい申し訳ございませんが、何卒ご教示頂けませんでしょうか。


追記1
postgresqlのバージョンは
移行前:8.3
移行後:9.2
となっております。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

A.Ichi

2017/02/27 06:28

32と64サーバのPostgresのバージョンは一緒でしょうか?
ssall

2017/02/27 06:44 編集

すみません。大事な情報が抜け落ちていました。postgresqlのバージョンは8.3.23から8.4.20に上がっています ↑ 上記間違っておりました。移行後は9.2です。重ね重ねすみません。
guest

回答1

0

ベストアンサー

同じ環境とPHPが揃わなかったのでご参考としてください。

32bitから64bitのOSへ移行したときのPostgres内bytea型のデータは、dumpallしてそのままphpで扱えるデータなのか。使えない場合はどうしたら64bit版のデータに変換できるのか。

に関してのみですが、下記の環境ではできました。但しdumpallでなくpg_dumpにてテーブル指定して行いましたので、異なるかもしれません。
CentOS 5.3(32bit) Postgres 8.3.8
CentOS 6.8(64bit) Postgres 9.3.6
(1)32ビットサーバでjpegファイルをPHPで取り込み
(2)pg_dumpでダンプファイルを作成
(3)64ビットサーバで上記ファイルをpsqlで取り込み
(4)phpでブラウザでjpegイメージを表示

つたないテストPHPですが・・・

php

1$conn = pg_connect( 'host=127.0.0.1 port=5432 dbname=hogedb user=hoge' ); 2if( $conn == false ) exit; 3 4$sql = "SELECT ENCODE( byte_data::bytea, 'escape' ) byte_data FROM tst_image"; 5$res = pg_query( $sql ); 6if( $res == false ) exit; 7 8$data = pg_fetch_object( $res ); 9if( $data == false ) exit; 10 11//DB切断 12pg_free_result( $res ); 13pg_close( $conn ); 14 15//画像の情報を取得する 16$img = base64_encode( pg_unescape_bytea( $data->byte_data ) ); 17$scheme = 'data:application/octet-stream;base64,'; 18$size = getimagesize( $scheme . $img ); 19if( $size == false ) exit; 20 21//バイナリに変換し、ブラウザに送信する 22header( 'Content-type: ' . $size['mime'] ); 23echo pg_unescape_bytea( $data->byte_data ); 24exit; 25

投稿2017/02/27 08:54

A.Ichi

総合スコア4070

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ssall

2017/02/28 02:15

A.Ichi様 ご回答頂き有難うございます。 また、わざわざ環境をご用意して検証して頂き有難うございます。 上記のコードと環境でできるということはそもそものpostgresqlの設定がおかしいだろうといういことで調査したのですが、こちらのサイトのように、どうやらbytea型に対するデフォルトの設定がバージョンが上がって変更されたそうで、 http://www.jdcn.co.jp/blog/archives/2010/10/postgresql-9.php サイトの通りにbytea_output = 'escape'の設定を入れたところ、ひとまずエラーなく表示されるようになりました。 まだ検証が全て済んだわけではありませんが、ご協力頂いたおかげで原因の特定につながりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問