megaman's avatar

strongly declared variables

When using laravel sometimes you see code which has a object type before a variable name like this

__construct(UserRepository $users)

or

post_message(StoreMessageRequest $request)

In other languages (particularly strongly typed ones) this declares the variable as an object of that specific type. would i be correct to believe that it does not do this at all in Laravel and what it does is fetch an object of that type from the service container and based on its contect populate it with other data (for example a request object would have the http request data)

0 likes
8 replies
tykus's avatar

Not quite as simple as that. What you are looking at is Dependency Injection rather than "strongly typing" variables.

Any class that is resolved out of the Container will know how to resolve its typehinted dependencies (providing it knows about them). In turn, anything needed by the dependency will also be resolved whenever that dependency is created too. This allows use to swap out the bound implementations at runtime if needed.

megaman's avatar

I did say that my belief was that it does not "strongly type" the variable and that what it actually does is dependancy injection (although i used other terms)

is this sort of type hinting laravel specific?

jlrdw's avatar

DI is pretty neat:

public function __construct(Pet $pet)

Instead of

$pet = new Pet();

@megaman if php had strongly type variables like c# or java, many php'ers would have some new learning to do.

tykus's avatar

is this sort of type hinting laravel specific?

No. Symfony uses a similar Container. Slim uses a similar approach albeit less ubiquitous

megaman's avatar

I like to use the following style synxax a lot

class myClass{

private someDependancy;

constructor(someDependancy) {
    $this->someDependancy = someDependancy
}

}

This does not use a service container. Is it still considered to be dependancy injection?

Snapey's avatar

(assuming you fix it to use $)

Yes, this is dependency injection but its not Automatic

You must pass someDependency into the constructor, and since you have not indicated what type of thing is to be passed then php cannot check it is correct.

All explained in Caleb's video

ConfusedDevelopment's avatar

PHP has the ability to have 'strongly typed' in a manner of speaking:

//Definition of Loader
interface Loader
{
    public function load();
}

//In Another file:
//This is a snippet from a class in a custom framework

public function init(): void
{
    $loaders = [
        HelperLoader::class,
        MiddlewareLoader::class,
        ViewLoader::class,
        ConfigLoader::class
    ];
    foreach ($loaders as $loader) {
//Here each instance of the above classes implement the Loader interface and are passed to the load function
        $this->load(new $loader());
    }
}

private function load(Loader $loader): void
{
    $loader->load();
}

You can ask in functions for either the Full object,

so

private function load (HelperLoader $loader)...

Or better the interface.

private function load (Loader $loader)...

If you try pass something that in the first case isn't HelperLoader, or in the second (correct) case doesn't implement Loader, php will error out.

The above is essentially what Laravel is doing, however, it uses reflection to determine what exactly to inject into the class. So if you've got a 'contract' defined in your service container that points to a concrete implementation, that will be bound to the service container and called when necessary.

Please or to participate in this conversation.