CakePHPで画像をプロジェクト内にアップロード機能を実装する方法

CakePHPで画像をプロジェクト内にアップロード機能を実装する方法

32 回閲覧されました

みなさんこんにちは、jonioです。

今回はCakePHPでプロジェクト内に画像をアップロードする方法の解説をします。

CakePHPのバージョン

4で解説しますが今回登場するメソッドは3でも使える気がするのでバージョン3でも実装できると思います。

前提

テーブル名はuploadsテーブルとします。

モデル・コントローラー・ビューはallコマンドで作成してデフォルトのコードを少し変えることで実装しています。

やりたいこと

画像のアップロードをするページで画像をアップロードして登録します。

すると画像登録用のテーブル(uploadsテーブル)のnameカラムに画像名が登録されて「CakePHPのプロジェクト > webroot > img > uploads」の下の階層に画像が登録されます。

それでは実装します。

ビュー

add.phpのコードを下記にします。

<div class="row">
    <aside class="column">
        <div class="side-nav">
            <h4 class="heading"><?= __('Actions') ?></h4>
            <?= $this->Html->link(__('List Uploads'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
        </div>
    </aside>
    <div class="column-responsive column-80">
        <div class="uploads form content">
            <?= $this->Form->create($upload, ['type' => 'file']) ?>
            <fieldset>
                <legend><?= __('Add Upload') ?></legend>
                <?php
                    echo $this->Form->file('file');
                ?>
            </fieldset>
            <?= $this->Form->button(__('Submit')) ?>
            <?= $this->Form->end() ?>
        </div>
    </div>
</div>

10行目の「[‘type’ => ‘file’]」と14行目で画像を登録できるようになります。

次はコントローラーのアクションです。

アクション

コードを下記にします。

public function add()
{
  $upload = $this->Uploads->newEmptyEntity();
  if ($this->request->is('post')) {
    $upload = $this->Uploads->patchEntity($upload, $this->request->getData());


    //ここから追加
    $uploadedFile = $this->request->getData('file');

    if (!empty($uploadedFile)) {
      $uploadedFileName = $uploadedFile->getClientFilename();

      $filePath = WWW_ROOT . 'img/uploads/' . $uploadedFileName;

      $uploadedFile->moveTo($filePath);

      $upload->name = $uploadedFileName;
    }
    //ここまで追加
    
    
    if ($this->Uploads->save($upload)) {
      $this->Flash->success(__('The upload has been saved.'));

      return $this->redirect(['action' => 'index']);
    }
    $this->Flash->error(__('The upload could not be saved. Please, try again.'));
  }
  $this->set(compact('upload'));
}

まずは画像名をuploadsテーブルのnameカラムに登録します。

画像名の登録

9行目はビューで登録した画像を受け取る為にあります。

$uploadedFileに何が入っているかを確認する為にdd関数を使います。




$uploadedFile = $this->request->getData('file');
dd($uploadedFile);


ビューで画像を登録すると下記の表示になります。

APP/Controller/UploadsController.php (line 55)
object(Laminas\Diactoros\UploadedFile) id:0 {
private error => (int) 0
private file => '/Applications/MAMP/tmp/php/phpZ9Zk3B'
private moved => false
private stream => null
private size => (int) 18068
private clientFilename => 'demo-image.png'
private clientMediaType => 'image/png'
}

8行目の「demo-image.png」が登録した画像名です。

$uploadedFileから画像名を取得するにはgetClientFilenameメソッドを使います、それが12行目です。

そして$uploadedFileNameをuploadsテーブルのnameカラムに登録するために18行目があります。

次は画像をアップロードします。

画像のアップロード

14行目はCakePHPの中のどこに画像を配置するかの設定をしてます。

「WWW_ROOT」はCakePHPプロジェクトの直下にあるwebrootのことです。

「/img/uploads」のuploads(フォルダ名)はデフォルトでは存在しないのでimgフォルダの下の階層に作成してください。

16行目で画像をアップロードしていますがmoveToメソッドを使えば実現します、引数には画像を配置するパス(14行目)を記述します。

これで画像を登録するとuploadsテーブルのnameカラムに画像名が登録されてuploadsフォルダの下の階層に画像が保存されます。