Laravel 5のすべてのビューにデータを渡す方法は?


125

Laravel 5アプリケーションのすべてのビューでいくつかのデフォルトデータにアクセスできるようにしたいのですが。

私はそれを検索しようとしましたが、Laravel 4の結果しか見つかりませんでした。ここで「すべてのビューでデータを共有する」のドキュメントを読みましたが、何をすべきか理解できません。次のコードはどこに配置する必要がありますか?

View::share('data', [1, 2, 3]);

ご協力いただきありがとうございます。


さて、あなたはこの要件を管理するために起動コードが必要ですか?
Safoor Safdar、2015

1
データベースコールの結果を含むサービスプロバイダーでView :: shareを使用してヘッドアップすると、データベースの更新の移行を実行したり、到達できないデータベース接続で夕暮れを実行しようとしたりすると、アプリケーションがエラーになります(詳細は、.env.dusk.localはサービスプロバイダーが実行された後にのみ使用されます)。以下で説明するように、基本コントローラまたはミドルウェアが最適です。
アンディ・ロベル2017

また*、含まれているすべてのサブビュー、コンポーネントなどに対して実行されるので、特にdbクエリを使用する場合は、ビューコンポーザーで使用するときは注意してください。何百もの不要なクエリが実行される可能性があるため、レイアウトなどのベースビューを使用することをお勧めします。次に、アプリは必要に応じてデータを渡します。
アンディ・ロベル2017

回答:


221

この目標はさまざまな方法で達成でき、

1. BaseControllerの使用

物事を設定する方法として、BaseControllerLaravel独自のを拡張するクラスを作成し、Controllerそこにさまざまなグローバル物事を設定します。他のすべてのコントローラーBaseControllerは、Laravelのコントローラーではなく、から拡張されます。

class BaseController extends Controller
{
  public function __construct()
  {
    //its just a dummy data object.
    $user = User::all();

    // Sharing is caring
    View::share('user', $user);
  }
}

2.フィルターの使用

アプリケーション全体のすべてのリクエストのビューに何かを設定したいという事実がわかっている場合は、リクエストの前に実行されるフィルターを使用して設定することもできます。これが、LaravelのUserオブジェクトを処理する方法です。

App::before(function($request)
{
  // Set up global user object for views
  View::share('user', User::all());
});

または

独自のフィルターを定義できます

Route::filter('user-filter', function() {
    View::share('user', User::all());
});

簡単なフィルター呼び出しで呼び出します。

バージョン5に従って更新*

3.ミドルウェアの使用

使用するView::sharemiddleware

Route::group(['middleware' => 'SomeMiddleware'], function(){
  // routes
});



class SomeMiddleware {
  public function handle($request)
  {
    \View::share('user', auth()->user());
  }
}

4. View Composerの使用

View Composerは、特定のデータをバインドしてさまざまな方法で表示するのにも役立ちます。変数を特定のビューまたはすべてのビューに直接バインドできます。たとえば、独自のディレクトリを作成して、要件に応じてビューコンポーザファイルを保存できます。これらのビューコンポーザーファイルは、サービスを介してビューと対話します。

View composerメソッドはさまざまな方法を使用できます。最初の例は似ています。

App\Http\ViewComposersディレクトリを作成できます。

サービスプロバイダー

namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider {
    public function boot() {
        view()->composer("ViewName","App\Http\ViewComposers\TestViewComposer");
    }
}

その後、このプロバイダーを「プロバイダー」セクションのconfig / app.phpに追加します。

TestViewComposer

namespace App\Http\ViewComposers;

use Illuminate\Contracts\View\View;

class TestViewComposer {

    public function compose(View $view) {
        $view->with('ViewComposerTestVariable', "Calling with View Composer Provider");
    }
}

ViewName.blade.php

Here you are... {{$ViewComposerTestVariable}}

このメソッドは、特定のビューのみに役立ちます。ただし、すべてのビューに対してViewComposerをトリガーする場合は、この単一の変更をServiceProviderに適用する必要があります。

namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider {
    public function boot() {
        view()->composer('*',"App\Http\ViewComposers\TestViewComposer");
    }
}

参照

Laravelのドキュメント

さらに明確にするためにLaracastエピソード

それでもわからないことがあれば、私に知らせてください。


あなたの例にはregister()メソッドがありません
Jonathan

@jonathanは指摘してくれてありがとう、しかし例には注意する必要があるセクションだけが含まれています。ビューでデータを共有するための視点。
Safoor Safdar

フィルターはどこに置きますか?おそらく最も正しい答えは、現在ミドルウェアグループlaravel.com/docs/5.3/middleware#middleware-groupsまたはグローバルミドルウェアを使用していることです
Toskan

7
これは良い考えではありません。Viewコンポーザは、個々のビューごとにコンポーザインスタンスを作成します。つまり、1000回のループを実行すると、1000個のコンポーザインスタンスが作成され、1000回の起動イベントが処理されますが、これは望ましいことではありません。
Reza Shadman、2016年

