Fixing Laravel / PHP 8 “Error : Unknown named parameter” error

PHP 8 changed the way call_user_func and friends work which can affect Laravel’s routing, causing a “Unknown named parameter” error.(https://wiki.php.net/rfc/named_params#call_user_func_and_friends)

This means that if you had a Controller that received parameters, but the route captured more parameters than your method receives you would get this error.

Something like this will reproduce it:

class MyServiceProvider extends ServiceProvider
{
  public function boot(Router $router)
  {
    Route::get("foo/{path}", [MyController::class, 'get'])->where('path', '(.*)');
  }
}

class MyController extends Controller
{
  public function get(Request $request)
  {
    // Something here
  }
}

In this example, the {path} parameter is being captured so that it can be used in the where fluent method. However, this parameter isn’t actually used by the Controller.

Laravel (v8.9) will call this controller method using call_user_func_array([MyController::class, 'get'], ['request' => Request, 'path' => 'xyz'])

In PHP 7 and below this would work, because keys in the second argument were ignored. In PHP 8 they are not ignored and PHP will run something along the lines of $controller->get($request, $path);

This behaviour is fixed in Laravel’s php-8-builds branch, so will work fine in a future Laravel version.

However, if you upgrade to PHP 8 but you can’t upgrade Laravel, there’s a simple fix to your controller to override callAction like this:

class MyController extends Controller
{
  public function get(Request $request)
  {
    // Something here
  }
  
  public function callAction($method, $parameters)
    {
        return parent::callAction($method, array_values($parameters));
    }
}

This will provide the parameters in a way that is compatible with PHP 8.

Comments