勉強したことのメモ

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

  関連記事

DTIのVPSにCodeigniter3を導入する方法

DTIのVPSにPHPフレームワークのCodeigniter3系をインストールし ...

CodeIgniter4 & jQueryを用いて同一サイト内でajax通信する方法

CodeIgniter4.4.4 & jQueryを用いて同一サイト内で ...

CodeIgniter3で共通の変数と定数を設定する方法

CodeIgniter3系で共通する配列が入った変数と、定数を設定したかった。以 ...

Codeigniter4で独自・外部ライブラリの作成と呼び出し方法

Codeigniter4で独自ライブラリを作成し、コントローラー側で呼び出したい ...

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

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