> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Facades

> Learn how Laravel facades work, how to use them, real-time facades, how to test them, and when to prefer facades over dependency injection.

## What are facades

Facades provide a "static" interface to classes that are available in your application's [service container](/en/service-container). Laravel ships with many facades that provide access to almost all of its features.

Laravel facades serve as "static proxies" to underlying classes in the service container, providing the benefit of a terse, expressive syntax while maintaining more testability and flexibility than traditional static methods.

All of Laravel's facades are defined in the `Illuminate\Support\Facades` namespace.

```php theme={null}
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Route;

Route::get('/cache', function () {
    return Cache::get('key');
});
```

<Info>
  Don't worry about fully understanding how facades work at this point. Just learn how to use them and continue learning Laravel.
</Info>

## How facades work

In a Laravel application, a facade is a class that provides access to an object from the container. The machinery that makes this work is in the `Facade` class. Laravel's facades—and any custom facades you create—will extend the base `Illuminate\Support\Facades\Facade` class.

The `Facade` base class makes use of the `__callStatic()` magic method to defer calls from your facade to an object resolved from the container.

```mermaid theme={null}
flowchart LR
    A["Cache::get('key')"] --> B["Facade::__callStatic()"]
    B --> C["getFacadeAccessor()<br>→ 'cache'"]
    C --> D["Service container<br>make('cache')"]
    D --> E["Real class instance<br>CacheManager"]
    E --> F["Execute<br>get('key')"]
```

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Cache;
use Illuminate\View\View;

