前回OmniGraffleでワイヤーフレームをつくったので、しばらく(簡易)画像掲示板というか画像アップローダもどきを作ろうと思う(データベースを利用しない簡易アップローダは以前やった)。ドットインストールで画像掲示板をつくるレッスンがあり、他のも参考にさせてもらいながら作ろうかなと。今回は指定した画像をサーバーに格納するのと、フォームの値をMySQLデータベースに登録するところまで。
成果物:upload.html
やったことメモ
- HTMLでフォームをつくった
- 選択ボタン設置するときはinputタグのtypeを”file”にする
- 選択はselectタグ
- MySQLデータベースとテーブルをつくった
- データベースとテーブルの作成はphpMyAdminを使った
- テーブルのカラムは、ID(自動付与)、名前、投稿時間(自動付与)、ファイル名、OS(iOS/Android)、更新・削除キー、コメント、アクセス数の8つ
- 画像をimagesディレクトリに格納してサムネイルをつくってthumbnailsディレクトリに格納した
- フォームの値は、PHPの$_FILESで参照できる。
- filesize
- getimagesize
- move_uploaded_file
- imagecreatefromgif/imagecreatefromjpeg/imagecreatefrompng
- imagecreatetruecolor
- imagecopyresampled
- imagegif/imagejpeg/imagepng
- HTMLフォームの値をPHPのPDO(PHP Data Objects)でデータベースに挿入した
- PDOのコンストラクタの第1引数はデータソース名(data source name/dsn)。ホストはサーバーの管理パネルにある。

