PHPでフォームの値をMySQLデータベースに格納する

前回OmniGraffleでワイヤーフレームをつくったので、しばらく(簡易)画像掲示板というか画像アップローダもどきを作ろうと思う(データベースを利用しない簡易アップローダは以前やった)。ドットインストールで画像掲示板をつくるレッスンがあり、他のも参考にさせてもらいながら作ろうかなと。今回は指定した画像をサーバーに格納するのと、フォームの値をMySQLデータベースに登録するところまで。

成果物:upload.html

やったことメモ

  • HTMLでフォームをつくった
    • 選択ボタン設置するときはinputタグのtypeを”file”にする
    • 選択はselectタグ
  • MySQLデータベースとテーブルをつくった
    • データベースとテーブルの作成はphpMyAdminを使った
    • テーブルのカラムは、ID(自動付与)、名前、投稿時間(自動付与)、ファイル名、OS(iOS/Android)、更新・削除キー、コメント、アクセス数の8つ
  • 画像をimagesディレクトリに格納してサムネイルをつくってthumbnailsディレクトリに格納した
  • HTMLフォームの値をPHPのPDO(PHP Data Objects)でデータベースに挿入した
    • PDOのコンストラクタの第1引数はデータソース名(data source name/dsn)。ホストはサーバーの管理パネルにある。
      Screen_Shot_2013-01-30_at_22.46.17
    • データベースの接続=PDOインスタンスの生成(データベースハンドラ)/切断=データベースハンドラにnull代入
    • プリペアドステートメントでデータベースに挿入した
    • IDや投稿時間などオートインクリメントや処理実施時刻を設定したものはinsert文に書かなくても値挿入される
  • データベースに値が挿入されていること、画像がフォルダにアップロードされていることを確認した
    • データベースへの値挿入はphpMyAdminで確認した
      Screen Shot 2013-01-30 at 23.48.04

ソースコード
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ごとに新着順・人気順ページを表示する

参考サイト

パーフェクトPHP (PERFECT SERIES 3)
小川 雄大 柄沢 聡太郎 橋口 誠
技術評論社
売り上げランキング: 24,082

関連エントリー

  1. 画像アップローダー(PHP)
  2. PHPのPDOでMySQLデータベースのデータを更新する2(投稿内容の変更)
  3. PHPのPDOでMySQLデータベースのデータを更新する(アクセスカウンタ)
  4. PHPのPDOでMySQLデータベースのデータを取得する2
  5. PHPのPDOでMySQLデータベースのデータを取得する
This entry was posted in 未分類 and tagged , . Bookmark the permalink.