PHPスクリプトを使ってバイナリ列データ型(bytea)へのバイナリーデータの挿入と取得方法を以下に記します。
使用した環境は以下の通りです。
sakura@ubuntu:~$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 12.04.3 LTS Release: 12.04 Codename: precise
sakura@ubuntu:~$ sudo -i -u postgres
postgres@ubuntu:~$ psql -c "select version();"
version
------------------------------------------------------------------------------------------------------
PostgreSQL 9.1.11 on i686-pc-linux-gnu, compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 32-bit
(1 row)postgres@ubuntu:~$ php -version PHP 5.3.10-1ubuntu3.9 with Suhosin-Patch (cli) (built: Dec 12 2013 04:24:43) Copyright (c) 1997-2012 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
以下のようなエラーが出る場合は、PHP用のPostgreSQL用のモジュールがインストールされていません。
PHP Fatal error: Call to undefined function pg_connect() ...
Ubuntuの場合は、以下のコマンドでインストールしてください。
sudo apt-get install php5-pgsql
他のOS環境の場合は、php向けPostgreSQLのモジュールをインストールしてください。
Let's postgres - PHPでのSQLインジェクション対策 - エスケープ・クォート編: pg_escape_****を参考にhex書式でPHPサンプルスクリプトを紹介します。
以下のようなデータベースおよびテーブルを作成しました。
postgres@ubuntu:~$ createdb img_db postgres@ubuntu:~$ psql img_db -c "create table t1 (no int, img bytea);" CREATE TABLE
<?php
$DBNAME = 'img_db';
if ($argc != 3) {
echo "Usage: php $argv[0] <number> <image filename>\n";
exit(1);
}
if (!is_numeric($argv[1])) {
echo $argv[1] . " is not numeric.\n";
exit(1);
}
if (!file_exists($argv[2])) {
echo $argv[2] . " file not found.\n";
exit(1);
}
$no = $argv[1];
$img_filename = $argv[2];
$img_data = file_get_contents($img_filename);
$dbconn = pg_connect("dbname=$DBNAME");
$sql = 'INSERT INTO t1 VALUES(' .
$no . ',' .
'\'' . pg_escape_string($dbconn,'\x' . bin2hex($img_data)) . '\'' .
')';
$res = pg_query($dbconn, $sql);
pg_close($dbconn);
?>
以下の画像データを用意しました。
以下のコマンドでPostgreSQLに挿入してみます。
php ins_img.php 1 sakura-it.png
実際に実行したときの出力です。
postgres@ubuntu:~$ php ins_img.php 1 sakura-it.png postgres@ubuntu:~$ postgres@ubuntu:~$ psql img_db -c 'select count(*) from t1;' count ------- 1 (1 row)
上記の手順でPostgreSQLに挿入した画像データ(PNG)を取り出してみます。
<?php
$DBNAME = 'img_db';
if ($argc != 2) {
echo "Usage: php $argv[0] <number> > filename\n";
exit(1);
}
if (!is_numeric($argv[1])) {
echo $argv[1] . " is not numeric.\n";
exit(1);
}
$no = $argv[1];
$dbconn = pg_connect("dbname=$DBNAME");
$sql = 'SELECT img FROM t1 WHERE ' .
'no = ' . $no;
$res = pg_query($dbconn, $sql);
echo pg_unescape_bytea(pg_fetch_result($res, 'img'));
pg_close($dbconn);
?>
以下のコマンドでPostgreSQLから上記で挿入した画像データを取り出してみます。
php get_img.php 番号(カラムnoの値) > 出力ファイル名
実際に実行したときの出力です。
postgres@ubuntu:~$ php get_img.php 1 > get_img.png postgres@ubuntu:~$ diff sakura-it.png get_img.png postgres@ubuntu:~$ echo $? 0
diffにより元データ(sakura-it.png)とget_img.phpスクリプトで取り出したget_img.pngを比較しました。
差異がないのが確認できます。
以上、bytea型に画像データを挿入と取得例でした。
画像データに限らず、MS Officeの文書ファイルなどバイナリデータであれば同様に動作します。