- データベースの接続=PDOインスタンスの生成(データベースハンドラ)/切断=データベースハンドラにnull代入
- プリペアドステートメントでデータベースに挿入した
- IDや投稿時間などオートインクリメントや処理実施時刻を設定したものはinsert文に書かなくても値挿入される
- データベースに値が挿入されていること、画像がフォルダにアップロードされていることを確認した
ソースコード
upload.html
<html lang="ja"> <head> <meta charset="UTF-8"> <title>スマホキャプチャーギャラリー</title> </head> <body> <a href="index.html">Home</a> | <a href="upload.html">アップロード</a> | <a href="ranking.html">人気順</a> | <a href="latest.html">新着順</a> <p>アップロード画面[upload.html]:フォーム(プレビュー欲しい)、エラーチェック(必須項目、ファイル形式、ファイルサイズ、コメント上限)</p> <form action="upload.php" method="post" enctype="multipart/form-data"> <p> <label for="">画像:<input type="file" name="image" /></label> </p> <p> <label for="">名前:<input type="text" name="name" size="40" /></label> </p> <p> <label for="">OS:<select name="os"> <option value="default">選択してください</option> <option value="iPhone">iPhone</option> <option value="Android">Android</option> </select> </label> </p> <p> <label for="">コメント:<br /><textarea id="" name="comment" rows="10" cols="30"></textarea></label> </p> <p> <label for="">編集・削除キー:<textarea id="" name="updelkey" rows="1" cols="30"></textarea></label> </p> <p> <input type="submit" value="送信" /> </p> </form> </body>
upload.php
<?php
require_once('config.php');
if ($_FILES['image']['error'] != UPLOAD_ERR_OK) {
echo 'error occured:'.$_FILES['image']['error'];
exit;
}
$size = filesize($_FILES['image']['tmp_name']);
if (!$size || $size > MAX_FILE_SIZE) {
echo 'filesize invalid: 0 or too big';
exit;
}
// *** 画像の格納 ***
$imagesize = getimagesize($_FILES['image']['tmp_name']);
switch ($imagesize['mime']) {
case 'image/gif':
$ext = '.gif';
break;
case 'image/jpeg':
$ext = '.jpg';
break;
case 'image/png':
$ext = '.png';
break;
default:
echo 'gif/jpeg/png only';
exit;
}
$imageFileName = sha1(time().mt_rand()) . $ext;
$imageFilePath = IMAGES_DIR . '/' . $imageFileName;
$rs = move_uploaded_file($_FILES['image']['tmp_name'], $imageFilePath);
if (!$rs) {
echo "could not upload";
exit;
}
// *** サムネイルの生成と格納 ***
$width = $imagesize[0];
$height = $imagesize[1];
if ($width > THUMBNAIL_WIDTH) {
switch ($imagesize['mime']) {
case 'image/gif':
$srcImage = imagecreatefromgif($imageFilePath);
break;
case 'image/jpeg':
$srcImage = imagecreatefromjpeg($imageFilePath);
break;
case 'image/png':
$srcImage = imagecreatefrompng($imageFilePath);
break;
}
$thumbHeight = round($height * THUMBNAIL_WIDTH / $width);
$thumbImage = imagecreatetruecolor(THUMBNAIL_WIDTH, $thumbHeight);
imagecopyresampled($thumbImage, $srcImage,
0, 0, // コピー先の始点(dst_x, dst_y)
0, 0, // コピー元の始点(src_x, src_y)
THUMBNAIL_WIDTH, $thumbHeight, // コピー先の幅と高さ
$width, $height); // コピー元の幅と高さ
switch ($imagesize['mime']) {
case 'image/gif':
imagegif($thumbImage, THUMBNAIL_DIR.'/'.$imageFileName);
break;
case 'image/jpeg':
imagejpeg($thumbImage, THUMBNAIL_DIR.'/'.$imageFileName);
break;
case 'image/png':
imagepng($thumbImage, THUMBNAIL_DIR.'/'.$imageFileName);
break;
}
}
// *** フォームの情報をデータベースに格納 ***
try {
$dbh = new PDO(DSN, DB_USER, DB_PASS);
} catch (PDOException $e) {
var_dump($e->getMessage());
exit;
}
$statement = $dbh->prepare("insert into mobile_capture_showcase (name,filename,os,updelkey,comment,counter) values (:name,:filename,:os,:updelkey,:comment,0)");
$statement->bindParam(":name", $_POST['name']);
$statement->bindParam(":filename", $imageFileName);
$statement->bindParam(":os", $_POST['os']);
$statement->bindParam(":updelkey", $_POST['updelkey']);
$statement->bindParam(":comment", $_POST['comment']);
$statement->execute();
$dbh = null;
// *** ホームに戻る ***
header('Location: http://' . $_SERVER['SERVER_NAME'] . '/study/uploader/mobile_capture_showcase/index.html');
exit;
?>
config.php
<?php
define('DSN', 'mysql:host=xxxxx;dbname=xxxxx;');
define('DB_USER', 'xxxxxxxxxxx');
define('DB_PASS', 'xxxxxxxxxxx');
define('IMAGES_DIR', dirname($_SERVER['SCRIPT_FILENAME']).'/images');
define('THUMBNAIL_DIR', dirname($_SERVER['SCRIPT_FILENAME']).'/thumbnails');
define('THUMBNAIL_WIDTH', 160);
define('MAX_FILE_SIZE', 819200); // 800KB(800*1024)
error_reporting(E_ALL & ~E_NOTICE);
if (!function_exists('imagecreatetruecolor')) {
echo "GDがインストールされていません";
exit;
}
?>
次回以降にやろうと思っていること
- エラーチェックをする(必須項目、ファイル形式、ファイルサイズ、コメント上限)
- トップページに画像一覧を表示する
- トップページの画像クリックで個別ページに遷移させる
- 投稿時間の降順で新着順ページを表示する(表示方法はトップページのを流用できるはず)
- 個別ページヘのアクセスをカウントする
- アクセス数の降順で人気順ページを表示する(表示方法は新着順ページのを流用できるはず)
- 個別ページに編集リンクを用意&データ編集できるようにする
- 個別ページに削除リンクを用意&データ削除できるようにする
- CSSフレームワーク(Twitter Bootstrap)を適用する
以上でベースができるはずで、さらに追加したいこと
- アップロードフォームに画像プレビューを設置する
- ページング機能を新着順、人気順ページに設置する
- トップページと個別ページにソーシャルボタンを設置する
- OSごとに新着順・人気順ページを表示する
参考サイト
- HTML5リファレンス
- PHPの基礎(応用編) (全12回) – ドットインストール
- PHP: PDO – Manual
- PHPで作る「画像掲示板」 (全18回) – ドットインストール
- お問合せ管理システムを作ろう (全21回) – ドットインストール
- PHP/jQueryで作るToDoアプリ (全20回) – ドットインストール
- PHPで作る「ページング機能」 (全10回) – ドットインストール
パーフェクトPHP (PERFECT SERIES 3)
posted with amazlet at 13.01.30
小川 雄大 柄沢 聡太郎 橋口 誠
技術評論社
売り上げランキング: 24,082
技術評論社
売り上げランキング: 24,082
関連エントリー
