Nello
Nello

Reputation: 1755

Need Clarification of Laravel Facade

So in the laravel documentation in laravel 5.2 it stated that this is how facade is implemented in laravel.

<?php

namespace App\Http\Controllers;

use Cache;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     *
     * @param  int  $id
     * @return Response
     */
    public function showProfile($id)
    {
        $user = Cache::get('user:'.$id);

        return view('profile', ['user' => $user]);
    }
}

Could we do this instead?

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Cache;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     *
     * @param  int  $id
     * @return Response
     */
    public function showProfile(Cache $cache, $id)
    {
        $user = $cache->get('user:'.$id);

        return view('profile', ['user' => $user]);
    }
}

From what I can see I think that

use Cache;

is just encapsulating the call to

Illuminate\Support\Facades\Cache

am I correct? The application bootstrap that namespace into that alias I believe?

More clarification would definitely help. I'm new to laravel.Anything that I explained or described wrong please correct me thanks.

Upvotes: 1

Views: 253

Answers (1)

maiorano84
maiorano84

Reputation: 11951

Yes, I believe you can, but I wouldn't do it that way. Instead, consider the purpose of a Laravel Facade: A class that is capable of sitting in the global namespace that allows static access to a given instance's public methods.

Laravel Facades are nothing more than syntactic sugar, and I would actually recommend to avoid using them if at all possible. While very convenient, they tend to obfuscate the code driving them.

In the case of the Cache facade, you can basically figure out the actual class that's being leveraged by looking at both the Facade's code, as well as the Service Provider responsible for all of the Cache's moving parts:

Cache Facade

namespace Illuminate\Support\Facades;

/**
 * @see \Illuminate\Cache\CacheManager
 * @see \Illuminate\Cache\Repository
 */
class Cache extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'cache';
    }
}

You can see in the comments that there's a reference to \Illuminate\Cache\CacheManager and \Illuminate\Cache\Repository. So which is it? The key here is the facade accessor cache. If we look at the service provider, we can see what class is being returned by the facade when using this accessor:

Cache Service Provider

class CacheServiceProvider extends ServiceProvider
{
    ...
    public function register()
    {
        $this->app->singleton('cache', function ($app) {
            return new CacheManager($app);
        });

        $this->app->singleton('cache.store', function ($app) {
            return $app['cache']->driver();
        });

        $this->app->singleton('memcached.connector', function () {
            return new MemcachedConnector;
        });

        $this->registerCommands();
    }
    ...
}

I would suggest declaring your dependency like this:

<?php

namespace App\Http\Controllers;

use Illuminate\Cache\CacheManager as Cache;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     *
     * @param  int  $id
     * @return Response
     */
    public function showProfile(Cache $cache, $id)
    {
        $user = $cache->get('user:'.$id);

        return view('profile', ['user' => $user]);
    }
}

I'm fairly certain that PHP actually allows you to access static methods from an instance. If that's the case, then the way to do it in the way you were thinking of would need to look something like this:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Cache;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     *
     * @param  int  $id
     * @return Response
     */
    public function showProfile(Cache $cacheFacade, $id)
    {
        $cache = $cacheFacade->getFacadeRoot()
        $user = $cache->get('user:'.$id);

        return view('profile', ['user' => $user]);
    }
}

Hope this helps!

Upvotes: 1

Related Questions