PHPの画像アップロードが任意のフォームで、
・新規画像アップロード
・上書き画像アップロード
・画像削除
の編集しDBにファイル名を保存する機能がある。
画像アップロードあった場合に、画像のサイズを取得し、縦横どちらかが基準値により大きい場合、比率を保ったまま縮小する。
もくじ
php関連記事
PHPのmb_send_mailでメール送信時に、はしご高「髙」やたつさき「﨑」など旧漢字や丸数字の日本語文字化け対策をする
MySQL/MariaDBのデータをPHP側で暗号化・復号する
phpで10進数と16進数、2進数、8進数の変換と0埋め表記
WordPressの条件分岐タグでページを判別する
PHPでpreg_splitの文字化けを回避しながらテキストを改行ごとに区切ってHTMLメールをつくる
WordPressテーマアップロード時に「辿ったリンクは期限が切れています。 もう一度お試しください。」と表示される
PHPで画像アップロード時に比率を保ったまま縮小する
phpで郵便番号を正規表現で3桁・ハイフン・4桁で出力するfunction
phpで電話番号のハイフンを正規表現で出力するfunction
フォームのHTML
HTML
<form action="" method="post" enctype="multipart/form-data"> <div class="form-group"> <label for="image">画像</label> <input type="file" name="image" id="image" accept=".jpg,.gif,.png,image/gif,image/jpeg,image/png"> <div>ファイルサイズ10MB以内</div> <div id="already" style="display: none;"> <img id="preview"> <a href="javascript:void(0)" id="imagedel"> <img src="/img/icon/batu.jpg"> </a> </div> <canvas id="trimed_image" style="display: none;"></canvas> <input type="hidden" name="" id="imagedel_send" value="del"> <button type="submit">投稿する</button> </div> </form>
formタグには、ファイルアップロードがあるので、enctype="multipart/form-data"
をつけます。ファイルアップロードがある場合は、これを付けないとファイルの送信ができません。
input type="file"
には、accept=".jpg,.gif,.png,image/gif,image/jpeg,image/png"
をつけています。
ユーザーが選択できるファイル形式を、あらかじめ選択しておくことができます。
img id="preview"
は、既存の画像がある場合の表示と、canvas id="trimed_image"
アップロードされたファイルのプレビュー用です。
id="imagedel"
は、既存の画像がある場合に表示される、画像削除用ボタンです。
aタグのjavascript:void(0)
については、下記で確認してください。

画像アップロード時にプレビューを表示する
jQueryで画像アップロード時にプレビューを表示する詳細は、下記を参照してください。

