DIY 實現 ThinkPHP 核心框架 (十三)利用反射實現引數繫結

cn-five發表於2020-09-07

什麼是反射?

它是指在 PHP 執行狀態中,擴充套件分析 PHP 程式,匯出或提取出關於類、方法、屬性、引數等的詳細資訊,包括註釋。這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為 反射 API 。主要用於框架或外掛的開發。

修改 core/src/think/Container.php 中的 invokeClass() 方法。

    public function invokeClass (string $class, array $vars = [])
    {
        // 獲取反射類
        $reflect = new ReflectionClass($class);
        // 獲取構造方法
        $constructor = $reflect->getConstructor();
        // 利用 bindParams 繫結引數
        $args = $constructor ? $this->bindParams($constructor, $vars) : [];
        // 例項化
        return $reflect->newInstanceArgs($args);
    }

編寫 bindParams() 方法,實現引數繫結

    protected function bindParams(ReflectionFunctionAbstract $reflect, array $vars = []): array
    {
        // 如果需要例項化的類沒有引數設定,就直接返回空陣列
        if ($reflect->getNumberOfParameters() == 0) {
            return [];
        }
        $args   = [];
        // 獲取引數資訊
        $params = $reflect->getParameters();
        foreach ($params as $param) {
            $name = $param->getName();
            if (isset($vars[$name])) {
                $args[] = $vars[$name];
                // 如果沒有引數,就使用預設值
            } elseif ($param->isDefaultValueAvailable()) {
                $args[] = $param->getDefaultValue();
            }
        }
        return $args;
    }

Request 類中定義構造方法用於測試

public function __construct(string $addr, string $forum, string $lang)
    {
        echo '論壇網址是:' . $addr . '<br />';
        echo '論壇名稱是:' . $forum . '<br />';
        echo '技術語言是:' . $lang . '<br />';
    }

Index 控制器編寫 show() 方法,測試繫結引數的功能

public function show ()
    {
        \think\Container::get('request', ['addr' => 'https://learnku.com/php',  'forum' => 'PHP 技術論壇', 'lang' => 'PHP'], true);
    }

訪問 diy.tp ,成功輸出

論壇網址是:https://learnku.com/php
論壇名稱是:PHP 技術論壇
技術語言是:PHP
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章