Home Backend Development PHP Tutorial Laravel5.5 controller parameter passing order problem and solution

Laravel5.5 controller parameter passing order problem and solution

May 10, 2018 pm 04:34 PM
controller solution

The controller of laravel5.5 provides the ability to automatically inject based on the method parameter type. But sometimes there is a slight inconvenience, which is reflected in the fact that the injection of method parameters is not entirely based on the parameter name. If the order of the incoming parameters is changed, it will cause a type mismatch error. This article will solve the problem from an in-depth analysis of its injection principle.

1. Controller method parameter injection step design

1. Add routing in /routes/web.php

Route::get('/diary/show/{diary}/{page?}','Diary\DiaryController@list');
Copy after login

2. Write the controller file DiaryController.php and put it in Go to the path of /app/Http/Controllers/Diary/

<?php
namespace App\Http\Controllers\Diary;
use App\Http\Controllers\Controller;
class DiaryController extends Controller
{
    public function show(\App\Diary $diary,$page=11){
        var_dump($diary->title,$page); 
  } 
}
Copy after login

3. Build the model\App\Diary and install it into the database (omitted)

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Diary extends Model
{
    protected $table=&#39;diary&#39;;
    public $timestamps = false;
}
Copy after login

4. Access the controller method

Open the browser and enter: "http://127.0.0.1//diary/show/4/12"

At this time, the title field value and 12## of id=4 in the data table diary are output.

#2. Injection parameter type description

Description: Laravel will generate and inject instance objects based on the matching {diary} and {page} variables in the request route and the method parameter types required in the controller method. In the controller method,

There are three situations for different parameter types:

1. If the parameter type implements the UrlRoutable interface (that is, inherited from Illuminate\Database\Eloquent\Model), Then search the table corresponding to the model object for the record whose id value is the matching parameter value in the route, and build the model object;

2. If the parameter type is a custom type (the UrlRoutable interface is not implemented), then Laravel will construct an object and then inject it;

3. If the parameter type is a basic data type and the name is the name defined in the routing parameter, the value will be obtained from the routing parameter;

4. If the parameter type is a basic data type but the name is not defined in the routing parameter, use the default value if there is one, otherwise the system will prompt an error.

3. Analysis of current problems with injected parameters

Referring to Java's Spring MVC framework, laravel's parameter type injection still has flaws, mainly reflected in the fact that it is not injected entirely according to the parameter name.

1. If you change the order of controller parameters, a parameter type transfer error will occur. If you change the order of the parameters of the show method controlled by DiaryController, an error will occur:

<?php
namespace App\Http\Controllers\Diary;
use App\Http\Controllers\Controller;
class DiaryController extends Controller
{
    public function show($page,\App\Diary $diary){
        var_dump($diary->title,$page); 
  } 
}
Copy after login

2. Since the parameter type is a basic data type (see 2 (3)), it is not a parameter injected according to the name. Therefore, changing the code to the following will also run normally

<?php
namespace App\Http\Controllers\Diary;
use App\Http\Controllers\Controller;
class DiaryController extends Controller
{
    public function show(\App\Diary $diary,$pag){
        var_dump($diary->title,$pag); 
  } 
}
Copy after login

4. laravel5.5 controller method Parameter injection source code analysis

1. The parameter type that implements the UrlRoutable interface is constructed by the routing middleware Illuminate\Routing\Middleware\SubstituteBinding

    public function handle($request, Closure $next)
    {
        $this->router->substituteBindings($route = $request->route());
        $this->router->substituteImplicitBindings($route);
        return $next($request);
    }
Copy after login

Illuminate\Routing\Router's substituteImplicitBindings method

    public function substituteImplicitBindings($route)
    {
        ImplicitRouteBinding::resolveForRoute($this->container, $route);
    }
Copy after login

