Sven Luijten

Laravel facades vs class aliases

Published on 4 minutes to read

There's a difference between what Laravel calls facades and class aliases. Let's take a look at both, how they're different from each other, and how they became so intertwined with each other in the public eye.

Facades

A facade in Laravel is nothing but a proxy to an object in the service container. In other words, if an object is bound to the service container as 'my-service', you can call methods on that object by using static methods on the following facade:

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

class MyServiceFacade extends Facade
{
    public function getFacadeAccessor()
    {
	    return 'my-service';
    }
}

Notice the 'my-service' string by which the service is bound to the container. When any static method is called on this facade, the facade's __callStatic()magic method is invoked, the 'my-service' service is retrieved from the container, and your call is forwarded to that instance.

You still have to reference the full namespace to this facade (App\Facades\MyServiceFacade) when you use it in your application. At least, if you don't also add a class alias.

Class Aliases

PHP allows developers to alias any class to any other name using the class_alias function. For example, say I have a class named Aang, I could alias it toBonzuPippinpaddleopsicopolisTheThird and use it like normal:

class Aang
{
	public static function greet(): string
	{
		return 'Flameo!';
	}
}

class_alias(Aang::class, 'BonzuPippinpaddleopsicopolisTheThird');

echo BonzuPippinpaddleopsicopolisTheThird::greet(); // Flameo!

You can also alias something to another namespace if you want:

namespace App {
    class User
    {
        public static function greet(): string
        {
            return 'Hello!';
        }
    }
}

namespace {
    class_alias(App\User::class, 'User');

    echo \User::greet(); // Hello!
}

This can be useful for using classes with a long FQCN in views, where importing classes with use statements might not be possible or is just plain ugly.

The most obvious downside is that you lose autocomplete in most IDEs, because your IDE can't know when/if the class_alias() function has been called at that point in your application.

The Confusion

Laravel aliases all facades it ships with to their base classname like in the second example above. That means all classes in the Illuminate\Support\Facades namespace are available as if they were in the global namespace. You can see this happen in your own config/app.php (the aliases key).

I think this default behavior is why a lot of people in the Laravel community have conflated facades and class aliases.

Using a namespaced class as if it lives in the global namespace is not only for facades. You can alias whatever classes you want in the aforementioned config/app.php. For example, you might alias Illuminate\Support\Str to just Str and Illuminate\Support\Number to Num for quick and easy use in views.

Conclusion

\Config is not a facade, it's a class alias for the facade. There is no reason why you shouldn't import the full namespace to a facade in PHP-only files.

I generally think that you should import the full namespace (use Illuminate\Support\Facades\Config) for facades, and not the alias. I also try to limit the use of class aliases in views and opt for the global functions Laravel provides instead because aliases don't work with autocomplete in my IDE without external tooling.