使用Container類實現ThinkPHP核心框架

使用Container類實現ThinkPHP核心框架

相關推薦:thinkphp

thinkphp 的 container 類提供了靜態方法 get() ,可以根據類名或類的別名獲取實例,會保持創建完成的實例,避免重復創建。下面實現這個方法,修改 container.php ,添加以下代碼。

//?????*?ThinkPHP?5?與?6?在此處參數一致//?????*?@param?string?$abstract//?????*?@param?array?$vars//?????*?@param?bool?$newInstance//?????*/ ????public?static?function?get(string?$abstract,?array?$vars?=?[],?bool?$newInstance?=?false) ????{ ????????return?static::getInstance()->make($abstract,?$vars,?$newInstance); ????}

編寫 getInstance() 方法,并新增靜態屬性 $instance 保存自身實例。

protected?static?$instance;public?static?function?getInstance() ????{ ????????//?創建自身實例 ????????if?(is_null(static::$instance))?{ ????????????static::$instance?=?new?static; ????????} ????????return?static::$instance; ????}

編寫 make() 方法。

public?function?make?(string?$abstract,?array?$vars?=?[],?bool?$newInstance?=?false) ????{ ????????//?這里的?$abstract?是包含有命名空間的類名 ????????if?(isset($this->bind[$abstract]))?{ ????????????$abstract?=?$this->bind[$abstract]; ????????}  ????????//?如果已經實例化直接返回 ????????if?(isset($this->instances[$abstract])?&&?!$newInstance)?{ ????????????return?$this->instances[$abstract]; ????????}  ????????//?如果就創建 ????????$object?=?$this->invokeClass($abstract,?$vars);  ????????//?保存實例 ????????if?(!$newInstance)?{ ????????$this->instances[$abstract]?=?$object; ????????}  ????????return?$object; ????}

創建保存屬性的別名數組 $bind

????protected?$bind?=?[ ????????'app'?=>?App::class, ????????'config'?=>?Config::class, ????????'request'?=>?Request::class ????];

編寫 invokeClass() 方法

立即學習PHP免費學習筆記(深入)”;

public?function?invokeClass?(string?$class,?array?$vars?=?[]) ????{ ????????//?$vars?為構造函數的參數 ????????return?new?$class(); ????}

修改入口文件 index.php

require?__DIR__?.?'/../core/base.php';use?thinkRequest;$req?=?thinkContainer::get('request');var_dump($req?instanceof?Request);

輸出 bool(true) 表示 get() 方法功能正常。

也可以利用魔術方法 __get() 和 __set() ,實現外部對象直接操作容器實例。

????public?function?__get($abstract) ????{ ????????//?返回容器的類實例 ????????return?$this->make($abstract); ????}public?function?__set($abstract,?$instance) ????{ ????????if?(isset($this->bind[$abstract]))?{ ????????????$abstract?=?$this->bind[$abstract]; ????????} ????????//?裝入容器 ????????$this->instances[$abstract]?=?$instance; ????}

在 index.php 進行測試

$container?=?thinkContainer::getInstance();//?獲取容器中的實例,輸出對象var_dump($container->request);//?裝入容器$container->contianerName?=?$container;var_dump($container->contianerName);

輸出 object(thinkRequest) 表示成功

想了解更多編程學習,敬請關注php培訓欄目!

? 版權聲明
THE END
喜歡就支持一下吧
點贊11 分享