4
@RezaShadmanは正しいです!私はこれを難しい方法で学びました。調査するためにlaravel-debugbarツールをインストールするまで、アプリケーションの実行が非常に遅くなりました。その後、8つのクエリすべてが1ページの読み込みで約15回実行されることに気付きました。これは、含まれているブレードファイルごとにビューコンポーザーが呼び出されるためです。これは、アスタリスクを使用している場合です*。を使用していない場合は、問題ありません*
Syclone、

66

独自のサービスプロバイダーViewServiceProvider名前は一般的)を作成するか、既存のを使用できますAppServiceProvider

選択したプロバイダーで、コードをbootメソッドに配置します。

public function boot() {
    view()->share('data', [1, 2, 3]);
}

これにより$data、すべてのビューで変数にアクセスできるようになります。

ヘルパーの代わりにファサードを使用したい場合は、に変更view()->しますが、ファイルの先頭View::に置くことuse View;を忘れないでください。


ありがとうございます。ブート機能はこの種のもののためのものですか、それとも自分のサービスプロバイダーを作成することをお勧めしますか?
Ragnarsson、2015

2
共有するものが1つまたは2つしかない場合AppServiceProviderは入れてもかまいませんが、それ以上のものがあれば、新しいプロバイダーの作成を検討してください。
Marwelln 2015

動作していましたが、今日は動作していないようです。使用してcomposer updateも動作しません。実際にはまったく発砲していませんboot()。2つの変数を共有する必要があります。
itsazzad

11
移行を実行する前に呼び出されるため、データベースレコードをフェッチしている場合は機能しないことに注意してください。つまり、基本的に、データベースレコードが存在する前にフェッチしようとしています。少なくともそれは私には当てはまるようです。
lorey

1
残念ながら、これはログインユーザーAuth :: user()の共有では機能しないようです。Safoorの#1の回答は、この回答の下にあります:)
Stan Smulders

11

これが一番簡単だと思いました。新しいプロバイダーを作成し、'*'ワイルドカードを使用してすべてのビューにアタッチします。5.3でも動作します:-)

<?php

namespace App\Providers;

use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;

class ViewServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     * @return void
     */
    public function boot()
    {
        view()->composer('*', function ($view)
        {
            $user = request()->user();

            $view->with('user', $user);
        });
    }

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

2
このプロバイダーを、config / app "App \ Providers \ ViewServiceProvider :: class、"のプロバイダーの配列に追加します
Nadeem0035

8

最善の方法は、変数を共有することです View::share('var', $value);

を使用して作成する際の問題"*"

次のアプローチを検討してください。

<?php
// from AppServiceProvider::boot()
$viewFactory = $this->app->make(Factory::class);

$viewFacrory->compose('*', GlobalComposer::class);

ブレードビューの例から:

  @for($i = 0; $i<1000; $i++)
    @include('some_partial_view_to_display_i', ['toDisplay' => $i])
  @endfor

何が起こるのですか?

  • GlobalComposerクラスがインスタンス化された1000の使用して回 App::make
  • イベントcomposing:some_partial_view_to_display_i1000回処理されます。
  • クラスcompose内の関数GlobalComposerは1000回呼び出されます。

ただし、部分ビューsome_partial_view_to_display_iはによって構成される変数とは関係ありませんが、GlobalComposerレンダリング時間を大幅に増加させます。

最善のアプローチは?

View::shareグループ化されたミドルウェアに沿って使用します。

Route::group(['middleware' => 'WebMiddleware'], function(){
  // Web routes
});

Route::group(['prefix' => 'api'], function (){

});

class WebMiddleware {
  public function handle($request)
  {
    \View::share('user', auth()->user());
  }
}

更新

ミドルウェアパイプラインで計算されたものを使用している場合は、適切なイベントをリッスンするか、ビュー共有ミドルウェアをパイプラインの最後に配置することができます。


4

ドキュメントでは:

通常、サービスプロバイダーの起動メソッド内で共有メソッドを呼び出します。それらをAppServiceProviderに追加するか、それらを格納する別のサービスプロバイダーを生成するかは自由です。

私はマーウェルンに同意します、それをAppServiceProviderブート関数に入れます:

public function boot() {
    View::share('youVarName', [1, 2, 3]);
}

他の「グローバル」な変数との混乱や間違いを避けるために、変数には特定の名前を使用することをお勧めします。


3

ドキュメントはhttps://laravel.com/docs/5.4/views#view-composersを聞いていますが、私はそれを分解します

  1. アプリケーションのルートディレクトリでapp \ Providersディレクトリを探し、ComposerServiceProvider.phpファイルを作成し、以下のテキストをコピーしてそこに貼り付けて保存します。

    <?php
        namespace App\Providers;
        use Illuminate\Support\Facades\View;
        use Illuminate\Support\ServiceProvider;
    
        class ComposerServiceProvider extends ServiceProvider
        {
            /**
            * Register bindings in the container.
            *
            * @return void
            */
        public function boot()
        {
            // Using class based composers...
            View::composer(
                'profile', 'App\Http\ViewComposers\ProfileComposer'
            );
    
            // Using Closure based composers...
            View::composer('dashboard', function ($view) {
                //
            });
        }
    
        /**
        * Register the service provider.
        *
        * @return void
        */
        public function register()
        {
            //
        }
    }
  2. アプリケーションのルートからConfig / app.phpを開き、ファイルでプロバイダーセクションを探し、この'App \ Providers \ ComposerServiceProvider'をコピーして配列に貼り付けます。

