<?php
/* html特殊文字をエスケープする関数 */
function h($str) {
return htmlspecialchars($str, ENT_QUOTES, 'utf-8');
}
// xhtmlとしてブラウザに認識させる
//(ie8以下はサポート対象外)
header('Content-Type: application/xhtml+xml; charset=utf-8');
try {
// データベースに接続
$pdo = new PDO(
'mysql:host=localhost;dbname=test;charset=utf8',
'root',
'',
[
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]
);
/* アップロードがあったとき */
if (isset($_FILES['upfile']['error']) && is_int($_FILES['upfile']['error'])){
// バッファリングを開始
ob_start();
try {
// $_FILES['upfile']['error']の値を確認
switch ($_FILES['upfile']['error']){
case UPLOAD_ERR_OK: // ok
break;
case UPLOAD_ERR_NO_FILE:
throw new RuntimeException('ファイルが選択されていません', 400);
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
throw new RuntimeException('ファイルサイズが大きすぎます', 400);
default:
throw new RuntimeException('その他のエラーが発生しました', 500);
}
// $_FILES['upfile']['mime']の値はブラウザ側で偽装可能なので
// MIMEタイプを自前でチェックする
if (!$info = getimagesize($_FILES['upfile']['tmp_name'])){
throw new RuntimeException('有効な画像ファイルを指定してください', 400);
}
if (!in_array($info[2], [IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG], true)){
throw new RuntimeException('未対応の画像形式です', 400);
}
// サムネイルをバッファに出力
$create = str_replace('/', 'createfrom', $info['mime']);
$output = str_replace('/', '', $info['mime']);
if ($info[0] >= $inf0[1]){
$dst_w = 120;
$dst_h = ceil(120 * $info[1] / max($info[0], 1));
} else {
$dst_w = ceil(120 * $info[0] / max($info[1], 1));
$dst_h = 120;
}
if (!$src = @$create($_FILES['upfile']['tmp_name'])){
throw new RuntimeException('画像リソースの生成に失敗しました', 500);
}
$dst = imagecreatetruecolor($dst_w, $dst_h);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $dst_w, $dst_h, $info[0], $info[1]);
$output($dst);
imagedestroy($src);
imagedestroy($dst);
// INSERT処理
$stmt = $pdo->prepare('INSERT INTO image(name,type,raw_data,thumb_data,date) VALUES(?,?,?,?,?)');
$stmt->execute([
$_FILES['upfile']['name'],
$info[2],
file_get_contents($_FILES['upfile']['tmp_name']),
ob_get_clean(),
(new DateTime('now', new DateTimeZone('Asia/Tokyo')))->format('Y-m-d H:i:s'),
]);
$msgs[] = ['green', 'ファイルは正常にアップロードされました'];
} catch (RuntimeException $e){
while(ob_get_level()){
ob_end_clean();
}
http_response_code($e instanceof PDOException ? 500 : $e->getCode());
$msgs[] = ['red', $e->geteMessage()];
}
} elseif (isset($_GET['id'])){
try {
$stmt = $pdo->prepare('SELECT type, raw_data FROM iamge WHERE id = ? LIMIT 1');
$stmt->bindValue(1, $_GET['id'], PDO::PARAM_INT);
$stmt->execute();
if (!$row = $stmt->fetch()){
throw new RuntimeException('該当する画像は存在しません', 404);
}
header('X-Content-Type-Options: nosniff');
header('Content-Type: ' . image_type_to_mime_type($row['type']));
echo $row['raw_data'];
exit;
} catch (RuntimeException $e){
http_response_code($e instanceof PDOException ? 500 : $e->getCode());
$msgs[] = ['red', $e->getMessage()];
}
}
$rows = $pdo->query('SELECT id,name,type,thumb_data,data From image ORDER BY date DESC')->fetchAll();
} catch(PDOException $e){
http_response_code(500);
$msgs[] = ['red', $e->getMessage()];
}
?>
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>画像アップロード</title>
<style><![CDATA[
fieldset { margin: 10px; }
legend { font-size: 12px; }
img {
border: none;
float: left;
}
]]></style>
</head>
<body>
<form enctype="multipart/form-data" method="post" action="">
<fieldset>
<legend>画像ファイルを選択(GIF, JPEG, PNGのみ対応)</legend>
<input type="file" name="upfile" /><br>
<input type="submit" value="送信" />
</fieldset>
</form>
<?php if (!empty($msgs)): ?>
<fieldset>
<legend>メッセージ</legend>
<?php foreach ($msgs as $msg): ?>
<ul>
<li style="color:<?=h($msg[0])?>;"><?=h($msg[1])?></li>
</ul>
<?php endforeach; ?>
</fieldset>
<?php endif; ?>
<?php if (!empty($rows)): ?>
<fieldset>
<legend>サムネイル一覧(クリックすると原寸大表示)</legend>
<?php foreach ($rows as $i => $row): ?>
<?php if ($i): ?>
<hr />
<?php endif; ?>
<p>
<?=sprintf(
'<a href="?id=%d"><img src="data:%s;base64,%s" alt="%s" /></a>',
$row['id'],
image_type_to_mime_type($row['type']),
base64_encode($row['thumb_data']),
h($row['name'])
)?><br>
ファイル名: <?=h($row['name'])?><br />
日付: <?=h($row['date'])?><br clear="all">
</p>
<?php endforeach; ?>
</fieldset>
<?php endif; ?>
</body>
</html>