fc2ブログ

写真のチカラ

やっぱり、短時間におけるインパクトはやはり。眼は耳程に物を言う?

DSC06348

で、「どくしょのていぎ」で、先日写真アップロードを実装してみました。

PHPで画像をMySQLに入れたい。」でも書きましたけど、送信元のFORMでおまじないを唱えて。

で、サーバー側では、こんな感じの関数を呼び出して。もちろん、前もって、チェックは必要です。他人を信じられない人間の性?


function addProfilePhoto($user_id, $file_path, $validated_file_type) {
global $g_db;

$data = file_get_contents($file_path);

$sql = 'update b_user set photo=?, photo_state=?, photo_mime=? where user_id=?';

$create_date = time();

if(defined('DEBUG')) { d($sql); }
$result = $g_db->query($sql, array($data, PHOTO_CONFIRM_STATE, $validated_file_type, $user_id));
if(DB::isError($result)) {
trigger_error($result->getMessage() . '
');
}

return DB_OPERATE_SUCCESS;
}

チェック用の関数は以下。これでも100%安全、って訳じゃないですけど。一応、アップロードされたファイルなのか、サイズは規定値以内なのか、ファイルフォーマットは許可されたものなのかをチェックしてます。

function validate_profile_photo($file_path, $file_size) {
global $g_error;

$valid_flag = true;

if(!is_uploaded_file($file_path)) {
$g_error .= '不正なファイルです。';
$valid_flag = false;
}

$validated_filesize = filesize($file_path);

if($file_size != $validated_filesize) {
$g_error .= '不正なファイルです。';
$valid_flag = false;
}

if($validated_filesize > MAX_PHOTO_FILE_SIZE) {
$g_error .= 'ファイルサイズは最大' . number_format(MAX_PHOTO_FILE_SIZE) . 'バイトまでです。
';
$valid_flag = false;
}

list($width, $height, $type, $attr) = getimagesize($file_path);

if($type != 1 && $type != 2) {
$g_error .= 'ファイルタイプはGIF、JPEGのみとなっています。
';
$valid_flag = false;
}

if($type == 1) {
$validated_file_type = 'image/gif';
} else if($type == 2) {
$validated_file_type = 'image/jpeg';
} else {
$validated_file_type = '';
}

return array($valid_flag, $validated_file_type, $validated_filesize);
}

ちなみに、MySQLだったら、カラムはMEDIUMBLOB(16Mまでオッケー)にしといた方が吉かと。で、確認画面てあるじゃないですか。でも、その時点でファイルはアップロードしておかないとならないんですよね。だから、ステータス管理しないと行けない訳で。それ以外の方法あったら教えてくださいませ。素晴らしきかなサンドボックスモデル。

ここまでが、格納編。


で、参照なんですけど。こんな感じのPHPスクリプトを用意。image.phpとでもしておきます。


<?php

if(isset($_GET['mode'])) {
$mode = $_GET['mode'];
} else {
$mode = '';
}

if(isset($_GET['user_id'])) {
$user_id = $_GET['user_id'];
$user_array = getUserInformation($user_id);
} else {
exit;
}

if($user_array != NULL) {
$profile_photo = $user_array['photo'];
$profile_photo_state = $user_array['photo_state'];
$profile_photo_mime = $user_array['photo_mime'];

if($profile_photo != NULL) {

header("Content-type: $profile_photo_mime");

if($mode == 'thumbnail') {

$file_path = "image.php?user_id=$user_id";

if($profile_photo_mime == 'image/jpeg') {
$image = ImageCreateFromJPEG($file_path); //JPEGファイルを読み込む
} else if($profile_photo_mime == 'image/gif') {
$image = ImageCreateFromGIF($file_path); //GIFファイルを読み込む
} else {
exit;
}

$width = ImageSX($image); //横幅(ピクセル)
$height = ImageSY($image); //縦幅(ピクセル)

$new_width = 100;
$rate = $new_width / $width; //圧縮比
$new_height = $rate * $height;

$new_image = ImageCreateTrueColor($new_width, $new_height);
ImageCopyResized($new_image,$image,0,0,0,0,$new_width,$new_height,$width,$height);

if($profile_photo_mime == 'image/jpeg') {
ImageJPEG($new_image);
} else if($profile_photo_mime == 'image/gif') {
ImageGIF($new_image);
} else {
exit;
}

} else {
print $profile_photo;
}
}
}
?>

途中の「getUserInformation」なんて関数で、MEDIUMBLOB列を含む連想配列を取り出しています。で、$modeで、そのまま表示か、サムネイル化して表示かを切り分けています。このソースの場合は、サムネイルを事前に持たないで、動的に生成しています。それが、「ImageCreateFromJPEG」あたりで、自分自身のスクリプトを呼び出している理由なのです。オリジナルサイズの画像を読み込んで、サムネイル作って出力。なので、Webサーバには二回リクエストが飛びます。まぁ、性能はクエスチョンですが、ファイル気にしなくて済むと。

だって、サイズなんてデザインに合わせてころころ変わるんですもの。別カラムに持っていたら、参照性能は良いかもですが、運用大変、なんて、作り手の都合ですね。。

まあ、呼び出し元ではベタでHTMLでこんな書き方を。
<img src="image.php?user_id=$user_id&mode=thumbnail">

MIMEタイプはGDのgetimagesize関数で判別したものを使います。それをheader関数で指定して、画像ですよーとブラウザに教えてあげると言う訳です。
スポンサーサイト



FC2 Blog Ranking


読書の定義@2007/08/08 21:39   | 0 comments | 0 trackbacks |

コメント

コメントの投稿


秘密にする

«  | HOME |  »

いろいろ作ったり

プロフィール

icot

Author:icot
総合電気メーカで働く会社員でしたがいい年にも関わらずコンサルに転職。お酒、ジョギング、音楽、本、料理をこよなく愛してます。ここでは、日々感じた事を書き連ねるとともに、いろいろ実験してみたりしてます。
icotfeels[at]gmail.com

これまでに感じたこと