This may not be the only way to implement facades in Laravel 5, but here is how I did it.
We're going to create a custom Foo
facade available in the Foobar
namespace.
1. Create a custom class
First, for this example, I will be creating a new folder in my project. It will get its own namespace that will make it easier to find.
In my case the directory is called Foobar:
In here, we'll create a new PHP file with our class definition. In my case, I called it Foo.php
.
<?php
// %LARAVEL_ROOT%/Foobar/Foo.php
namespace Foobar;
class Foo
{
public function Bar()
{
return 'got it!';
}
}
2. Create a facade class
In our fancy new folder, we can add a new PHP file for our facade. I'm going to call it FooFacade.php
, and I'm putting it in a different namespace called Foobar\Facades. Keep in mind that the namespace in this case does not reflect the folder structure!
<?php
// %LARAVEL_ROO%/Foobar/FooFacade.php
namespace Foobar\Facades;
use Illuminate\Support\Facades\Facade;
class Foo extends Facade
{
protected static function getFacadeAccessor()
{
return 'foo'; // Keep this in mind
}
}
- Bear in mind what you return in
getFacadeAccessor
as you will need that in a moment.
Also note that you are extending the existing Facade class here.
3. Create a new provider using php artisan
So now we need ourselves a fancy new provider. Thankfully we have the awesome artisan
tool. In my case, I'm gonna call it FooProvider
.
php artisan make:provider FooProvider
Bam! We've got a provider. Read more about service providers here. For now just know that it has two functions (boot
and register
) and we will add some code to register
. We're going to bind our new provider our app:
$this->app->bind('foo', function () {
return new Foo; //Add the proper namespace at the top
});
So this bind('foo'
portion is actually going to match up with what you put in your FooFacade.php
code. Where I said return 'foo';
before, I want this bind to match that. (If I'd have said return 'wtv';
I'd say bind('wtv',
here.)
Furthermore, we need to tell Laravel where to find Foo
!
So at the top we add the namespace
use \Foobar\Foo;
Check out the whole file now:
<?php
// %LARAVEL_ROOT%/app/Providers/FooProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Foobar\Foo;
class FooProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->app->bind('foo', function () {
return new Foo;
});
}
}
- Make sure you use
Foobar\Foo
and not Foobar\Facades\Foo
- your IDE might suggest the wrong completion.
4. Add our references to config/app.php
Now we have to tell Laravel we're interested in using these random files we just created, and we can do that in our config/app.php
file.
Add your provider class reference to 'providers'
: App\Providers\FooProvider::class
Add your facade class reference to 'aliases'
: 'Foo' => Foobar\Facades\Foo::class
Remember, in aliases, where I wrote 'Foo'
, you will want to put the name you want to reference your facade with there. So if you want to use MyBigOlFacade::helloWorld()
around your app, you'd start that line with 'MyBigOlFacade' => MyApp\WhereEverMyFacadesAre\MyBigOlFacade::class
5. Update your composer.json
The last code change you should need is to update your composer.json
's psr-4
spaces. You will have to add this:
"psr-4": {
"Foobar\\" : "Foobar/",
// Whatever you had already can stay
}
Final move
Okay so now that you have all that changed, the last thing you need is to refresh the caches in both composer and artisan. Try this:
composer dumpautoload
php artisan cache:clear
Usage & A Quick Test:
Create a route in app/routes.php
:
Route::get('/foobar', 'FooBarController@testFoo');
Then run
php artisan make:controller FooBarController
And add some code so it now looks like this:
<?php
namespace App\Http\Controllers;
use Foobar\Facades\Foo;
use App\Http\Requests;
class FooBarController extends Controller
{
public function testFoo()
{
dd(Foo::Bar());
}
}
You should end up with the following string:
Troubleshooting
- If you end up with and error saying it cannot find the class
Foobar\Facades\Foo
, try running php artisan optimize
artisan optimize
command – Martin Mar 2 '16 at 20:45Foobar\Join;
? And unfortunately all I get as the end result isClass 'Foobar\Facades\Foo' not found
. Followed the directions down the the letter. – Jiho Kang Aug 23 '16 at 6:05