Laravel 路由中不固定數量引數,是如何實現的?

無銘發表於2017-12-10

最近在讀 Laravel 原始碼的時候,發現了一個段特別有趣的程式碼,大家請看:

Laravel 原始碼

... 這三個點是做什麼用的呢?我查了 PHP 的手冊後發現,這個東西叫做可變數量的引數列表

這個是幹啥用的呢?PHP 手冊是這麼解釋的。

... 是使用者自定義函式中支援可變數量的引數列表。

... 存在於 PHP 5.6 及以上的版本中。 在 PHP 5.5 及更早版本中,使用函式 func_num_args(),func_get_arg(),和 func_get_args() 。

可變數量的引數列表,這個概念可能你會覺得很抽象。

我們可以這麼來理解,我們自定義了一個函式或者某個 function,但是這個 function 的引數數量是不固定的,這也就是可變數量的引數列表。

關於可變數量的引數列表,讓我們來看兩個示例;

<?php
function sum(...$numbers) {
    $acc = 0;
    foreach ($numbers as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);
?>
複製程式碼

以上例程會輸出:

10

可變數量引數將被傳遞到 function 中,給定的引數變數會作為陣列。

我們再看一個示例:

<?php
function add($a, $b) {
    return $a + $b;
}

echo add(...[1, 2])
?>
複製程式碼

以上例程會輸出:

3

可變數量引數將被傳遞到 function 中,給定的陣列會作為引數變數。


這個可變數量引數,又和 Laravel 路由有什麼關係呢?

在 Laravel 中,我們自定義路由是非常自由的,比如是這樣的:

Route::get('user/{id}', 'UsersController@filter');

//路由對應的方法
public function filter($id)
{
    # code...
}
複製程式碼

或許有可能這樣的:

Route::get('user/{id}/{name}', 'UsersController@filter');

//路由對應的方法
public function filter($id, $name)
{
    # code...
}
複製程式碼

Laravel 路由中這樣不固定數量引數,在程式碼中是如何實現的呢?使用的就是可變數量引數。

// */vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php

/**
 * Dispatch a request to a given controller and method.
 *
 * @param  \Illuminate\Routing\Route  $route
 * @param  mixed  $controller
 * @param  string  $method
 * @return mixed
 */
public function dispatch(Route $route, $controller, $method)
{
    $parameters = $this->resolveClassMethodDependencies(
        $route->parametersWithoutNulls(), $controller, $method
    );

    if (method_exists($controller, 'callAction')) {
        return $controller->callAction($method, $parameters);
    }

    return $controller->{$method}(...array_values($parameters));
}
複製程式碼

不得不讓人佩服 Laravel 作者泰勒腦路清奇啊!

最近有人留言問我,Laravel 的路由原理是什麼?Laravel 的路由是如何分配到 Controller 中的方法中呢?

下一篇文章,我會講解 Laravel 路由的實現過程以及原理。

大家可以關注一下我的公眾號哦! :joy:

file

相關文章