laravel / tinker

Powerful REPL for the Laravel framework.
https://laravel.com/docs/artisan#tinker
MIT License
7.32k stars 130 forks source link

Contextual binding doesn't appear to work in tinker #131

Closed yamut closed 2 years ago

yamut commented 3 years ago

Description:

When using contextual binding on classes tinker does not provide the arguments correctly to the class.

Steps To Reproduce:

Repository: https://github.com/yamut/binding

Relevant files: https://github.com/yamut/binding/blob/master/app/Services/FooService.php https://github.com/yamut/binding/blob/master/app/Providers/AppServiceProvider.php https://github.com/yamut/binding/blob/master/routes/web.php

Documentation: https://laravel.com/docs/8.x/container#binding-primitives

Tinker:

Psy Shell v0.10.8 (PHP 7.4.23 — cli) by Justin Hileman
>>> app()->make(FooService::class)
[!] Aliasing 'FooService' to 'App\Services\FooService' for this Tinker session.
Illuminate\Contracts\Container\BindingResolutionException with message 'Unresolvable dependency resolving [Parameter #0 [ <required> int $a ]] in class App\Services\FooService'

When loading index using php artisan serve the output is 1 as expected.

Edit:

Running the binding in tinker does cause this to work.

Psy Shell v0.10.8 (PHP 7.4.23 — cli) by Justin Hileman
>>> app()->when(FooService::class)->needs('$a')->give(1);
=> null
>>> app()->make(FooService::class)
[!] Aliasing 'FooService' to 'App\Services\FooService' for this Tinker session.
=> App\Services\FooService {#3454
     +a: 1,
   }

This made me question if AppServiceProvider is run in tinker, which it does appear to be. Added $_SERVER['foo'] = 'bar'; to AppServiceProvider::register, and it is accessible from tinker.

Psy Shell v0.10.8 (PHP 7.4.23 — cli) by Justin Hileman
>>> $_SERVER['foo']
=> "bar"
driesvints commented 3 years ago

It's because of the aliasing. That indeed doesn't seem to be working. I can use it when I use the full namespace:

$ a tinker
Psy Shell v0.10.8 (PHP 8.0.9 — cli) by Justin Hileman
>>> app()->make(App\Services\FooService::class)
=> App\Services\FooService {#3431
     +a: 1,
   }
>>>

I looked into this a bit but have no idea why it doesn't work for the alias. Appreciating any help with figuring this out.

driesvints commented 2 years ago

Hey Yamut. Since we only received one bug report for this I'm going to close this as we don't want to put in the work/time into this ourselves right now and we don't consider this a very priority issue. Should we receive more reports for this we can have a look. Otherwise we'd appreciate PR's. Thanks

Radiergummi commented 2 years ago

Hi there, unfortunately I just hit the exact same issue - it's not a major blocker, but definitely annoying.

The fact that it works with the FQCN is very relieving though! Thanks for that.

lk77 commented 4 months ago

Hi,

i have the same issue,

when doing app(MyClass::class) or even app(FQCNofMyClass::class), the subclasses passed into the constructor of the main class are not the correct one, they should be the one from the app()->bind() but it's not the case in tinker for some reason