class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     */
    public function showProfile(string $id): View
    {
        $user = Cache::get('user:'.$id);

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

At the top of the file, we import the `Cache` facade. This facade serves as a proxy for accessing the underlying implementation of the `Illuminate\Contracts\Cache\Factory` interface. Any calls we make using the facade will be passed to the underlying instance of Laravel's cache service.

If we look at the `Illuminate\Support\Facades\Cache` class, you'll see that there is no static method `get`:

```php theme={null}
class Cache extends Facade
{
    /**
     * Get the registered name of the component.
     */
    protected static function getFacadeAccessor(): string
    {
        return 'cache';
    }
}
```

The `Cache` facade extends the base `Facade` class and defines the `getFacadeAccessor()` method. This method returns the name of a service container binding. When a user references any static method on the `Cache` facade, Laravel resolves the `cache` binding from the service container and runs the requested method (in this case, `get`) against that object.

## When to use, and when not to use, facades

### The benefits of facades

Facades have many benefits. They provide a terse, memorable syntax that lets you use Laravel's features without having to remember long class names that must be injected or configured manually. Because of PHP's unique usage of dynamic methods, they are also very easy to test.

### Beware of scope creep

The primary risk of using facades is class "scope creep." Since facades are easy to use and don't require injection, it's easy to let your classes grow and continue to use many facades in a single class. Using dependency injection, this potential is mitigated by the visual feedback a large constructor gives you. So, when using facades, pay special attention to the size of your class so that its scope of responsibility stays narrow.

<Warning>
  If you feel your class is getting too large, consider splitting it into multiple smaller classes.
</Warning>

### Facades vs. dependency injection

One of the primary benefits of dependency injection is the ability to swap implementations of the injected class. This is useful during testing, since you can inject a mock or stub and assert that various methods were called on the stub.

Typically, it would not be possible to mock or stub a truly static class method. However, because facades use dynamic methods to proxy method calls to objects resolved from the service container, you can test facades just as you would test an injected class instance.

```php theme={null}
use Illuminate\Support\Facades\Cache;

Route::get('/cache', function () {
    return Cache::get('key');
});
```

For this route, you could write the following test to verify that `Cache::get` was called with the argument we expected:

```php theme={null}
use Illuminate\Support\Facades\Cache;

test('basic example', function () {
    Cache::shouldReceive('get')
        ->with('key')
        ->andReturn('value');

    $response = $this->get('/cache');

    $response->assertSee('value');
});
```

### Facades vs. helper functions

In addition to facades, Laravel provides a variety of "helper" functions that can perform common tasks like generating views, firing events, dispatching jobs, or sending HTTP responses. Many of these helper functions perform the same function as a corresponding facade.

```php theme={null}
// Call using the facade
return Illuminate\Support\Facades\View::make('profile');

// Equivalent call using the helper function
return view('profile');
```

There is no practical difference between facades and helper functions. When using helper functions, you can still test them exactly as you would the corresponding facade.

```php theme={null}
use Illuminate\Support\Facades\Cache;

test('cache helper test', function () {
    Cache::shouldReceive('get')
        ->with('key')
        ->andReturn('value');

    $response = $this->get('/cache');

    $response->assertSee('value');
});
```

## Real-time facades

Using real-time facades, you may treat any class in your application as if it were a facade. To illustrate how this can be used, let's first examine some code that does not use real-time facades.

For example, let's assume our `Podcast` model has a `publish` method. However, in order to publish the podcast, we need to inject a `Publisher` instance.

```php theme={null}
<?php

namespace App\Models;

use App\Contracts\Publisher;
use Illuminate\Database\Eloquent\Model;

class Podcast extends Model
{
    /**
     * Publish the podcast.
     */
    public function publish(Publisher $publisher): void
    {
        $this->update(['publishing' => now()]);

        $publisher->publish($this);
    }
}
```

Using real-time facades, we can maintain the same testability while not being required to explicitly pass a `Publisher` instance. To generate a real-time facade, prefix the namespace of the imported class with `Facades`.

```php theme={null}
<?php

namespace App\Models;

use Facades\App\Contracts\Publisher;
use Illuminate\Database\Eloquent\Model;

class Podcast extends Model
{
    /**
     * Publish the podcast.
     */
    public function publish(): void
    {
        $this->update(['publishing' => now()]);

        Publisher::publish($this);
    }
}
```

When the real-time facade is used, the publisher implementation will be resolved from the service container using the portion of the interface or class name that appears after the `Facades` prefix.

```php theme={null}
<?php

use App\Models\Podcast;
use Facades\App\Contracts\Publisher;
use Illuminate\Foundation\Testing\RefreshDatabase;

pest()->use(RefreshDatabase::class);

test('podcast can be published', function () {
    $podcast = Podcast::factory()->create();

    Publisher::shouldReceive('publish')->once()->with($podcast);

    $podcast->publish();
});
```

<Tip>
  Real-time facades are useful when you want to keep tests easy to mock while removing the need to pass the dependency as an argument.
</Tip>

## Testing facades

To test a facade, use the `shouldReceive` method, which returns a Mockery mock instance. Because facades are actually resolved and managed by the service container, they're far more testable than typical static classes.

```php theme={null}
use Illuminate\Support\Facades\Cache;

test('display user profile', function () {
    Cache::shouldReceive('get')
        ->once()
        ->with('user:1')
        ->andReturn(['name' => 'Taylor']);

    $response = $this->get('/users/1');

    $response->assertSee('Taylor');
});
```

Commonly used mock methods:

| Method                    | Description                                    |
| ------------------------- | ---------------------------------------------- |
| `shouldReceive('method')` | Expect the method to be called                 |
| `once()`                  | Expect it to be called exactly once            |
| `times(n)`                | Expect it to be called n times                 |
| `with(args)`              | Expect it to be called with specific arguments |
| `andReturn(value)`        | Return the given value                         |
| `andReturnNull()`         | Return null                                    |

## Key facades reference

A mapping of commonly used facades to their underlying classes and service container bindings:

| Facade         | Class                                     | Binding      |
| -------------- | ----------------------------------------- | ------------ |
| `App`          | `Illuminate\Foundation\Application`       | `app`        |
| `Auth`         | `Illuminate\Auth\AuthManager`             | `auth`       |
| `Cache`        | `Illuminate\Cache\CacheManager`           | `cache`      |
| `Config`       | `Illuminate\Config\Repository`            | `config`     |
| `Cookie`       | `Illuminate\Cookie\CookieJar`             | `cookie`     |
| `Crypt`        | `Illuminate\Encryption\Encrypter`         | `encrypter`  |
| `DB`           | `Illuminate\Database\DatabaseManager`     | `db`         |
| `Event`        | `Illuminate\Events\Dispatcher`            | `events`     |
| `File`         | `Illuminate\Filesystem\Filesystem`        | `files`      |
| `Gate`         | `Illuminate\Contracts\Auth\Access\Gate`   | —            |
| `Hash`         | `Illuminate\Contracts\Hashing\Hasher`     | `hash`       |
| `Http`         | `Illuminate\Http\Client\Factory`          | —            |
| `Log`          | `Illuminate\Log\LogManager`               | `log`        |
| `Mail`         | `Illuminate\Mail\Mailer`                  | `mailer`     |
| `Notification` | `Illuminate\Notifications\ChannelManager` | —            |
| `Queue`        | `Illuminate\Queue\QueueManager`           | `queue`      |
| `RateLimiter`  | `Illuminate\Cache\RateLimiter`            | —            |
| `Redirect`     | `Illuminate\Routing\Redirector`           | `redirect`   |
| `Request`      | `Illuminate\Http\Request`                 | `request`    |
| `Route`        | `Illuminate\Routing\Router`               | `router`     |
| `Schema`       | `Illuminate\Database\Schema\Builder`      | —            |
| `Session`      | `Illuminate\Session\SessionManager`       | `session`    |
| `Storage`      | `Illuminate\Filesystem\FilesystemManager` | `filesystem` |
| `URL`          | `Illuminate\Routing\UrlGenerator`         | `url`        |
| `Validator`    | `Illuminate\Validation\Factory`           | `validator`  |
| `View`         | `Illuminate\View\Factory`                 | `view`       |

## Next steps

<Card title="Contracts" icon="file-contract" href="/en/contracts">
  Learn about Contracts and how they complement facades.
</Card>


## Related topics

- [Package Static Analysis (PHPStan / Larastan)](/en/advanced/package-static-analysis.md)
- [Laravel Package Development](/en/advanced/package-development.md)
- [Contracts](/en/contracts.md)
- [Mocking](/en/mocking.md)
- [Service container](/en/service-container.md)
