CloudinaryをLaravelで使いたい

# きっかけ
Laravelで開発したアプリケーションをHerokuでデプロイしたが、Herokuの仕様上画像を保持するのが難しく、クラウド上にアップロードするようにしたかった。
（なお、Base64の形式に画像を変換すれば、Heroku上でも保存・管理が可能なのだが、容量が大きくなるため、クラウドで画像の管理をするのが一般的なよう。）

# 内容
Cloudinaryなら、通年無料で使える容量も申し分なかったため、今回はCloudinaryを使用する。（2024年12月時点）
アプリから、Cloudinaryに画像をアップロード、Cloudinary上のURLを取得して、画像を表示させる。

# 調べたこと
https://tedask.jp/laravel/laravel-and-cloudinary/

こちらのサイトさんを参考にしつつ、環境を構築した。
おおむねこのサイトの手順通りだったが、一部異なる部分があったため、ここにまとめる。

### １）Cloudinaryに登録
https://cloudinary.com/
登録後は、API KEYを開いておくと便利。
![Group 20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3958920/2a0089d8-ea39-978b-7f03-76ebace0a20d.jpeg)
View API Keyを押すと、このようなポップアップが出てくる。
![Group 21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3958920/d90c0b9e-6cf9-1695-8cbe-506e87b1d646.jpeg)
このAPI environment variableが、のちに必要となる。

### ２）Laravel用のコンポーザーをインストール
Laravel用のCloudinaryのコンポーザーが用意されているようだ。↓
https://github.com/cloudinary-community/cloudinary-laravel?tab=readme-ov-file#installation
こちらのInstallに従って、準備していく。

まずはターミナルから、コンポーザーをインストール。
```
composer require cloudinary-labs/cloudinary-laravel
```
次にconfigファイルを作成。
```
php artisan vendor:publish --provider="CloudinaryLabs\CloudinaryLaravel\CloudinaryServiceProvider" --tag="cloudinary-laravel-config"
```
.envファイルに、以下を追加。
```
CLOUDINARY_URL=cloudinary://API_KEY:API_SECRET@CLOUD_NAME
CLOUDINARY_UPLOAD_PRESET=（任意）
CLOUDINARY_NOTIFICATION_URL=（任意）
```
Cloudinary登録後に表示した、API KeyのAPI environment variableを、CLOUDINARY_URL=に貼り付ける。

### ３）ControllerやView、Routeを設定
```php
// コントローラー（ItemCotroller.php）

/**
 * 商品一覧
 */
public function index(){
    $items = Item::all();

    return view('index', compact('items'));
}

/**
 * アイテムアップロード
 */
public function store(Request $request){
    // アップロード
    $uploadedFileUrl = cloudinary()->upload($request->file('file')->getRealPath())->getSecurePath();
    
    // アップロード時にフォルダ指定や変換したい場合
    $uploadedFileUrl = cloudinary()->upload($request->file('file')->getRealPath(), [
        'folder' => 'uploads',
        'transformation' => [
            'width' => 400,
            'height' => 400,
            'crop' => 'fill'
        ]
    ])->getSecurePath();

        // アップロードした内容を保存
        Item::create([
            'title' => $request->title,
            'iamge' => $uploadedFileUrl,
        ]);

    return redirect('/index');
}

```

```html
// ビュー（index.balde.php）

<!-- アイテムアップロード -->
<form action="{{ url('/store') }}" method="POST" enctype="multipart/form-data">
        {{ csrf_field() }}

        <!-- アイテム名 -->
         <div class="form-group">
            <label for="item-name" class="col-sm-3 control-label">アイテム</label>
            <div class="col-sm-6">
                <input type="text" name="name" class="form-control">
            </div>
        <!-- 画像追加 -->
            <input type="file" name="image">
         </div>
         
         <!-- タスク追加ボタン -->
        <div class="form-group">
            <div class="col-sm-offset-3 col-sm-6">
                <button type="submit" class="btn btn-primary">
                    アップロード
                </button>
            </div>
        </div>
    </form>



<!-- アイテム一覧-->
<table class="table">
    <!-- テーブルヘッダ -->
    <thead>
        <th>タイトル</th>
        <th>画像</th>
    </thead>

    <!-- テーブル本体 -->
    <tbody>
        @foreach ($items as $item)
        <tr>
            <!-- アイテム名 -->
            <td class="table-text">
                <div>{{ $item->title }}</div>
            </td>
            <!-- 画像 -->
            @if($item->image != null)
            <td>
                <img src="{{$item->image}}" alt="アイテム画像" style="width: 100px; height: 100px;">
            </td>
            @endif
        </tr>
        @endforeach
    </tbody>
</table>
```
```php
// ルーティング（web.php）

 Route::get('/index', [App\Http\Controllers\ItemController::class, 'index']);
 Route::post('/store', [App\Http\Controllers\ItemController::class, 'store']);

```


# さいごに
これで、Lravelで、Cloudinaryにアップロードができるようになりました！


こちらの投稿は、素人ほぼ独学プロウラマーのメモ書き投稿のため、参考程度にご活用ください。
また、質問やアドバイスなどコメントいただけますと、大変ありがたいです。