is_uploaded_fileで、アップロードがあったかの判別する
php
if (is_uploaded_file($_FILES['image']['tmp_name'])) { //アップロードがあった処理 }elseif(isset($_POST["img_d"])){ //画像削除があった処理 }else{ //アップロードがなかった処理 }
is_uploaded_file
で、アップロードがあったかの判別します。
あった場合は、アップロードされた画像が最優先で利用されます。
アップロードがなく、画像の削除ボタンが押されたときは、DBの更新やファイルの削除処理なんかをしていきます。
アップロードファイルが正しいかチェックする
php
if(!isset($_FILES['image']['error']) || !is_int($_FILES['image']['error'])){ throw new ErrorException('パラメータが不正です'); } // $_FILES['image']['error'] の値を確認 switch ($_FILES['image']['error']) { case UPLOAD_ERR_OK: // OK break; case UPLOAD_ERR_NO_FILE: // ファイル未選択 throw new ErrorException('ファイルが選択されていません'); case UPLOAD_ERR_INI_SIZE: // php.ini定義の最大サイズ超過 case UPLOAD_ERR_FORM_SIZE: // フォーム定義の最大サイズ超過 (設定した場合のみ) throw new ErrorException('ファイルサイズが大きすぎます'); default: throw new ErrorException('その他のエラーが発生しました'); }
$_FILES['image']['error']
のerrorの値を調べて、アップロードファイルが正しいかチェックします。
ファイルサイズの大きさをチェックする
php
if ($_FILES['image']['size'] > 10485760) { throw new ErrorException('ファイルサイズが大きすぎます'); }
$_FILES['image']['size']
の値を調べて、アップロードファイルのサイズが問題ないかをチェックします。
MIMEタイプに対応する拡張子をチェックする
php
if (!$ext = array_search( mime_content_type($_FILES['image']['tmp_name']), array( 'gif' => 'image/gif', 'jpg' => 'image/jpeg', 'png' => 'image/png', ), true )) { throw new ErrorException('ファイル形式が不正です'); }
mime_content_type
でアップロードされたファイルのMIMEタイプをチェックします。
今回は画像のアップロードなので、このくらいで問題ないと思います。
アップロードされた画像のファイル名を変更する
php
$rename_org = TALK_PFX.$insct_id."-".$local_id; $rename_org = $rename_org.".".$ext; if (!move_uploaded_file( $_FILES['image']['tmp_name'], "./".UP_PATH_TALK.$rename_org ) ) { throw new ErrorException('ファイル保存時にエラーが発生しました'); } $fileimagename = $rename_org; // ファイルのパーミッションを確実に0644に設定する chmod("./".UP_PATH_TALK.$rename_org, 0644);
$rename_org
であらかじめファイルの命名規則を作成しておき、チェックした拡張子を、合わせます。
アップロードされたファイル名はそのまま使わないようにしましょう。
その後、move_uploaded_file
で、ファイルをコピーします。
さらに、そのファイルのパーミッションを0644に変更します。自分は読み書き、他の人は読み込みのみ可能な状態にします。
画像の縦横のサイズを取得して縮小後のサイズを計算するfunction
php
function ratio($w, $h){ $newwidth = 0; // 新しい横幅 $newheight = 0; // 新しい縦幅 $res_w = 800; // 最大横幅 $res_h = 800; // 最大縦幅 if ($w > $h) { // 横長の画像は横のサイズを指定値にあわせる $ratio = $h / $w; $newwidth = $res_w; $newheight = $res_w * $ratio; } else { // 縦長の画像は縦のサイズを指定値にあわせる $ratio = $w / $h; $newwidth = $res_h * $ratio; $newheight = $res_h; } $rtn_wh = [ 'width' => $newwidth, 'height' => $newheight, ]; return $rtn_wh; }
縦横どちらか大きい方の辺に合わせて、反対の辺を縮小した際の比率を計算します。
画像をリサイズするfunction
php
function img_resize($url, $res_w, $res_h, $p_w, $p_h, $x, $y, $picturename){ list($w, $h, $type) = getimagesize($url); switch($type){ case IMAGETYPE_JPEG: $in = imagecreatefromjpeg($url); break; case IMAGETYPE_GIF: $in = imagecreatefromgif($url); break; case IMAGETYPE_PNG: $in = imagecreatefrompng($url); break; } // コピー画像のリソース $out = imagecreatetruecolor($res_w, $res_h); imagealphablending($out, false); imagesavealpha($out, true); // リサイズ ImageCopyResampled($out, $in, 0, 0, $x, $y, $res_w, $res_h, $p_w, $p_h); imagepng($out, UP_PATH_TALK.$picturename); imagedestroy($out); imagedestroy($in); }
ratio
関数で、取得した比率を元に画像を縮小するfunctionです。
ここでも拡張子をチェックします。
画像の縦横のサイズを取得してリサイズする
php
list($wid, $hei, $type) = getimagesize("./".UP_PATH_TALK.$rename_org); if($wid >= 800 || $hei >= 800){ $wh = ratio($wid, $hei); img_resize( "./".UP_PATH_TALK.$rename_org, $wh['width'], $wh['height'], $wid, $hei, 0, 0, $rename_org); } $image_change = true;
画像の縦横サイズを取得してから、必要ならratio
関数と、img_resize
関数を使って、辺の最大値より大きい場合に、画像をリサイズします。
リサイズをしてもしなくても、DBは更新するので$image_change
をtrueにします。
画像の削除をする場合
php
elseif(isset($_POST["img_d"])){ $fileimagename = ""; $image_change = true; }
$fileimagename
がDBに入れるファイル名で値をブランクにし、DBは更新するので、$image_change
をtrueにします。
最終的なコード
HTML
//アップロードがあった if (is_uploaded_file($_FILES['image']['tmp_name'])) { $rename_org = TALK_PFX.$insct_id."-".$local_id; if(!isset($_FILES['image']['error']) || !is_int($_FILES['image']['error'])){ throw new ErrorException('パラメータが不正です'); } // $_FILES['image']['error'] の値を確認 switch ($_FILES['image']['error']) { case UPLOAD_ERR_OK: // OK break; case UPLOAD_ERR_NO_FILE: // ファイル未選択 throw new ErrorException('ファイルが選択されていません'); case UPLOAD_ERR_INI_SIZE: // php.ini定義の最大サイズ超過 case UPLOAD_ERR_FORM_SIZE: // フォーム定義の最大サイズ超過 (設定した場合のみ) throw new ErrorException('ファイルサイズが大きすぎます'); default: throw new ErrorException('その他のエラーが発生しました'); } // ここで定義するサイズ上限のオーバーチェック if ($_FILES['image']['size'] > 10485760) {// throw new ErrorException('ファイルサイズが大きすぎます'); } if (!$ext = array_search( mime_content_type($_FILES['image']['tmp_name']), array( 'gif' => 'image/gif', 'jpg' => 'image/jpeg', 'png' => 'image/png', ), true )) { throw new ErrorException('ファイル形式が不正です'); } $rename_org = $rename_org.".".$ext; if (!move_uploaded_file( $_FILES['image']['tmp_name'], "./".UP_PATH_TALK.$rename_org ) ) { throw new ErrorException('ファイル保存時にエラーが発生しました'); } $fileimagename = $rename_org; // ファイルのパーミッションを確実に0644に設定する chmod("./".UP_PATH_TALK.$rename_org, 0644); list($wid, $hei, $type) = getimagesize("./".UP_PATH_TALK.$rename_org); if($wid >= 800 || $hei >= 800){ $wh = ratio($wid, $hei); img_resize( "./".UP_PATH_TALK.$rename_org, $wh['width'], $wh['height'], $wid, $hei, 0, 0, $rename_org); } $image_change = true; }elseif(isset($_POST["img_d"])){ $fileimagename = ""; $image_change = true; }else{ $fileimagename = ""; }
検証中のため、漏れ等あるかもしれませんので、ご注意ください。
コメント