Memo

メモ > 技術 > フレームワーク: Laravel > ファイル

■ファイル
■ファイルの保存(ローカル) ファイルストレージ 5.5 Laravel https://readouble.com/laravel/5.5/ja/filesystem.html コントローラなどで以下を読み込む
use Illuminate\Support\Facades\Storage;
以下のコードを実行すると
Storage::put('test/1.txt', 'test1');
以下にファイルが保存される。ファイル内には「test1」と書き込まれる
storage\app\test\1.txt
■ファイルの保存(S3) Laravel 5.4でS3ファイルアップロード - Qiita https://qiita.com/zz22394/items/cd960124c3aec164a24d ファイルのアップロード - ララジャパン http://www.larajapan.com/tag/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E3%82%A2%E3%83%83%E3%83%9... あらかじめAWSのコンソールで、S3のバケットを作成しておく ドライバをインストール
composer require league/flysystem-aws-s3-v3
S3を使うために、.envに設定を追加する
AWS_KEY=XXXXX AWS_SECRET=YYYYY AWS_REGION=ap-northeast-1 AWS_BUCKET=laravel-test
コントローラなどで以下を読み込む
use Illuminate\Support\Facades\Storage;
以下のコードを実行するとアップロードされる
Storage::disk('s3')->put('test/1.txt', 'test1', 'public');
AWSのコンソールで、ファイルが作成されていることを確認する なお、以下のようにしてアップロードするようにしておくと、 .env に「FILESYSTEM_CLOUD=public」を追加することで「ローカル環境の場合のみS3を使用しない」などができるようになる (ローカル環境なら storage\app\public\test に保存されるようになる)
$image = $request->file('image')->storeAs( 'test', 'image.jpg', config('filesystems.cloud') );
■ファイルアップロード 一例だが、以下のようなフォームからアップロードできる
<input type="file" id="image" name="image"> @if (isset($information) && $information->image) <label> <input type="checkbox" id="image_delete" name="image_delete" value="{{{ $information->image }}}"> ファイルを削除する </label> @endif @if ($errors->first('image')) <span class="help-block"> <strong>{{ $errors->first('image') }}</strong> </span> @endif
サービスで受け取って以下のように処理する いったん一時的なディレクトリに保存し、データベースを更新できたら正式な場所に移動させている
public function postInformation($id, InformationCreateRequest $request) { $input = $request->only([ 'title', 'body', 'datetime', ]); $temporary_directory = 'temp/' . $request->session()->getId() . '/'; $extension = pathinfo($request->file('image')->getClientOriginalName(), PATHINFO_EXTENSION); $file_path = $request->file('image')->storeAs($temporary_directory, 'image.' . $extension, config('filesystems.cloud')); $input['image'] = basename($file_path); try { return DB::transaction(function () use ($id, $input, $temporary_directory) { $result = $this->informationRepository->save($id, $input); $data_directory = 'information/' . $result->id . '/'; if (isset($input['image_delete'])) { Storage::disk(config('filesystems.cloud'))->delete($data_directory . $input['image_delete']); } elseif (isset($input['image'])) { Storage::disk(config('filesystems.cloud'))->delete($data_directory . $input['image']); Storage::disk(config('filesystems.cloud'))->move($temporary_directory . $input['image'], $data_directory . $input['image']); Storage::disk(config('filesystems.cloud'))->setVisibility($data_directory . $input['image'], 'public'); } Storage::disk(config('filesystems.cloud'))->deleteDirectory($temporary_directory); }); } catch (\Exception $e) { return null; } }
InformationCreateRequest では以下のようにして入力チェックできる
public function rules() { return [ 'title' => 'required|string|max:191', 'body' => 'required|string|max:1000', 'datetime' => 'required|date', 'image' => 'nullable|mimes:jpeg,gif,png|max:1000', ]; }
ビューで以下のようにすることで、ファイルを表示できる
@if ($information->image) <img src="{{ Storage::disk(config('filesystems.cloud'))->url('information/' . $information->id . '/' . $information->image) }}"> @endif
S3使用時でも、ローカル環境で .env に以下を追記することで、storage\app\public\ 内にファイルが保存される
FILESYSTEM_CLOUD=public
ローカルに保存する場合、以下のコマンドを実行すると storage\app\public\ 内のファイルを /storage/ で参照できるようになる (シンボリックリンクが張られる) $ php artisan storage:link The [public/storage] directory has been linked. homestead - Laravel 5.3 storage:link -> symlink(): Protocol error - Stack Overflow https://stackoverflow.com/questions/39496598/laravel-5-3-storagelink-symlink-protocol-error PHP - Laravel5.4で画像をアップロードし、public/imagesに保存したい|teratail https://teratail.com/questions/89984 Laravelで画像ファイルアップロードをする簡単なサンプル - Qiita http://qiita.com/makies/items/0684dad04a6008891d0d Laravel上画像アップロード - Qiita http://qiita.com/samudra/items/3cb97bd6f1750c3f8134 ■ファイルアップロード(保存先が異なる場合の補足) デフォルトで storage/app/public が参照されるが、 例えば storage/app 直下に products などを作って保存する場合には問題がある この場合、以下のように手動でシンボリックリンクを作成するといい
# rm /var/www/public/storage # ln -s /var/www/storage/app /var/www/public/storage
laravel - Laravel-ローカルストレージのシンボリックリンクを元に戻して更新する方法 https://www.webdevqa.jp.net/ja/laravel/laravel%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%82%B9%E3%83%88... ■ファイルアップロード(Docker環境での補足) PHPのコンテナ内で、通常どおり以下を実行すると対応できる
# php artisan storage:link
■ファイルアップロード(Vagrant環境での補足)
$ php artisan storage:link In Filesystem.php line 228: symlink(): Protocol error
このようなエラーになる場合、いったん
>vagrant halt
でHomesteadを終了し、コマンドプロンプトを右クリックして「管理者として実行」で起動する その状態で再度以下を実行する
$ php artisan storage:link
それでも解決しなければ、Windowsのコマンドプロンプトから以下のように実行する ショートカットのようなものが作成されるが、これはシンボリックリンク (コマンドプロンプトは管理者権限で起動しないと、「この操作を実行するための十分な特権がありません。」のエラーになるので注意)
>cd C:\Vagrant\test\code\main\public >mkdir storage >cd storage >mklink /D gift_item ..\..\storage\app\gift_item gift_item <<===>> ..\..\storage\app\gift_item のシンボリック リンクが作成されました
WindowsでLaravelのphp artisan storage:linkが実行できなかった場合の対処法 - Qiita https://qiita.com/shioharu_/items/608d024c48d9d9b5604f コマンドプロンプト | シンボリックリンクの作成(MKLINK) https://www.javadrive.jp/command/dir/index8.html ■CSSファイルやJSファイルのパスに、自動でファイルのタイムスタンプを追加する LaravelでBladeを拡張する(@asset( )) - Qiita https://qiita.com/reflet/items/a24b3c8e809f75fdbc19 実際は、以下のようにして組み込んだ app\Providers\BladeServiceProvider.php を作成
<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; use Illuminate\Support\Facades\Blade; class BladeServiceProvider extends ServiceProvider { /** * Bladeサービスの初期化処理 * * @return void */ public function boot() { /** * CSSファイルやJSファイルのパスに、ファイルのタイムスタンプを追加 * * @param string $file * @return string */ Blade::directive('asset', function ($file) { $file = str_replace(["'", '"'], '', $file); $path = public_path() . '/' . $file; try { $timestamp = "?<?php echo \File::lastModified('{$path}') ?>"; } catch (\Exception $e) { $timestamp = ''; } return asset($file) . $timestamp; /* // ロードバランサーを考慮する場合(環境によってはURLを自動取得できないので、.envのAPP_URLを参照) $app_url = env('APP_URL'); if (empty($app_url)) { return asset($file) . $timestamp; } else { return $app_url . '/' . $file . $timestamp; } */ }); } /** * アプリケーションサービスの登録 * * @return void */ public function register() { // } }
config\app.php を編集
'providers' => [ 〜略〜 App\Providers\BladeServiceProvider::class,
ビュー内で以下のように asset を使用すると、ファイル名の最後に「?1541565515」のような値が追加される
<script src="@asset('js/app.js')"></script> <script src="@asset('js/plugins/datetimepicker/jquery.datetimepicker.full.min.js')"></script>

Advertisement