In my AppServiceProvider.php
I tried binding a singleton interface to a concrete class using the array syntax:
class AppServiceProvider extends ServiceProvider
{
public $singletons = [
MyClassInterface::class => MyClass::class,
];
}
The interface is then typehinted in a class.
This gives an error like:
TypeError: TheClassThatUsesTheService::__construct(): Argument #2 ($myClass) must be of type MyClassInterface, string given
The errors disspears if I make a manual singleton binding using a closure:
class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind(MyClassInterface::class, function () {
return new MyClass;
});
}
}
Should this not behave the same?
MyClass.php:
<?php
class MyClass extends Base implements MyClassInterface
{
public function get(): mixed
{
//
}
public function insert(): void
{
//
}
}
MyClassInterface.php:
<?php
interface MyClassInterface
{
public function get(): mixed;
public function insert(): void;
}
Base.php:
class Base
{
protected function service()
{
//
}
}
My Answer:
The issue you are facing is because when you use the array syntax to define singletons in the $singletons property of the AppServiceProvider, Laravel expects the value to be a string representing the concrete class name. So when you try to inject the MyClassInterface into a class, Laravel is actually injecting the string MyClass instead of an instance of MyClass.
To fix this issue, you can define the singleton bindings in the register method of the AppServiceProvider using the array syntax like this:
php
class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(MyClassInterface::class, MyClass::class);
}
}
This way, Laravel will correctly bind the MyClassInterface to an instance of MyClass when it is injected into a class.
Alternatively, you can continue using the closure syntax as you have shown in your second example, which also works correctly. Both methods should behave the same way and achieve the desired result.
Rate this post
4 of 5 based on 7238 votesComments