laravel5.2 全部(一部)のビューで表示するデータをテーブルから自動で読み込む

たとえば運営からのお知らせや今日の天気なんかを全部の機能のビューで表示したい。

でも毎回毎回全コントローラーでそれを読むコードを書くのはめんどくさい。

それをなんとかできる機能がありました。

googleで検索ワードなんていれればいい?

「laravel5.2 共通メッセージ 一度読み込む」

「laravel5.2 全部の機能で使うデータ 共通で読む」

「laravel5.2 全部のビュー 共通の値 読む」

最後のでそれらしいのがヒット。

こういうのなんていうんですかね。

view()->share()

サービスプロバイダーに書いちゃう。

おー。そゆことなのかー。

AppServiceProvider.php に書いてもいいらしいけど、一応分けるときはこんな感じ。

php artisan make:provider InfoServiceProvider
<?php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class InfoServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        view()->share('info', 'こんにちは!');
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

view()->sharedってメソッドですでに存在してるかもわかる。

config/app.php に追加するの忘れずに。追加したら composer dump-autoload も。

ViewComposer

ただこれだとなんか気持ち悪い。長々したもの書きづらいし。

そこで、「指定したビューの生成前に必ず実行するメソッドをフックできる」的な機能があるみたい。

それが ViewComposer。

あの php の composer とごっちゃになりますが別物です。

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class InfoServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        view()->composer('*', 'App\Http\ViewComposers\InfoComposer'); // ここ変更
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

値をセットするクラスを適当に掘った App/Http/ViewComposers/ の下に InfoComposer.php とかって名前で作る。

<?php
namespace App\Http\ViewComposers;

use Illuminate\Contracts\View\View;
use App\Models\Info;

Class InfoComposer{

    protected $info;

    public function __construct()
    {
        $this->loadInfo();

    }

    public function compose(View $view)
    {
        $view->with('info', $this->info);
    }

    private function loadinfo(){
        
        $this->info = Info::all();  

    }
}

これでビューを作る前に compose を実行してくれる。

※注意

複数のビューを組み合わせてレイアウト作ってる場合、そのビューの数だけこれ実行されちゃうw

メイン画面とかサイドバーとか?表示するとこだけフックするように ServiceProvider で指定するの忘れないで。

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class InfoServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        view()->composer('sidebar', 'App\Http\ViewComposers\InfoComposer'); // 実行するビュー名の指定もできる
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

ただこれは、 Controller でビューを生成した後に実行されるので、使おうと思っている変数が使われている可能性がある。

ネーミングルールでなんとかなるっちゃーなるけど、こういうメソッドもあるみたい。

$view->offsetExists('info'); // infoがある?
$pre_info = $view->offsetGet('info'); 先に設定されてる $info の中身取得!

てかマニュアルにかいてあるね

よく読もう・・・。

ビュー 5.1 Laravel