こんにちは。
テダスクのToshiです。
今回はLaravel8+Cloudinaryで画像アップロードをする方法について説明していこうと思います。
ここ最近は、自社製品でもお客様に納品する際もHerokuを使うことが増えました。
ただ、Herokuはストレージ機能はあるものの1日でリセットされてしまうため、ずっと保存することが出来ません。
そこでどうするかというと、AWSのS3に保存するのが一般的な感じもしますが、今回はHerokuのアドオンでもあるCloudinaryにしてみようと思いました。
しかしながら、Herokuが使われるのはRubyユーザーが多いみたいで、PHP+Cloudinaryの情報が多くありません。
Laravelに関してはLaravel5の記事がいまだに参考にされていたり、それがなぜか非公式のライブラリーを使っていたりでちゃんとした記事が見当たらなかったので、今回はCloudinary公式のライブラリーを使って画像アップロードまでの作業について書いていこうと思います。
操作環境について
PC:Windows10
LAMP環境:XAMMP(PHP7.4)
Laravel:8.5.2.1
状況:cloudinaryと言う名前でプロジェクト作成済み
Cloudinaryの利用登録
先ずは、Cloudinaryの登録をしましょう。
「SING UP FOR FREE」をクリックして登録します。
登録の詳細は省きます。
登録が完了すると、APIを使うための認証情報が表示されます。
「Dashboard」のページの画面左上に表示されます。
これは後程.envファイルに情報を入れるのに使いますので、場所だけとりあえず覚えておきましょう。
Cloudinary公式ライブラリーのインストール
composerでライブラリーのインストールをするために、Cloudinaryのgithubに移動します。
すると画面中程にインストール方法が載っていますので、composerでインストールしましょう。
composer require cloudinary-labs/cloudinary-laravel
インストールが完了したら、そのすぐ下にある「Configuration」を行います。
php artisan vendor:publish --provider="CloudinaryLabs\CloudinaryLaravel\CloudinaryServiceProvider" --tag="cloudinary-laravel-config"
見にくいですが、Publishing completeとなればOKです。
Publishが成功すると、configディレクトリに「cloudinary.php」が生成されます。
中身はこんな感じで、envから環境変数を取れるようになります。
return [ /* |-------------------------------------------------------------------------- | Cloudinary Configuration |-------------------------------------------------------------------------- | | An HTTP or HTTPS URL to notify your application (a webhook) when the process of uploads, deletes, and any API | that accepts notification_url has completed. | | */ 'notification_url' => env('CLOUDINARY_NOTIFICATION_URL'), /* |-------------------------------------------------------------------------- | Cloudinary Configuration |-------------------------------------------------------------------------- | | Here you may configure your Cloudinary settings. Cloudinary is a cloud hosted | media management service for all file uploads, storage, delivery and transformation needs. | | */ 'cloud_url' => env('CLOUDINARY_URL'), /** * Upload Preset From Cloudinary Dashboard * */ 'upload_preset' => env('CLOUDINARY_UPLOAD_PRESET') ];
Laravelで環境設定
引き続きGithubを見ていきます。
Configurationの下に「API Keys」の項目がありますので、その内容を一度そのまま.envファイルにコピーします。
そうしたら、今度は実際に先程表示したCloudinaryのDashboardから、データをコピーします。
このコピーした値を.envファイルの「CLOUDINARY_URL=」に上書きする形で、貼り付けます。
ちなみに、「CLOUDINARY_UPLOAD_PRESET」と「CLOUDINARY_NOTIFICATION_URL」については、オプション設定なので、今回は説明はしません。
.envファイルを保存したら、設定を反映するためにキャシュクリアをします。
php artisan config:cache
アップロードするためのページの作成
ここからはアップロードに必要なRoute、Controler、Viewを作っていきます。
route/web.php
<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\CloudinaryUploadController; /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::get('/', function () { return view('welcome'); }); Route::get('/uplopad', [CloudinaryUploadController::class, 'uplopad']); Route::post('/upload', [CloudinaryUploadController::class, 'store'])->name('store');
app/Http/Controllers/CloudinaryUploadController.php
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Cloudinary; class CloudinaryUploadController extends Controller { public function upload() { return view('upload'); } public function store(Request $request) { $uploadedFileUrl = Cloudinary::upload($request->file('image')->getRealPath())->getSecurePath(); dd($uploadedFileUrl); } }
dd()については、アップロードされたか確認(試験)するために入れていますので、実際はこのdd()は消して下さい。
また、Cloudinaryにアップロードするためのメソッドについては、インストールで参考にしたGithubのUsageに使い方が載っていますので、詳しくはそちらを参考にして下さい。
resouces/views/upload.blade.php
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Cloudinary Upload Test</title> </head> <body> <form action="{{route('store')}}" method="POST" enctype="multipart/form-data"> @csrf <input type="file" name="image"> <button>画像をアップロード</button> </form> </body> </html>
アップロードをしてみる
アップロードする準備が終わったので、早速アップロードの試験をしてみます。
ファイルを選択した状態です。
画像アップロードをクリックしてアップロードします。
すると
こんな感じでレスポンスが返ってきました。
今度はCloudinaryのサイト上で、「Media Library」のページで実際に画像が上がっているかを確認します。
Newと書いてあるのが、アップロードした画像です。
うまくアップロードされていますね!
非常に簡単にアップロードできることが分かります。
アップロードに関するTips
Laravelだと画像を扱うとき「Intervention Image」を使うことが多いかと思いますが、このCloudinaryのライブラリーも同様の事が出来そうです。
その一つが「画像をリサイズしてアップロードする」ことができます。
例)
//ファイルの有無確認 $image_main = $request->hasFile('mainimage') ? $request->file('mainimage') : ""; //画像アップロード $image_main_up = $image_main ? Cloudinary::upload($request->file('mainimage')->getRealPath(), ['folder' => 'images', 'width' => 800,])->getSecurePath() : "";
先程のアップロードした画像名で気付いた方もいるかと思いますが、アップロードする前の名前ではなく、ランダムな名前になっています。
これはセキュリティ上の対策、名前をユニークにするための仕様みたいですが、オプションで変更もできます。
詳しくはCloudinaryのリファレンスに書いてありますので読んでみて下さい。
もしGuzzleHttp\Psr7\stream_for()のエラーが出たら
実は、この記事を書くちょっと前までGuzzleHttpのエラーが出ていてライブラリーの更新をしないと上手くいかなかったので、その対応についても書きたいと思います。
こんな風に、Cloudinaryにアップロードしようとするとエラーが出たことが有ります。
こうなってしまった場合は、php用のCloudinaryのライブラリーの更新が必要なので、composerでインストールします。
composer require "cloudinary/cloudinary_php:^2"
githubもとはこちら
このインストールをすると、stream_for()の記述方法が最新のGuzzleHttpのものに書き換えられ、エラーがなくなります。
まとめ
今回はLaravel8でCloudinaryにアップロードする方法について説明してきました。
Cloudinaryは容量やアクセス量、画像変換の数が一定を超えなければ無料で使えるサービスです。
画像メインでないサイトの場合は無料で足りるくらいだとおもうので、この機会に一度Cloudinaryを利用してみてはいかがでしょうか?
以上、「Laravel8でCloudinaryで画像アップロードをする方法」でした!
参考URL
コメント