0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Laravel 6.x 【画像アップロード】 ディレクトリの作成、ファイルの保存、データベースへの登録、表示

Last updated at Posted at 2020-10-16

#制作環境

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をインストールしてからはじめてください。

#完成イメージ
###アップロードフォーム
シンプルにファイル選択画面のみ。

up.jpg

###登録完了後
完了メッセージと、登録した画像を表示。

comp.jpg

#要件
・画像を選択し、アップロードできる。
・プロジェクトのstorage>app>public>imagesにファイルを保存する。
・保存する際に、ファイル名は元のファイル名と別の名称にする。
・データベースにファイルの名前を登録する。

それでは、はじめていきます。

#モデルとマイグレーションファイルの作成
プロジェクトのディレクトリでターミナルを起動し、以下を実行してください。

php artisan make:model Models/FileImage -m

これで、モデルとマイグレーションファイルが作成されます。
※モデルはModelsの中に作成するようにしています。

#マイグレーションファイルの編集
database>migrations 内のxxxx_xx_xx_xxxxx_create_file_images_table.phpを開き、以下のように編集します。

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を開き、以下を記述します。

FileImage.php
class FileImage extends Model
{
    protected $fillable = ['file_name'];
}

#コントローラの作成
ターミナルで以下を実行。

php artisan make:controller FileUpController

#コントローラの編集
app>Http>Controllers 内のFileUpController.phpを開き、以下のように記述します。

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
・ルートディレクトリからの相対位置を返します

リファレンス
https://readouble.com/laravel/6.x/ja/requests.html?header=%25E3%2582%25A2%25E3%2583%2583%25E3%2583%2597%25E3%2583%25AD%25E3%2583%25BC%25E3%2583%2589%25E3%2583%2595%25E3%2582%25A1%25E3%2582%25A4%25E3%2583%25AB%25E3%2581%25AE%25E4%25BF%259D%25E5%25AD%2598

#ビューの作成
resources>views 内にfile.blade.phpを作成し、以下のように記述します。

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を開き、以下のように記述します。

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です。

up.jpg

次に適当な画像ファイルを選択し、送信をクリックしてください。
送信後、以下のように選択した画像が表示されればOKです。

peach.jpg

#####※ちなみにバリデーションも何もやってないので、ファイルを選択しない状態で送信するとエラーが発生します。

#ファイルの確認
以下の場所にimagesディレクトリと、画像ファイルが保存されていることを確認してください。
ファイル名は自動的に付くので、変な名前になってます。セキュリティー対策ですね。

storage.jpg

同じく、以下の場所にimagesディレクトリと、画像ファイルがリンクされていることを確認してください。

symbol.jpg

確認ができればOKです。

#データベースの確認
tinkerを使い、データベースにファイル名が保存されているか確認します。

ターミナルで以下を実行します。

php artisan tinker

次に以下を実行。

use App\Models\FileImage;

次に以下を実行。

FileImage::all();

以下のように表示され、storageに保存されているファイル名と、登録されたfile_nameが合っていたらOKです。

tinker.jpg

最後にexitかCtrl+cでtinkerを終了します。

exit or Ctrl+c

以上で終了です。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?