CodeIgniterでファイルアップロードをマスター!安全な保存と管理方法
生徒
「CodeIgniter(コードイグナイター)を使って、ユーザーが送ってくれた画像をサーバーに保存したいのですが、どうすればいいですか?」
先生
「ファイルアップロードですね!実はそのまま保存すると、悪い人に変なファイルを送られてサイトが壊される危険があるんです。CodeIgniterの便利な機能を使って、安全に管理する方法を教えますね。」
生徒
「安全に管理…なんだか難しそうですが、私にもできますか?」
先生
「大丈夫ですよ。まずは、家(サーバー)に荷物(ファイル)が届いたときのチェックの仕方をイメージしながら、基本から一緒に見ていきましょう!」
1. ファイルアップロードの仕組みとは?
プログラミング未経験の方にとって、「ファイルをアップロードする」という言葉は少し難しく感じるかもしれません。これは簡単に言うと、あなたのパソコンにある画像や書類を、インターネット上にある「専用のコンピュータ(サーバー)」の中にコピーして保存することを指します。SNSで写真を投稿したり、メールに資料を添付したりするのも、すべてこの「アップロード」という仕組みで動いています。
PHPというプログラミング言語で作られたフレームワーク「CodeIgniter」は、このファイルを送る作業をとても簡単にしてくれます。しかし、誰でも自由にファイルを送れるようにしてしまうと、ウイルスが入ったファイルを送りつけられたり、もともとあった大切なデータを上書きされたりする恐れがあります。そのため、「名前を変えて保存する」「決まった場所以外には置かせない」といった安全管理が非常に重要になるのです。
2. フォーム作成:ファイルを送るための窓口を作ろう
まずは、ユーザーがファイルを選択するための「窓口」をHTMLで作ります。ここで一番大切なのは、formタグにenctype="multipart/form-data"という魔法の言葉を書くことです。これがないと、どんなに頑張ってもファイルは送られません。
<form action="/upload/do_upload" method="post" enctype="multipart/form-data">
<p>プロフィール画像を選んでね:</p>
<input type="file" name="userfile" size="20">
<br><br>
<button type="submit">アップロード開始!</button>
</form>
このコードにあるinput type="file"が、パソコンの中にあるファイルを選ぶボタンを表示させる命令です。name="userfile"という名前は、後でプログラムが「どのファイルのことかな?」と探すときの目印になります。
3. バリデーション:怪しいファイルを通さない関所
ファイルがサーバーに届いたら、すぐに保存してはいけません。まずは「バリデーション」というチェックを行います。バリデーションとは、「中身は本当に画像かな?」「サイズが大きすぎてパンクしないかな?」という確認作業のことです。CodeIgniterでは、あらかじめルールを決めておくだけで、自動的にこのチェックをしてくれます。
$validationRule = [
'userfile' => [
'label' => 'アップロードファイル',
'rules' => 'uploaded[userfile]'
. '|is_image[userfile]'
. '|mime_in[userfile,image/jpg,image/jpeg,image/png]'
. '|max_size[userfile,1024]',
],
];
if (! $this->validate($validationRule)) {
echo "エラーが発生しました:画像以外のファイルや、1MBより大きいものは送れません。";
}
上記のコードでは、is_imageで「画像かどうか」、max_sizeで「サイズ制限(ここでは1024KB=1MB)」を設定しています。これによって、悪意のあるプログラムファイルなどが紛れ込むのを未然に防ぐことができるのです。
4. ファイル名の安全な管理:ランダムな名前に変えよう
届いたファイルをそのままの名前で保存するのは危険です。例えば「photo.jpg」という名前のまま保存すると、別の人が同じ名前でアップロードしたときに、古い写真が消えて上書きされてしまいます。また、日本語のファイル名はサーバーによっては文字化けして読み込めなくなることもあります。
一番安全な方法は、「世界に一つだけのランダムな名前」に自動で書き換えてしまうことです。CodeIgniterのgetRandomName()という機能を使うと、誰とも被らない複雑な名前に一瞬で変えてくれます。
$file = $this->request->getFile('userfile');
if ($file->isValid() && ! $file->hasMoved()) {
// ランダムな新しい名前を作る
$newName = $file->getRandomName();
// 「uploads」というフォルダに、新しい名前で移動させる
$file->move(WRITEPATH . 'uploads', $newName);
echo "保存完了!新しい名前は:" . $newName;
}
これで、ファイル名の重複や文字化けに悩まされることはなくなります。WRITEPATHというのは、CodeIgniterが「ここに書いてもいいよ」と許可している専用の安全な保存場所を指す言葉です。
5. 保存先のフォルダ構成とセキュリティ
ファイルを保存する場所(ディレクトリ)にも工夫が必要です。ウェブサイトの仕組み上、ブラウザから直接アクセスできる場所にファイルを置くと、URLを適当に入力されただけで中身を盗み見られてしまう可能性があります。これを防ぐために、「一般公開されていない特別なフォルダ」に保存するのが基本です。
CodeIgniterでは「writable」というフォルダが用意されています。ここにはインターネットから直接アクセスできないよう鍵がかかっています。ユーザーの個人情報が含まれる書類や、会員限定の画像などは必ずこの「鍵のかかった場所」に保存するようにしましょう。もし画像を公開したい場合は、プログラムを通じて「この人には見せてもいいよ」と判断してから表示させる仕組みを作ります。これを「ストレージ管理」と呼び、大切なデータを守るための必須技術です。
6. データベースへの記録:どこに何があるかメモする
ファイルを保存しただけでは、後でそのファイルが誰のものか分からなくなってしまいます。そこで、データベースという「情報の整理棚」にメモを残します。保存するのは「ファイルそのもの」ではなく、ファイルの名前や保存された日付、アップロードした人のIDです。
$data = [
'user_id' => 123,
'file_name' => $newName, // さっき作ったランダムな名前
'file_type' => $file->getClientMimeType(),
'created_at' => date('Y-m-d H:i:s')
];
// データベースの「images」というテーブルに保存
$db = \Config\Database::connect();
$db->table('images')->insert($data);
echo "データベースに記録しました!";
このようにメモを残しておくことで、「会員番号123番さんの画像を表示して」というリクエストがあったときに、即座に正しいファイルを探し出して表示することができるようになります。実際の実行結果は以下のようになります。
保存完了!新しい名前は:1715234567_a8b9c10.png
データベースに記録しました!
7. エラーハンドリング:失敗したときのご案内
プログラミングにおいて、成功したときのことだけでなく「失敗したとき」のことを考えるのはとても大切です。ネット回線が途切れたり、サーバーの容量がいっぱいだったりすると、アップロードは失敗します。そのとき、真っ白な画面が出るのではなく「申し訳ありません、もう一度試してください」と優しく教えてあげるコードを書きましょう。
CodeIgniterでは、isValid()という命令でファイルが正しく届いたかを確認し、もしダメならgetErrorString()で「何がダメだったのか」というメッセージを受け取ることができます。これを初心者のうちから意識しておくと、ユーザーに親切な、使いやすいアプリを作れるようになります。安全で確実なファイル管理は、こうした小さな積み重ねでできているのです。