画像ファイルのアップロード
掲示板や日記帳などで、記事と一緒に画像ファイルもアップロードして表示すれば、見ている人により内容が分かりやすく、楽しさも倍増します。ただ画像ファイルにはGIFやJPEGなど種類がいくつかありますので、アップロードする際にはそれぞれ画像の種類によってその処理内容を分けてやらなくてはいけません。では、以下にその手法を順を追って解説して行きましょう。
初期設定-画像のアップロード先ディレクトリ
まず最初に決めなくてはいけないのは、画像ファイルをどのディレクトリにアップするかと言う事です。僕がよく使うのは「/img」ディレクトリですが、大体スクリプト本体と同じ階層(場所)に置く事が多いです。
$up_dir = '/img/'; …画像をアップするディレクトリ名
次に「/img」ディレクトリがサーバの中の何処にあるのかを示すパスが必要になります。これは環境変数$PATH_TRANSLATEDで求める事ができるので、dirname()関数を使ってスクリプト本体のある階層(場所)を求め、それに$up_dirをつなげます。
$path = dirname($PATH_TRANSLATED).$up_dir;
尚、スーパーグローバル変数で取得する場合は以下のようになります。
$path = dirname($_SERVER["PATH_TRANSLATED"]).$up_dir;
画像送信フォーム
PHP基礎講座の「ファイルのアップロード」のページでも解説しているように、画像送信フォームの属性は「ENCTYPE="multipart/form-data"」でなくては行けません。又、変数名をupfileとすると、フォーム(例:<INPUT TYPE="file" NAME="upfile" SIZE="35">)から送信された画像ファイルの情報は、以下のような形で得られます。
$upfile サーバマシンにアップロードされたファイルが保存されているテンポラリファイル名。 $upfile_name 送信元のシステムにおける元のファイルの名前又はパス。 これも、スーパーグローバル変数で取得する場合は以下のようになります。
$upfile = $_FILES['upfile']['tmp_name'];
…「/tmp/***」のような形です。Windowsの「Temp」ディレクトリは、Linuxでは「/tmp」ディレクトリです。
$upfile_name = $_FILES['upfile']['name'];
送信された画像の属性の取得
送信された画像の種類に応じて、ログファイルに記録する画像ファイル名を区別しなくてはいけません。その為には、getimagesize()関数を使って各要素を取り出します。
getimagesize()関数 この関数は、任意のGIF、 JPG、PNG、SWF、SWC、PSD、TIFF、BMP、IFF、JP2、JPX、JB2、JPC、XBM、もしくはWBMPファイルの大きさを定義し、 ファイルの型と HTMLIMG タグ中で通常使用される高さと幅からなる寸法を表す文字列を返します。
返り値は、4つの要素からなる配列です。0番目の要素は、ピクセル単位 での画像の幅。1番目の要素は高さ。2番目の要素は画像の種類を 示すフラグです。1 = GIF、2 = JPG、3 = PNG、4 = SWF、5 = PSD、6 = BMP、7 = TIFF(intel byte order)、8 = TIFF(motorola byte order)、9 = JPC、10 = JP2、11 = JPX、12 = JB2、13 = SWC、14 = IFF、15 = WBMP、16 = XBMです。 3番目の要素はIMGタグで直接利用できる文字列 "height=xxx width=xxx" です。$imagesize = getimagesize($upfile);
とすると、$imagesize[2]の値で画像の種類が判別できますので、ログファイルに記録する画像ファイル名を以下の処理で得られます。(ここでは、扱う画像の種類を3種類に絞っています。)
switch($imagesize[2]){
case 1:
$out = $code . ".gif";
break;
case 2:
$out = $code . ".jpg";
break;
case 3:
$out = $code . ".png";
break;
default:
unlink($upfile);
}画像ファイルの移動
今の段階では、アップした画像ファイルはまだサーバの「/tmp」ディレクトリ内にあります。ではいよいよ、上記処理で得られたログ記録用ファイル名を使って、指定のディレクトリ内に画像ファイルを移動させましょう。これには、move_uploaded_file()関数を使います。
$sendpath = $path.$out; …移動先のパス及びファイル名
move_uploaded_file($upfile, $sendpath);
これでアップロードした画像ファイルが「/tmp」ディレクトリから削除されて、指定のディレクトリ内に指定のファイル名でコピーされました。
更に、アップロードした画像ファイルの属性を「666」に変更します。これは、スクリプトを通じてアップされた画像の所有者情報が、WWWサーバ・デーモン「httpd」指定のnobodyやappachになってしまうからです。属性を変更しておかないと、FTPで接続してファイルのバックアップを取ろうとしても、所有者の違いからダウンロードに失敗してしまいます。
chmod($sendpath,0666);
処理の全体像
処理の全体像を把握する為、該当部分のみを抜粋します。尚、全体的な処理の流れは、KOMONETで配布している実際のスクリプトのソースをご覧になって下さい。
//=====初期設定=======================================
$up_dir = '/img/';
//スーパーグローバル変数対策
if(!isset($PATH_TRANSLATED)){
$path = dirname($_SERVER["PATH_TRANSLATED"]).$up_dir;
}else{
$path = dirname($PATH_TRANSLATED).$up_dir;
}
if(!isset($upfile)){ $upfile = $_FILES['upfile']['tmp_name']; }
if(!isset($upfile_name)){ $upfile_name = $_FILES['upfile']['name']; }
//====================================================
//画像のアップロード処理
if(is_uploaded_file($upfile)){
$imagesize = getimagesize($upfile); //画像の属性を取得
switch($imagesize[2]){
case 1:
$out = $code . ".gif";
break;
case 2:
$out = $code . ".jpg";
break;
case 3:
$out = $code . ".png";
break;
default:
unlink($upfile);
}
if($out){
$sendpath = $path.$out;
if(move_uploaded_file($upfile, $sendpath)){
chmod($sendpath,0666);
$fname = $out;
}
}
}尚、ここで使っている処理コードは、最近少し改造したものです。従来の処理コードに比べ、より簡潔な処理になっていると思います。