I have a question regarding the use of $this inside a Laravel routing.
Recently I'm trying to find a way to pass PHP variables between Route::group() and Route::get/put/post/anything-that-fits-inside-the-group(). So I tried to Google my way out and found most of the results always related to passing variable between routes and view (which is not the case). This result were closest to -- if not exactly -- what I'm trying to achieve, stating that variable passing can't be done in such way.
During my curiosity over this topic, I fiddled around with the routes, trying to pass the PHP variables between routes in a few ways until I found a solution to this case: by using $this
Here's a bit of my code just to give you some context:
...
Route::prefix("api")->middleware("verify_api_call")->group( function(){
[$this->success, $this->message, $this->data] = [false, "", null];
$this->ctx = [
"success" => &$this->success,
"message" => &$this->message,
"data" => &$this->data
];
Route::get("test", function(){
$this->success = true;
$this->message = "ok";
$this->data = [
"somekey" => "somevalue"
];
return response()->json(["Contextual" => $this->ctx, "All of this" => $this]);
});
...
Calling mysite.com/api/test gives the expected result as below:
{
"Contextual": {
"success": true,
"message": "ok",
"data": {
"somekey": "somevalue"
}
},
"All of this": {
"success": true,
"message": "ok",
"data": {
"somekey": "somevalue"
},
"ctx": {
"success": true,
"message": "ok",
"data": {
"somekey": "somevalue"
}
}
}
}
Now the question might be no longer about how it works, but rather: will there be any unexpected problems that I'm unaware of if I keep using $this this way?
CodePudding user response:
TL;DR; Yes, you could cause undefined behaviour in future.
You're basically storing your custom variables on an instance of the class:
Illuminate\Routing\RouteFileRegistrar
And currently, said Class has only $router field, and each Group creates a new instance of said Class for itself.
But in future Laravel versions, said Class may have additional fields, which you may override by accident, or it could entirely change to another Class.
So, for now you are good to go, but consider using function () use($ctx) {} syntax instead, like:
Route::prefix("api")->middleware("verify_api_call")->group( function(){
[$success, $message, $data] = [false, "", null];
$ctx = [
"success" => & $success,
"message" => & $message,
"data" => & $data
];
Route::get("test", function() use($ctx) {
$ctx->success = true;
$ctx->message = "ok";
$ctx->data = [
"somekey" => "somevalue"
];
return response()->json(["Contextual" => $ctx]);
});
});
CodePudding user response:
You are creating public dynamic properties on an object of class you don't control.
Two immediate problems:
The API of the class could change in the future, and your chosen properties may clash with whatever the class creator chooses.
Dynamic properties will be deprecated by PHP 8.2, and removed by PHP 9.0. So unless the class maintainer adds code to allow for developers to add random dynamic properties, your code will fail by then.
It's a bad idea and poor design.
