This code will give this error: (all routes of this controller are api protected)
"Maximum function nesting level of '200' reached, aborting!"
class UserController {
use Helpers;
public function __construct()
{
$this->user = $this->user(); // WHY? No problem if we use "this->user()" without injecting in the constructor
}
public function me()
{
return $this->item($this->user, UserTransformer::class);
}
public function update(Request $request)
{
$this->user->update($request->all());
return $this->item($this->user, UserTransformer::class);
}
}
Why is this? I'm using last versions of laravel and dingo
Are you sure it was supposted to work with class string. In the wiki you will find like this
return $this->response->item($user, new UserTransformer);
@catalinux Yes, but it doesn't matter, is an example code, the problem is in the constructor.
You have an infinite loop there.
You cant use $this->user() on __construct method because it will be recursive. This errors occurs only if the user variable isn't set and if the user isn't authenticated.
Keep in mind that at this point the route object doesn't exist yet. So the API try to authenticate the user (https://github.com/dingo/api/blob/master/src/Auth/Auth.php#L151) that will try to use each provider available (https://github.com/dingo/api/blob/master/src/Auth/Auth.php#L82) to do so. This authenticate function expects as parameter 2 the current route (that doesn't exist remember?).
So the function $this->router->getCurrentRoute() called as parameter 2 take us to Router.php calling $this->createRoute($route) (https://github.com/dingo/api/blob/master/src/Routing/Router.php#L691) that creates a new Route object (https://github.com/dingo/api/blob/master/src/Routing/Router.php#L713).
In this point tracking the Route object and its construct method it calls $this->setupRouteProperties($request, $route) (https://github.com/dingo/api/blob/master/src/Routing/Route.php#L144) that calls $this->mergeControllerProperties() (https://github.com/dingo/api/blob/master/src/Routing/Route.php#L167) that finally calls $this->makeControllerInstance() (https://github.com/dingo/api/blob/master/src/Routing/Route.php#L186).
So makeControllerInstance method is making a new instance of our controller (https://github.com/dingo/api/blob/master/src/Routing/Route.php#L325) that's call our __construct method again, that fires $this->user() again, and the stack begins again.
This will be recursive until the max stack on nesting level in xDebug be reached that for you is 200 (but for me is 256). BTW you can deactivate xDebug or set the maximum nesting level in the php.ini higher using xdebug.max_nesting_level=500 for example.
So this proves that you can't use $this->user() on __construct method.
But the real question is WHY you need to use that or even set it to a user property when the Helpers trait dynamic offers you that user property by magic method __get as an alias for user() method?
@tembra Thx from your great explanation.
I did not know that "user" property exists (magic method), so I had more methods in the controller that I need the "user" object, that's why I initialized the user property to user method.
Excellent explanation @tembra, thanks for your replies to many of these issues. Very helpful. :+1:
I do need to clear a lot of these little confusing errors up though by noting it in the docs. One day.
Most helpful comment
You have an infinite loop there.
You cant use
$this->user()on__constructmethod because it will be recursive. This errors occurs only if theuservariable isn't set and if the user isn't authenticated.Keep in mind that at this point the route object doesn't exist yet. So the API try to authenticate the user (https://github.com/dingo/api/blob/master/src/Auth/Auth.php#L151) that will try to use each provider available (https://github.com/dingo/api/blob/master/src/Auth/Auth.php#L82) to do so. This
authenticatefunction expects as parameter 2 the current route (that doesn't exist remember?).So the function
$this->router->getCurrentRoute()called as parameter 2 take us toRouter.phpcalling$this->createRoute($route)(https://github.com/dingo/api/blob/master/src/Routing/Router.php#L691) that creates a newRouteobject (https://github.com/dingo/api/blob/master/src/Routing/Router.php#L713).In this point tracking the
Routeobject and its construct method it calls$this->setupRouteProperties($request, $route)(https://github.com/dingo/api/blob/master/src/Routing/Route.php#L144) that calls$this->mergeControllerProperties()(https://github.com/dingo/api/blob/master/src/Routing/Route.php#L167) that finally calls$this->makeControllerInstance()(https://github.com/dingo/api/blob/master/src/Routing/Route.php#L186).So
makeControllerInstancemethod is making a new instance of our controller (https://github.com/dingo/api/blob/master/src/Routing/Route.php#L325) that's call our__constructmethod again, that fires$this->user()again, and the stack begins again.This will be recursive until the max stack on nesting level in xDebug be reached that for you is 200 (but for me is 256). BTW you can deactivate xDebug or set the maximum nesting level in the php.ini higher using
xdebug.max_nesting_level=500for example.So this proves that you can't use
$this->user()on__constructmethod.But the real question is WHY you need to use that or even set it to a
userproperty when the Helpers trait dynamic offers you thatuserproperty by magic method__getas an alias foruser()method?