Back

Is there a way to pass every variable in a controller action, to the view automatically?


Is there a way to pass every variable in a controller action, to the view automatically?

So if I have

class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     *
     * @param  int  $id
     * @return Response
     */
    public function show($id)
    {
        $testvar = "hello";
        return view('user.profile');
    }
}

So when I echo $testvar in the view, the hello text prints on the screen, without me having to manually pass the variable to the view?

tajulasri replied 3 months ago

meaning you are talking about global scope variables which is its value can be override?

tutelagesystems replied 3 months ago

You could create a global scope (view share) variable and just override it in your class as mentioned by tajulasri

Ahmed Mohamed Abd El Ftah replied 3 months ago

you can use view composer

in AppServiceProvider you can do something like that

public function boot()
{

  $views = ['user.profile'];

  View::compose($views , function ($view){
      $view->with('testvar','hello');
  });

}

so each time the view 'user.profile' get called it will have the $testvar

https://laravel.com/docs/5.4/views#view-composers

Alok replied 3 months ago

You can use view composer or view share to share the variables in the view Blade files.

Mike B. replied 3 months ago

I don't think the author was thinking about the global scopes / view composers but only about not needing to pass an array of variables in each controller action.

The thing that you need is get_defined_vars() - it gets all defined variables in the current scope. See the dummy code below:

$notVisible1 = 1;

function view($name, $arguments) {
    return "{$name} => " . json_encode($arguments) . "\n";
}

class TestClass {
    public function test()
    {
        $a = 1;
        $b = 2;

        return view('viewName', get_defined_vars());
    }
}

$notVisible2 = 2;
$tc = new TestClass();
echo $tc->test(); // output: viewName => {"a":1,"b":2}

I'm not advocating the use of this since it can easily make the views polluted with variables that should never be available there but I understand where it is coming from

fetzi replied 3 months ago

Passing all defined vars to the view can be dangerous if you provide default data (e.g. current user) from your ViewComposer.

I would say it is always a good idea to be explicit about what gets passed to the view.

denjaland replied 3 months ago

I agree with @fetzi. I don't like to much magic going on outside of my control :-) Also - we call it controllers so we can control stuff in there :-)

Mike B. replied 3 months ago

It's true that it can be dangerous and it will pass down the function arguments too (since they are defined variables)

but it shouldn't be too dangerous if used with caution - the blade files are written by devs not by the end user so echoing crucial data should not be an issue and dumping the view data on exception should be disabled on production environments by default anyway.

I would worry more about multiple variables with the same name and accidental overwrites that could end with unexpected behavior.

To be on the safer side one could pass only variables that are explicitly named for example only the ones that begin with the 'view*'

function filter(array $variables)
{
    $prefix = 'view';
    return array_filter($variables, function ($key) use ($prefix) {
        return substr($key, 0, 4) === $prefix;
    }, ARRAY_FILTER_USE_KEY);
}

// and then in controller action
$a = 1;
$b = 2;
$viewVariable = 'asd';
return view('viewName', filter(get_defined_vars())); // returns: ['viewVariable' => 'asd']

Personally I wouldn't use this since it feels hacky and generates unneeded overhead compared to manually entering an array that should be passed to view

denjaland replied 3 months ago

I still wouldn't be using it, but it's a nice solution to still keep it under control :)

Mike B. replied 3 months ago

Now that I'm thinking about it - one could reverse the filter to exclude variables starting with underscore ($_var) to get back in time and get the feeling like it is a PHP4 again, lol ;)

massimoselvi replied 3 months ago

at the Controller level: you can set variables to the view thought the share() method in the constructor

public function __construct()
{
    View::share('testvar', 'hello'); // or app('view')->share('testvar', 'hello');
}

at the App level:

https://laravel.com/docs/5.4/views#sharing-data-with-all-views


Sign in to participate in this thread!



We'd like to thank these amazing companies for supporting us