SPONSORS

Deploy Your Apps on AWS Cloud
1588 views · 211 days ago

![Custom extension to Laravel Application class](https://images.ctfassets.net/vzl5fkwyme3u/505z7itnLO8suUC6oGMmKq/fa48e59682497e2480e9f1822ec8a498/AdobeStock_184180246.jpeg?w=1000)

Hello folks! This post is for those of you using Laravel. This beautiful framework makes web development super-easy compared to most of competitors. In the heart of Laravel is the Application class, which is responsible for bootstrapping, registering services and also serves as a dependency injection container. What I do with my Laravel apps, is that I take a slight detour from the common path by adding a custom Application class. While this is not really necessary, I find this approach nice, and will try to share my thought below.

It's normal practice in Laravel world to build all kinds of objects like this:

```php

$cache = app("cache");

```

I find it a bit confusing to call `app("cache"")` and expect a `Cache\Repository` instance as result. If I pass the result of this call to a function that requires a `Cache\Repository` as parameter, I will probably have a code inspection warning from IDE. Moreover, if I want proper autocompletion, I will have to add additional comment:

```php

/ ** @var \Illuminate\Contracts\Cache\Repository */

$cache = app("cache");

```

This is where a custom application class might be handy:

```php

namespace App;

class MyApp extends Application

{

public function cacheRepository(): Repository

{

return $this->make(Repository::class);

}

}

```

This way I get a `TypeError` in case of a misconfiguration, and I have a type-hint which allows the IDE to recognize the return value. Bye-bye nasty comment lines and IDE warnings! I make a method per service, with type-hints, like `dbConnection()` or `viewFactory()` - works really well for me!

I also thought that, if I have a custom class, then all the custom setup that normally you have in `bootstrap/app.php`, should reside in that custom class:

```php

namespace App;

class MyApp extends Application

{

public function __construct()

{

define('LARAVEL_START', microtime(true));

define("APP_ROOT", realpath(__DIR__ . "/../"));

parent::__construct(APP_ROOT);

$this->setUp();

}

private function setUp()

{

/ / all the stuff from bootstrap/app.php, goes here

$this->singleton(

Contracts\Http\Kernel::class,

\App\Http\Kernel::class

);

}

}

```

Then your `bootstrap/app.php` becomes just this:

```php

return new \App\MyApp;

```

The Laravel `app()` function will also return an instance of MyApp from now on. However, it's @phpdoc says it returns `\Illuminate\Foundation\Application`, so for better clarity, I also added my own accessor method:

```php

namespace App;

class MyApp extends Application

{

public static function app(): self

{

/ ** @var self $ret */

$ret = parent::getInstance();

return $ret;

}

}

```

I tend to limit the use of global/static functions and methods, but sometimes it can be handy, and whenever I need an instance of MyApp, I just call `MyApp::app()`. The IDE wil be aware of the return type due to the type-hint, so I get everything I want for clean and clear development.

With your projects in Laravel, you may or may not want to follow this particular advice, but just be aware that extending a framework built-in classes for your team's comfort, is definitely something that can make your life easier. See you around, don't forget to leave comments!

SPONSORS

Faster PHP Cloud Hosting