勉強したことのメモ

Webエンジニア / プログラマが勉強したことのメモ。

CodeIgniter4でフォームからファイルをアップロードし保存する方法

   2024/01/12  PHP CodeIgniter

CodeIgniter4.4.4でformから画像等のファイルをアップロードし、当該ファイルはサーバ側に保存させたい。また、正常にアップロードできた場合は当該ファイルをページ上で表示させたい。以下に対応方法のメモ。

 

ルーティング設定

/app/Config/Routes.php

#ファイルアップロードテスト
$routes->add('/file_upload_test', 'FileUploadTest::index');
$routes->add('/file_upload_test/upload', 'FileUploadTest::upload');

 

ファイルの保存場所(アップロード先)

「/public/file_upload_test_dir」というディレクトリにした。正常にアップロードできない場合はパーミッションを777等に変更すること。

 

Views

/app/Views/file_upload_test/index.php

<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ファイルアップロードのテスト</title>
</head>
<body>
    <?php if( session()->has('msg') ){ //メッセージがある場合は出力?>
        <?php echo session()->getFlashdata('msg');?>
    <?php } ?>

    <?php if( session()->has('img') ){ //画像がアップロードされた場合は表示?>
        <img src="<?php echo session()->getFlashdata('img');?>">
    <?php } ?>

    <?php echo form_open_multipart('file_upload_test/upload');?>
        <input type="file" name="img">
        <input type="submit" value="upload">
    <?php echo form_close();?>
</form>
</body>
</html>

「session()->getFlashdata」の部分はセッションライブラリフラッシュデータを参照。フラッシュデータにメッセージや画像のURLが保存されている場合は表示させている。

 

Controllers

/app/Controllers/FileUploadTest.php

<?php
namespace App\Controllers;

class FileUploadTest extends BaseController
{

    //コンストラクタ
    public function __construct()
    {
        helper(['form']);
    }

    //ファイル選択ページ
    public function index()
    {
        echo view('/file_upload_test/index');
    }

    //アップロード処理
    public function upload()
    {

        //ファイルが送られてきた場合
        if( $file = $this->request->getFile('img') ){

            //HTTP経由でエラーなくアップロードされたことを確認
            if( $file->isValid() ){

                //ランダムな名前に変更
                $new_name = $file->getRandomName();

                //ファイルを移動できた場合
                if( $file->move(FCPATH . 'file_upload_test_dir', $new_name) ){

                    //セッションにファイル名とメッセージをセット
                    session()->setFlashdata('img', base_url() . 'file_upload_test_dir/' . $new_name);
                    session()->setFlashdata('msg', 'アップロードに成功しました。');
                }else{
                    session()->setFlashdata('msg', 'アップロードに失敗しました。');
                }
            }

        }else{
            session()->setFlashdata('msg', 'ファイルが送信されていません。');
        }

        //ファイル選択ページにリダイレクト
        return redirect()->to('/file_upload_test');
    }
}

画像処理関連はこちらのリファレンスを参照。また画像保存時の「FCPATH」は定数になりpublicディレクトリを返してくれる。

 

注意点

バリデート処理

最低限のアップロード処理機能となるため実運用の際はフロント側及びサーバ側で以下のような処理を入れる必要あり。

  • サイズ上限のチェック(10MBまで等)
  • 拡張子のチェック(画像以外の拡張子時はエラー等)

ファイルの保存場所に注意

最初は保存先をviews側にしようかと思ったけどプレビューさせることを考えるとpublicにする必要があった(アップロード自体はviews側でも可能)。

また、public側でルーティング設定と同じく「file_upload_test」フォルダにしたところ、ルーティング設定が正常に動作せず「file_upload_test」ディレクトリがそのまま開かれてしまったため「file_upload_test_dir」に修正した。ポカミスだけど気を付けていないと同じ事をしてしまいそうなので注意する。

 

参考サイト

http://blog.livedoor.jp/nnmy/archives/55105384.html

 - PHP CodeIgniter

  関連記事

CodeIgniter4でCronを実行する方法

CodeIgniter4.4.4で特定の処理をCronで自動実行させたい。以下に ...

CodeIgniterのバージョンの調べ方

CodeIgniterを使っているシステムがあったが、どうも記憶しているディレク ...

Codeigniter3で異なるデータベースを使用する

Codeigniterで2つのコンテンツがあって、それぞれ別のデータベースを使用 ...

Codeigniter3で外部ファイル(CSS / JS)の読み込みと共通パーツ化する方法

CodeigniterでCSSやJSファイル等の外部ファイル読み込みたかった。ま ...

Codeigniter4でMySQLに接続しCRUD操作する方法

Codeigniter4.4.4でMySQLに接続しCRUD操作したい。また、任 ...