これにより、Composerサービスプロバイダーが作成されました。http:// yourdomain / something / profileのようなビュープロファイルでアプリケーションを実行すると、サービスプロバイダーComposerServiceProviderが呼び出され、クラスApp \ Http \ ViewComposers \ ProfileComposerがインスタンス化されて、以下のコードによりComposerメソッドが呼び出されます。起動方法または機能。

 // Using class based composers...
 View::composer(
   'profile', 'App\Http\ViewComposers\ProfileComposer'
 );
  1. アプリケーションを更新すると、クラスApp \ Http \ ViewComposers \ ProfileComposerがまだ存在しないため、エラーが発生します。それを作成しましょう。

ディレクトリパスapp / Httpに移動します

  • ViewComposersというディレクトリを作成します

  • ProfileComposer.phpファイルを作成します。

    class ProfileComposer
    {
        /**
        * The user repository implementation.
        *
        * @var UserRepository
        */
        protected $users;
    
        /**
        * Create a new profile composer.
        *
        * @param  UserRepository  $users
        * @return void
        */
        public function __construct(UserRepository $users)
        {
            // Dependencies automatically resolved by service container...
            $this->users = $users;
        }
    
        /**
        * Bind data to the view.
        *
        * @param  View  $view
        * @return void
        */
        public function compose(View $view)
        {
            $view->with('count', $this->users->count());
        }
    }

次に、ビュー、またはこの場合はProfile.blade.phpに移動して、

{{ $count }}

プロフィールページのユーザー数が表示されます。

すべてのページの変更数を表示するには

// Using class based composers...
View::composer(
    'profile', 'App\Http\ViewComposers\ProfileComposer'
);

// Using class based composers...
View::composer(
    '*', 'App\Http\ViewComposers\ProfileComposer'
);

<?phpと名前空間App \ Http \ ViewComposers; Illuminate \ Contracts \ View \ Viewを使用します。がProfileComposer.phpにありません
Unicco



1

configフォルダー内に、たとえば以下のコンテンツを含む「variable.php」という名前のphpファイルを作成できます。

<?php

  return [
    'versionNumber' => '122231',
  ];

すべてのビュー内で、次のように使用できます

config('variable.versionNumber')

情報は真にグローバルであり、どこからでもアクセスできるため、場合によってはこのようにします。そのため、構成ファイル "global.php"を呼び出し、コードの他のすべての部分でアクセスできるようにしたいものをそこに配置します。唯一の制限は、これが静的データ用であり、キャッシュされることです。常にデータを変更している場合は、この方法を使用しないでください。
eResourcesInc 2018

1

1)(app \ Providers \ AppServiceProvider.php)

// in boot function
       view()->composer('*', function ($view) {
            $data = User::messages();
            $view->with('var_messages',$data);
        });

2)ユーザーモデル

  public static function messages(){ // this is just example
        $my_id = auth()->user()->id;
        $data= Message::whereTo($my_id)->whereIs_read('0')->get(); 
        return $data; // return is required
    }

3)あなたの視点で

 {{ $var_messages }}

0

Laravel 5.6メソッド:https : //laravel.com/docs/5.6/views#passing-data-to-views

例、モデルコレクションをすべてのビューで共有する場合(AppServiceProvider.php):

use Illuminate\Support\Facades\View;
use App\Product;

public function boot()
{
    $products = Product::all();
    View::share('products', $products);

}

2
空のデータベースで新しいアプリケーションを作成しようとすると、問題が発生します。
Chris Herbert、

0

次の2つのオプションがあります。

1. App \ Providers \ AppServiceProviderのBoot関数で共有

public function boot() { view()->share('key', 'value'); }

そして、任意のビューファイルで$ key変数にアクセスします。

注:ここでは、現在のセッション、認証、ルートデータにアクセスできないことに注意してください。このオプションは、静的データを共有する場合にのみ有効です。現在のユーザー、ルート、またはこれでは実行できないカスタムセッション変数に基づいていくつかのデータを共有するとします。

  1. ヘルパークラスの使用アプリケーションの任意の場所にヘルパークラスを作成し、configフォルダーのapp.phpファイルのAlias配列に登録します。

'aliases' => [ ..., 'Helper' => App\HelperClass\Helper::class, ],

Appフォルダー内のHelperClassフォルダーにHelper.phpを作成します

namespace App\HelperClass;

class Helper
{
    public static function Sample()
    {
        //Your Code Here
    }
}

どこでもアクセスできます Helper::Sample()

ここでは、Auth、Route、Session、またはその他のクラスの使用に制限されません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.