#制作環境
Windows 10
Laravel : 6.18.35
Laravel/ui : 1.0
Laravel-mix : 5.0.1
Bootstrap : 4.0.0
MDBootstrap : 4.19.1
chart.js : 2.9.3
XAMPP
PHP : 7.4.3
Visual Studio Code
#はじめに
この記事はプログラミングをはじめたばかりの素人が、できたことをメモするのに利用しています。
内容には誤りがあるかもしれません。
#参考にしたサイト
https://qiita.com/10mi8o/items/ce9c875e736c7b1d2498
https://qiita.com/koru1893/items/1d2f522e20744b03e3ad
https://laraweb.net/tutorial/2707/
https://php-junkie.net/framework/laravel/upload_image/
リファレンス
https://readouble.com/laravel/6.x/ja/helpers.html?header=redirect()
#関連記事
続編です。
Laravel 6.x 【画像アップロード】 ファイルの削除、データベースへのレコード削除
Laravel 6.x 【画像アップロード】 トランザクションを使用する
#この記事の目的
Laravelでの画像アップロードを、シンプルに理解できるよう画像アップロードに特化して掲載するのが目的です。
その為、バリデーション等は(素人の自分的に)わかりづらくなるのであえて割愛してます。
またデザインなども一切気にしてません。
あくまで、画像アップロードのやり方だけを見るのに特化させてます。
事前にLaravelをインストールしてからはじめてください。
#完成イメージ
###アップロードフォーム
シンプルにファイル選択画面のみ。
###登録完了後
完了メッセージと、登録した画像を表示。
#要件
・画像を選択し、アップロードできる。
・プロジェクトのstorage>app>public>imagesにファイルを保存する。
・保存する際に、ファイル名は元のファイル名と別の名称にする。
・データベースにファイルの名前を登録する。
それでは、はじめていきます。
#モデルとマイグレーションファイルの作成
プロジェクトのディレクトリでターミナルを起動し、以下を実行してください。
php artisan make:model Models/FileImage -m
これで、モデルとマイグレーションファイルが作成されます。
※モデルはModelsの中に作成するようにしています。
#マイグレーションファイルの編集
database>migrations 内のxxxx_xx_xx_xxxxx_create_file_images_table.phpを開き、以下のように編集します。
public function up()
{
// テーブルがなければ新規作成する
if (!Schema::hasTable('file_images')) {
Schema::create('file_images', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('file_name')->comment('ファイル名');
$table->timestamps();
});
}
}
->comment('ファイル名')は、なくてもかまいません。
#モデルの編集
app>Models 内のFileImage.phpを開き、以下を記述します。
class FileImage extends Model
{
protected $fillable = ['file_name'];
}
#コントローラの作成
ターミナルで以下を実行。
php artisan make:controller FileUpController
#コントローラの編集
app>Http>Controllers 内のFileUpController.phpを開き、以下のように記述します。
<?php
// モデル使用の為に追記
use App\Models\FileImage;
class FileUpController extends Controller
{
public function index()
{
// データベースからfile_imagesテーブルにある全データを抽出
$data = FileImage::all();
// ビューfile.blade.phpに$dataを渡して表示させる
return view('file', compact('data'));
}
// 登録処理
public function store(Request $request)
{
// $request->imgはformのinputのname='img'の値です
// ->storeメソッドは別途説明記載します
$path = $request->img->store('public/images');
// パスから、最後の「ファイル名.拡張子」の部分だけ取得します 例)sample.jpg
$filename = basename($path);
// FileImageをインスタンス化(実体化)します
$data = new FileImage;
// 登録する項目に必要な値を代入します
$data->file_name = $filename;
// データベースに保存します
$data->save();
// 登録後/fileにリダイレクトします その際にフラッシュメッセージを渡します
return redirect('/file')->with('success', '登録完了しました。');
}
}
####storeメソッドについて
下記storeメソッドだけで、
$path = $request->img->store('public/images');
以下の内容を実行してくれます。
・保存ディレクトリの作成 (今回はstorage>app>public 内にimagesディレクトリを作成してくれます)
・ファイルの保存
・保存の際に自動的に元のファイル名を変更します 例:mMwTQg1AGSNdhPaL5GofWxGF3DYkvgphEnzGEIxF.png
・ルートディレクトリからの相対位置を返します
#ビューの作成
resources>views 内にfile.blade.phpを作成し、以下のように記述します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ファイルアップロード</title>
</head>
<body>
<h1>ファイルアップロード</h1>
@if (session('success'))
<p>{{ session('success') }}</p>
@endif
<form action="/file" method="post" enctype="multipart/form-data">
@csrf
<label>画像選択<input type="file" name="img" accept=".png,.jpg,.jpeg,image/png,image/jpg"></label>
<br>
<input type="submit" value="送信">
</form>
@foreach ($data as $item)
<img src="{{ asset('storage/images/' . $item->file_name) }}">
@endforeach
</body>
</html>
#ルーティングの作成
routes 内のweb.phpを開き、以下のように記述します。
Route::get('/file', 'FileUpController@index');
Route::post('/file', 'FileUpController@store');
#シンボリックリンクの作成
ターミナルで以下を実行。
これをやらないと画像を表示できません。
php artisan storage:link
Laravelの仕様で、ファイルはstrage>app>public>imagesに保存されますが、読み込み時はpublic>storage>imagesからファイルが読み込まれます。
その為、リンクを貼って保存先にアクセスできるようにしてます。
#動作確認
/fileにアクセスして下さい。
以下が表示されればOKです。
次に適当な画像ファイルを選択し、送信をクリックしてください。
送信後、以下のように選択した画像が表示されればOKです。
#####※ちなみにバリデーションも何もやってないので、ファイルを選択しない状態で送信するとエラーが発生します。
#ファイルの確認
以下の場所にimagesディレクトリと、画像ファイルが保存されていることを確認してください。
ファイル名は自動的に付くので、変な名前になってます。セキュリティー対策ですね。
同じく、以下の場所にimagesディレクトリと、画像ファイルがリンクされていることを確認してください。
確認ができればOKです。
#データベースの確認
tinkerを使い、データベースにファイル名が保存されているか確認します。
ターミナルで以下を実行します。
php artisan tinker
次に以下を実行。
use App\Models\FileImage;
次に以下を実行。
FileImage::all();
以下のように表示され、storageに保存されているファイル名と、登録されたfile_nameが合っていたらOKです。
最後にexitかCtrl+cでtinkerを終了します。
exit or Ctrl+c
以上で終了です。