Implemented in the resolveForRoute method of Illuminate\Routing\ImplicitRouteBinding

    public static function resolveForRoute($container, $route)
    {
        //从路由参数中获取参数值,$parameters为 [&#39;diary&#39;:&#39;4&#39;,&#39;page&#39;:&#39;12&#39;]
        $parameters = $route->parameters();
        //获取控制器的函数参数列表,此处传入UrlRoutable::class,只返回实现UrlRoutable接口的参数
        $signatureParameters = $route->signatureParameters(UrlRoutable::class);
        foreach ($signatureParameters as $parameter) {
            if (! $parameterName = static::getParameterName($parameter->name, $parameters)) {
                continue;
            }
            $parameterValue = $parameters[$parameterName];
            if ($parameterValue instanceof UrlRoutable) {
                continue;
            }
            //构建模型的实例(基础自Illuminate\Database\Eloquent\Model),此处为App\Diary
            $instance = $container->make($parameter->getClass()->name);
            //将参数值绑定到模型,参加Illuminate\Database\Eloquent\Model的resolveRouteBinding方法
            if (! $model = $instance->resolveRouteBinding($parameterValue)) {
                throw (new ModelNotFoundException)->setModel(get_class($instance));
            }
       //根据参数名称注入模型实例
            $route->setParameter($parameterName, $model);
        }
    }
Copy after login

Additional instructions:

The setParameter method of the $route object (Illuminate\Routing\Route type) is called here to illustrate the model The parameter type (see 2 (1)) is injected into the model instance by matching the parameter type and parameter name at the same time

2. Other types of controller parameters are bound when running the routing controller

