Reputation: 6674
I'm asking/answering because I have had so much trouble getting this working and I'd like to show a step-by-step implementation.
References:
Upvotes: 6
Views: 3928
Reputation: 6674
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.
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!';
}
}
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
}
}
getFacadeAccessor
as you will need that in a moment.Also note that you are extending the existing Facade class here.
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;
});
}
}
Foobar\Foo
and not Foobar\Facades\Foo
- your IDE might suggest the wrong completion.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
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
}
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
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:
Foobar\Facades\Foo
, try running php artisan optimize
Upvotes: 14