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

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

ただいまの
回答率

90.53%

  • PHP

    20256questions

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

  • CentOS

    2692questions

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

  • PostgreSQL

    1057questions

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

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

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,330

ssall

score 21

  • 概要
    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
となっております。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • A.Ichi

    2017/02/27 15:28

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

    キャンセル

  • ssall

    2017/02/27 15:36 編集

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

    キャンセル

回答 1

checkベストアンサー

+1

同じ環境と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ですが・・・

$conn = pg_connect( 'host=127.0.0.1 port=5432 dbname=hogedb user=hoge' );
if( $conn == false ) exit;

$sql = "SELECT ENCODE( byte_data::bytea, 'escape' ) byte_data FROM tst_image";
$res = pg_query( $sql );
if( $res == false ) exit;

$data = pg_fetch_object( $res );
if( $data == false ) exit;

//DB切断
pg_free_result( $res );
pg_close( $conn );

//画像の情報を取得する
$img = base64_encode( pg_unescape_bytea( $data->byte_data ) );
$scheme = 'data:application/octet-stream;base64,';
$size = getimagesize( $scheme . $img );
if( $size == false ) exit;

//バイナリに変換し、ブラウザに送信する
header( 'Content-type: ' . $size['mime'] );
echo pg_unescape_bytea( $data->byte_data );
exit;

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/28 11:15

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

    キャンセル

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

  • ただいまの回答率 90.53%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • PHP

    20256questions

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

  • CentOS

    2692questions

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

  • PostgreSQL

    1057questions

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