The key part is implemented in the dispatch method of Illuminate\Routing\ControllerDispatcher:

    public function dispatch(Route $route, $controller, $method)
    {
        //解析控制器方法的参数
        $parameters = $this->resolveClassMethodDependencies(
            $route->parametersWithoutNulls(), $controller, $method
        );
        if (method_exists($controller, &#39;callAction&#39;)) {
            //通过Illuminate\Routing\Controller的callAction调用控制器方法
            return $controller->callAction($method, $parameters);
        }
        //直接调用控制器方法
        return $controller->{$method}(...array_values($parameters));
    }
Copy after login

Call the resolveClassMethodDependencies method

  public function resolveMethodDependencies(array $parameters, ReflectionFunctionAbstract $reflector)
    {
        $instanceCount = 0;
        $values = array_values($parameters);
        //通过方法反射获取方法参数
        foreach ($reflector->getParameters() as $key => $parameter) {
        //如果有默认值则返回默认值,如果是自定义方法则构建实例返回
            $instance = $this->transformDependency(
                $parameter, $parameters
            );
            if (! is_null($instance)) {
                $instanceCount++;
                //自定义类型(未实现UrlRoutable接口)的实例注入
                $this->spliceIntoParameters($parameters, $key, $instance);
            } elseif (! isset($values[$key - $instanceCount]) &&
                      $parameter->isDefaultValueAvailable()) {
                //未在路由参数中定义,但有默认值的参数注入
                $this->spliceIntoParameters($parameters, $key, $parameter->getDefaultValue());
            }
        }
        return $parameters;
    }
Copy after login

Summary of the problem:

1. Model parameters (see 2 ( 1)) and the basic types whose names are defined in the routing parameters (see 2 (3)) must first be passed into the controller method in the order defined in the routing, otherwise a type mismatch error will occur;

2. Custom types (see 2 (2)) and basic type parameters whose names are not defined in routing parameters (see 2 (4)) are passed in in the order of appearance in the controller method.

5. Problem fix

Open the /vendor/laravel/framework/src/Illuminate/Routing/RouteDependencyResolverTrait.php file,

Modify the resolveMethodDependencies method to the following code

    public function resolveMethodDependencies(array $parameters,ReflectionFunctionAbstract $reflector){
        $methodParameters=[];
        foreach($reflector->getParameters() as $key=>$parameter){
            $name=$parameter->getName();
            $instance=$this->transformDependency($parameter, $parameters);
            if(!is_null($instance)){
                $methodParameters[]=$instance;
            }elseif(!isset($parameters[$name]) && $parameter->isDefaultValueAvailable()){
                $methodParameters[]=$parameter->getDefaultValue();
            }else{
                $methodParameters[]=isset($parameters[$name]) ? $parameters[$name] : null;
            }
        }
        return $methodParameters;
    }
Copy after login
After the modification, the controller method parameters are injected completely according to the name and type. The code becomes more concise and the function is more powerful!

If the parameter is not defined in the route and no default value is provided, null will be injected.

Related recommendations:

Detailed explanation of PHP's method of automatic dependency injection based on reflection mechanism

What is dependency injection?

How to use the corresponding interface of Laravel 5.5?

The above is the detailed content of Laravel5.5 controller parameter passing order problem and solution. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Solution for Win11 unable to install Chinese language pack Solution for Win11 unable to install Chinese language pack Mar 09, 2024 am 09:15 AM

Win11 is the latest operating system launched by Microsoft. Compared with previous versions, Win11 has greatly improved the interface design and user experience. However, some users reported that they encountered the problem of being unable to install the Chinese language pack after installing Win11, which caused trouble for them to use Chinese in the system. This article will provide some solutions to the problem that Win11 cannot install the Chinese language pack to help users use Chinese smoothly. First, we need to understand why the Chinese language pack cannot be installed. Generally speaking, Win11

Reasons and solutions for scipy library installation failure Reasons and solutions for scipy library installation failure Feb 22, 2024 pm 06:27 PM

Reasons and solutions for scipy library installation failure, specific code examples are required When performing scientific calculations in Python, scipy is a very commonly used library, which provides many functions for numerical calculations, optimization, statistics, and signal processing. However, when installing the scipy library, sometimes you encounter some problems, causing the installation to fail. This article will explore the main reasons why scipy library installation fails and provide corresponding solutions. Installation of dependent packages failed. The scipy library depends on some other Python libraries, such as nu.

An effective solution to solve the problem of garbled characters caused by Oracle character set modification An effective solution to solve the problem of garbled characters caused by Oracle character set modification Mar 03, 2024 am 09:57 AM

Title: An effective solution to solve the problem of garbled characters caused by Oracle character set modification. In Oracle database, when the character set is modified, the problem of garbled characters often occurs due to the presence of incompatible characters in the data. In order to solve this problem, we need to adopt some effective solutions. This article will introduce some specific solutions and code examples to solve the problem of garbled characters caused by Oracle character set modification. 1. Export data and reset the character set. First, we can export the data in the database by using the expdp command.

Oracle NVL function common problems and solutions Oracle NVL function common problems and solutions Mar 10, 2024 am 08:42 AM

Common problems and solutions for OracleNVL function Oracle database is a widely used relational database system, and it is often necessary to deal with null values ​​during data processing. In order to deal with the problems caused by null values, Oracle provides the NVL function to handle null values. This article will introduce common problems and solutions of NVL functions, and provide specific code examples. Question 1: Improper usage of NVL function. The basic syntax of NVL function is: NVL(expr1,default_value).

Implementing Machine Learning Algorithms in C++: Common Challenges and Solutions Implementing Machine Learning Algorithms in C++: Common Challenges and Solutions Jun 03, 2024 pm 01:25 PM

Common challenges faced by machine learning algorithms in C++ include memory management, multi-threading, performance optimization, and maintainability. Solutions include using smart pointers, modern threading libraries, SIMD instructions and third-party libraries, as well as following coding style guidelines and using automation tools. Practical cases show how to use the Eigen library to implement linear regression algorithms, effectively manage memory and use high-performance matrix operations.

Resolve Unable to start application properly error code 0xc000007b Resolve Unable to start application properly error code 0xc000007b Feb 20, 2024 pm 01:24 PM

How to solve the problem of unable to start normally 0xc000007b When using the computer, we sometimes encounter various error codes, one of the most common is 0xc000007b. When we try to run some applications or games, this error code suddenly appears and prevents us from starting it properly. So, how should we solve this problem? First, we need to understand the meaning of error code 0xc000007b. This error code usually indicates that one or more critical system files or library files are missing, corrupted, or incorrect.

Revealing the method to solve PyCharm key failure Revealing the method to solve PyCharm key failure Feb 23, 2024 pm 10:51 PM

PyCharm is a powerful Python integrated development environment that is widely loved by developers. However, sometimes we may encounter key invalidation problems when using PyCharm, resulting in the inability to use the software normally. This article will reveal the solution to PyCharm key failure and provide specific code examples to help readers quickly solve this problem. Before we start solving the problem, we first need to understand why the key is invalid. PyCharm key failure is usually due to network problems or the software itself

Common causes and solutions for Chinese garbled characters in MySQL installation Common causes and solutions for Chinese garbled characters in MySQL installation Mar 02, 2024 am 09:00 AM

Common reasons and solutions for Chinese garbled characters in MySQL installation MySQL is a commonly used relational database management system, but you may encounter the problem of Chinese garbled characters during use, which brings trouble to developers and system administrators. The problem of Chinese garbled characters is mainly caused by incorrect character set settings, inconsistent character sets between the database server and the client, etc. This article will introduce in detail the common causes and solutions of Chinese garbled characters in MySQL installation to help everyone better solve this problem. 1. Common reasons: character set setting

See all articles