画像関連

【PHP・MySQL】データベースに画像を保存・表示する方法 第7回「ファイルサイズのチェック」

Sara

 
ここまでの記事はこちら

サイズが大きすぎる画像を保存できてしまうと、サーバーに負担がかかってしまいます。

前回の形式チェックと同じように画像ファイルのサイズチェックも入れておきましょう。

ファイルのサイズチェックを入れる方法

第6回「形式チェック」が完了している状態から始めます。

今回は 1MB までのファイルでチェックを入れてみましょう。

前回形式チェックを入れた箇所にコードを追加します。(10~14行目)

<?php
/* 省略 */
if (!empty($_FILES['image']['name'])) {
$name = $_FILES['image']['name'];
$type = $_FILES['image']['type'];
$content = file_get_contents($_FILES['image']['tmp_name']);
$size = $_FILES['image']['size'];
// 画像のサイズ・形式チェック
$maxFileSize = 1048576;
$validFileTypes = ['image/png', 'image/jpeg'];
if ($size > $maxFileSize || !in_array($type, $validFileTypes)) {
$err_msg = '* jpg, jpeg, png 形式で 1 MB までの画像を選択してください。';
}
if ($err_msg == '') {
view raw list.php hosted with ❤ by GitHub

10行目

$maxFileSize = 1048576;

$_FILES[‘image’][‘size’]; で取得した画像サイズの単位は Byte(バイト)です。

1 MB = 1024 KB = 1048576 Byte

なので $maxFileSize = 1048576; としています。 

12行目

if ($size > $maxFileSize || !in_array($type, $validFileTypes)) {

形式チェックと一緒にサイズの判定も入れています。

「画像サイズが $maxFileSize を超えている」または「形式が $validFileTypes に含まれていない」場合にエラーメッセージを表示します。

コードの修正

エラーメッセージを表示すると、左側に表示されるはずの登録済み画像が消えてしまいます。

登録済みの画像が常に表示されるようにコードを修正します。(1~13行目)

<?php
require_once('functions.php');
$pdo = connectDB();
$err_msg = '';
// 画像を取得
$sql = 'SELECT * FROM images ORDER BY created_at DESC';
$stmt = $pdo->prepare($sql);
$stmt->execute();
$images = $stmt->fetchAll();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// 画像を保存
if (!empty($_FILES['image']['name'])) {
$name = $_FILES['image']['name'];
$type = $_FILES['image']['type'];
view raw list.php hosted with ❤ by GitHub

完成

以下のように動いていれば完成です。

ここまでのコード

Q
list.php
<?php
require_once('functions.php');
$pdo = connectDB();
$err_msg = '';
// 画像を取得
$sql = 'SELECT * FROM images ORDER BY created_at DESC';
$stmt = $pdo->prepare($sql);
$stmt->execute();
$images = $stmt->fetchAll();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// 画像を保存
if (!empty($_FILES['image']['name'])) {
$name = $_FILES['image']['name'];
$type = $_FILES['image']['type'];
$content = file_get_contents($_FILES['image']['tmp_name']);
$size = $_FILES['image']['size'];
// 画像のサイズ・形式チェック
$maxFileSize = 1048576;
$validFileTypes = ['image/png', 'image/jpeg'];
if ($size > $maxFileSize || !in_array($type, $validFileTypes)) {
$err_msg = '* jpg, jpeg, png 形式で 1 MB までの画像を選択してください。';
}
if ($err_msg == '') {
$sql = 'INSERT INTO images(image_name, image_type, image_content, image_size, created_at)
VALUES (:image_name, :image_type, :image_content, :image_size, now())';
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':image_name', $name, PDO::PARAM_STR);
$stmt->bindValue(':image_type', $type, PDO::PARAM_STR);
$stmt->bindValue(':image_content', $content, PDO::PARAM_STR);
$stmt->bindValue(':image_size', $size, PDO::PARAM_INT);
$stmt->execute();
header('Location:list.php');
exit();
}
}
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Image Test</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
</head>
<body>
<div class="container mt-5">
<div class="row">
<div class="col-md-8 border-right">
<ul class="list-unstyled">
<?php for($i = 0; $i < count($images); $i++): ?>
<li class="media mt-5">
<a href="#lightbox" data-toggle="modal" data-slide-to="<?= $i; ?>">
<img src="image.php?id=<?= $images[$i]['image_id']; ?>" width="100" height="auto" class="mr-3">
</a>
<div class="media-body">
<h5><?= $images[$i]['image_name']; ?> (<?= number_format($images[$i]['image_size']/1000, 2); ?> KB)</h5>
<a href="javascript:void(0);" onclick="var ok = confirm('削除しますか?'); if (ok) location.href='delete.php?id=<?= $images[$i]['image_id']; ?>'"><i class="far fa-trash-alt"></i> 削除</a>
</div>
</li>
<?php endfor; ?>
</ul>
</div>
<div class="col-md-4 pt-4 pl-4">
<form method="post" enctype="multipart/form-data">
<div class="form-group">
<label>画像を選択</label>
<input type="file" name="image" accept=".jpg,.jpeg,.png" required>
<?php if ($err_msg != ''): ?>
<div class="invalid-feedback d-block"><?= $err_msg; ?></div>
<?php endif; ?>
</div>
<button type="submit" class="btn btn-primary">保存</button>
</form>
</div>
</div>
</div>
<div class="modal carousel slide" id="lightbox" tabindex="-1" role="dialog" data-ride="carousel">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-body">
<ol class="carousel-indicators">
<?php for ($i = 0; $i < count($images); $i++): ?>
<li data-target="#lightbox" data-slide-to="<?= $i; ?>" <?php if ($i == 0) echo 'class="active"'; ?>></li>
<?php endfor; ?>
</ol>
<div class="carousel-inner">
<?php for ($i = 0; $i < count($images); $i++): ?>
<div class="carousel-item <?php if ($i == 0) echo 'active'; ?>">
<img src="image.php?id=<?= $images[$i]['image_id']; ?>" class="d-block w-100">
</div>
<?php endfor; ?>
</div>
<a class="carousel-control-prev" href="#lightbox" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#lightbox" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
view raw list.php hosted with ❤ by GitHub

COMMENT

Subscribe
必ずお読みください!

投稿いただいたコメントは管理者の承認後に表示されます。

コードやエラーに関するご質問の場合は、以下の3点

  1. 開発環境(OS / ブラウザ / MAMP 6.6 / Android Studio Chipmunk など)
  2. エラーメッセージ
  3. お試しになったこと

できるだけ具体的に必ず書いてください。

Notify of


4 Comments
古い順
新しい順 人気順
Inline Feedbacks
View all comments
ABOUT ME
Sara
Sara
運営者
書籍やオンライン講座でプログラミングを勉強してフリーランスのプログラマーになりました。
このサイトでは「わかりやすく・シンプル」をモットーに、プログラミングの基礎からアプリ開発まで紹介します。
独学でプログラミングを勉強をしている方、基礎は勉強したけれど次に何をすれば良いか分からない...という方のお役に立てるサイトを目指しています。
主な使用言語:Java / Kotlin / PHP
>> 詳しいプロフィール
>> お問い合わせ
>> 書籍を出版しました!
本格的に学びたい方へ

Code for Fun プログラミング講座

POINT 01

動くコード

プログラミングの文法を学んでも、そこからどのようにアプリ開発ができるのかイメージが湧きにくいものです。

Code for Fun のプログラミング講座では、ゲームやカレンダーなどアプリとして機能するものを作りながらプログラミングを学ぶことができます。

POINT 02

自分のペースで

オンライン講座なので、ご自身のペースで学習を進めて頂けます。

受講期限もないので、いつでも前のレッスンに戻ることができるので安心です。

お申し込みしたその日からすぐに始めることができます。

POINT 03

個別サポート

プログラミング学習では、エラーが起きることはよくあります。そんな時はお気軽にお問い合わせください!

コメント欄またはメールによるサポートを回数無制限でご利用頂けます。(*講座に関連するご質問のみ対応)

今すぐ無料でお試し

4
0
この記事にコメントするx
記事URLをコピーしました