[PHP]文件上传示例(PHP → 数据库 → HTML)
将上传的图片注册到数据库并显示的示例。虽然不知道出处,但似乎有一些初学者参考书,许多初学者在将图像数据以二进制方式存储到数据库中后,在显示部分遇到困难,因此我写了一个简单保存图像路径的示例。
然而,我一直在思考为什么要将数据以二进制形式存入数据库,但也可以看出,既涉及文件上传又涉及数据库保存的文章在网络上数量较少,这可能是一个原因。
此外,我很難找到有提到刪除Exif信息的文章。現在的智能手機相機大多預設將位置信息嵌入圖像時關閉,但也有一些情況下可能不知道被打開了。為了預防從發佈的照片中識別出家庭位置等情況,請大家留意。
表格定义
CREATE TABLE `images` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(32) DEFAULT NULL,
`path` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
文件目录结构
创建一个名为upfiles的目录来保存图像,并按照以下方式进行配置。
ドキュメントルート
┣ upfile/
┣ common.php
┣ image.php
┗ index.php
公共.php
<?php
/**
* common.php
*/
/**
* connect_db
* @return \PDO
*/
function connect_db()
{
$dsn = 'mysql:host=localhost;dbname=sample;charset=utf8';
$username = 'root';
$password = 'password';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
];
return new PDO($dsn, $username, $password, $options);
}
/**
* insert
* @param string $sql
* @param array $arr
* @return int lastInsertId
*/
function insert($sql, $arr = [])
{
$pdo = connect_db();
$stmt = $pdo->prepare($sql);
$stmt->execute($arr);
return $pdo->lastInsertId();
}
/**
* select
* @param string $sql
* @param array $arr
* @return array $rows
*/
function select($sql, $arr = [])
{
$pdo = connect_db();
$stmt = $pdo->prepare($sql);
$stmt->execute($arr);
return $stmt->fetchAll();
}
/**
* htmlspecialchars
* @param string $string
* @return $string
*/
function h($string)
{
return htmlspecialchars($string, ENT_QUOTES, 'utf-8');
}
index.php -> 网页索引.php
<?php
/**
* index.php
*/
/**
* 共通関数読み込み
*/
require 'common.php';
/**
* file_upload
*/
function file_upload()
{
// POSTではないとき何もしない
if (filter_input(INPUT_SERVER, 'REQUEST_METHOD') !== 'POST') {
return;
}
// タイトル
$title = filter_input(INPUT_POST, 'title');
if ('' === $title) {
throw new Exception('タイトルは入力必須です。');
}
// アップロードファイル
$upfile = $_FILES['upfile'];
/**
* @see http://php.net/manual/ja/features.file-upload.post-method.php
*/
if ($upfile['error'] > 0) {
throw new Exception('ファイルアップロードに失敗しました。');
}
$tmp_name = $upfile['tmp_name'];
// ファイルタイプチェック
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo, $tmp_name);
// 許可するMIMETYPE
$allowed_types = [
'jpg' => 'image/jpeg'
, 'png' => 'image/png'
, 'gif' => 'image/gif'
];
if (!in_array($mimetype, $allowed_types)) {
throw new Exception('許可されていないファイルタイプです。');
}
// ファイル名(ハッシュ値でファイル名を決定するため、同一ファイルは同盟で上書きされる)
$filename = sha1_file($tmp_name);
// 拡張子
$ext = array_search($mimetype, $allowed_types);
// 保存作ファイルパス
$destination = sprintf('%s/%s.%s'
, 'upfiles'
, $filename
, $ext
);
// アップロードディレクトリに移動
if (!move_uploaded_file($tmp_name, $destination)) {
throw new Exception('ファイルの保存に失敗しました。');
}
// Exif 情報の削除
$imagick = new Imagick($destination);
$imagick->stripimage();
$imagick->writeimage($destination);
// データベースに登録
$sql = 'INSERT INTO `images` (`id`, `title`, `path`) VALUES (NULL, :title, :path) ';
$arr = [];
$arr[':title'] = $title;
$arr[':path'] = $destination;
$lastInsertId = insert($sql, $arr);
// 成功時にページを移動する
header(sprintf('Location: image.php?id=%d', $lastInsertId));
}
try {
// ファイルアップロード
file_upload();
} catch (Exception $e) {
$error = $e->getMessage();
}
?>
<!DOCTYPE HTML>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
.error {
color: red;
}
</style>
</head>
<body>
<div id="wrap">
<?php if (isset($error)) : ?>
<p class="error"><?= h($error); ?></p>
<?php endif; ?>
<form action="" method="post" enctype="multipart/form-data">
<p>
<label for="title">タイトル</label>
<input type="text" name="title" id="title" />
</p>
<p>
<label for="upfile">画像ファイル</label>
<input type="file" name="upfile" id="upfile" />
</p>
<p>
<button type="submit">送信</button>
</p>
</form>
</div>
</body>
</html>
图片.php
<?php
/**
* image.php
*/
require 'common.php';
try {
$id = filter_input(INPUT_GET, 'id');
// データベースからレコードを取得
$sql = 'SELECT `id`, `title`, `path` FROM `images` WHERE `id` = :id';
$arr = [];
$arr[':id'] = $id;
$rows = select($sql, $arr);
$row = reset($rows);
} catch (Exception $e) {
$error = $e->getMessage();
}
?>
<!DOCTYPE HTML>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
.error {
color: red;
}
</style>
</head>
<body>
<div id="wrap">
<?php if (isset($error)) : ?>
<p class="error"><?= h($error); ?></p>
<?php endif; ?>
<p><?= h($row['title']); ?></p>
<p>
<img src="<?= h($row['path']); ?>" alt="<?= h($row['title']); ?>" />
</p>
</div>
</body>
</html>