前期第11回 - oddmutou/jugyo-2026kyototech GitHub Wiki
画像アップロード機能の実装
前回作った掲示板に画像アップロード機能を追加してみましょう。
今現在一般的に、オンプレ環境を持たない会社がサービスを立ち上げる際はパブリッククラウドのオブジェクトストレージサービス(AWS S3とか、Azure Blob Storageとか。)を使うことが多いです。
今回は初歩的な学習のため、サーバー(EC2インスタンス)内に画像ファイルを保存するやり方で実装してみましょう。
画像アップロード場所の準備、ミドルウェアの設定
まず、PHPの実行ユーザーが書き込む権限を持つディレクトリを作成します。今回は /var/www/upload/image/ としてみています。Dockerfileに以下の行を追記してください。
RUN install -o www-data -g www-data -d /var/www/upload/image/
次に、画像を保存するディレクトリをコンテナのライフサイクルとは異なるものとしたいため(MySQLのデータの永続化と同様です。)、compose.yml にて volumes で定義し、webコンテナとPHPコンテナに /var/www/upload/image/ として割り当てましょう。
こんなかんじ: https://github.com/oddmutou/jugyo-2026kyototech/blob/20a825d0cdf6a8b4e3ec887c602e29269e658e70/zenki_11/compose.yml (9行目、19行目、36行目が今回追記した行です。)
次に、webコンテナ内の /var/www/upload/image/ を、nginxが、インターネットに対して /image/ として配信するように、nginxの設定ファイル nginx/conf.d/default.conf を編集しましょう。
こんなかんじ: https://github.com/oddmutou/jugyo-2026kyototech/blob/530916a6bd5e17f0dd604f318dbc9a43136f8a9c/zenki_11/nginx/conf.d/default.conf (15~17行目が今回追記した行です。)
画像アップロードのアプリケーション実装
今回は掲示板に画像投稿機能を追加します。
データベースの掲示板用テーブルに画像を保存するパスを入れておくカラムを追加しましょう。
クエリはこんなかんじ
ALTER TABLE `bbs_entries` ADD COLUMN image_filename TEXT DEFAULT NULL;
最後にPHPのプログラムを実装します。仮に、 public/bbsimagetest.php として作成します。
http://EC2インスタンスのIPアドレス/bbsimagetest.php にブラウザからアクセスして動作を確認してみましょう。
※ デフォルトの設定では1MB以下のファイルしか投稿できないため、動作確認時は注意してください。
演習
今回の演習は上記 bbsimagetest.php を改修する形で行います。
動作例: http://3.88.128.76/bbsimagetest.php
演習1
いまのところ、リクエスト内のファイルタイプを見てチェックしています。悪意のある利用者が、サーバーを簡単に騙せてしまいます。
mime_content_type() を使って、ファイルの内容を見て種類をサーバー側でチェックして、画像以外であれば弾く処理を実装しましょう。
実装例: https://github.com/oddmutou/jugyo-2026kyototech/commit/65e7b17e644c47a4b86133039f815efc310e9ca6
演習2
前述の通り、nginxやphpの設定を追加しないと、1MBを超えるような大きい画像ファイルをアップロードすることができません。
設定を書き換えて、最大5MBまでの画像をアップロードできるようにしてみましょう。
実装例: https://github.com/oddmutou/jugyo-2026kyototech/commit/5f90596d681491c66fe8705c2c43384ae9d84839
演習3
演習2の続きです。ブラウザでファイルを選択したときにファイルの中身をブラウザ側(JavaScript)でチェックして、5MB以上であればアラートを出し、ファイルの選択を強制解除するようにしてみましょう。
大きい画像ファイルが手元になければ、フリー素材 (例: イメージズラボさま https://imageslabo.com/photo/2082 ) を利用して動作チェックをしてみましょう。
実装例: https://github.com/oddmutou/jugyo-2026kyototech/commit/2279bcfc94de77a47147bc1a20973d9c1c1dd505