<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                我們來詳細的描述一下: 首先我們假設A依賴B和C,B依賴D,C依賴E,D依賴F,現在我們來看看怎么實例化A? ~~~ $a = new A(new B(new D(new F)), new C(new E())); ~~~ 是不是感覺要崩潰了,實例化A之前就得先知道它依賴哪些類。 從一開始我們為了解決依賴的問題,到現在依賴卻成了最棘手的問題,怎么辦? 有人提出:如果我們也有一個類似composer的管理容器,在實例化A的時候,能夠解決各個類之間的依賴問題是不是就很ok了? 沒錯,就是這樣。 php有一個IoC容器的概念,其作用,就是幫助我們解決這個問題。 IoC容器又是什么?所謂的IoC容器呢,并沒有多么高大上,它其實就是一個類,為了解決依賴問題,IoC應該提供如下功能: 存儲定義的類 實例化類 下面來看一個簡版的實現 ~~~ Class Container { private $_definitions; public function set($class, $definition) { $this->_definitions[$class] = $definition; } public function get($class, $params = []) { $definition = $this->_definitions[$class]; return call_user_func($definition, $params); } } ~~~ Container類封裝的很簡單,set方法用于存儲類,get用于實例化類。 還以上一節用戶發送郵件為例 ~~~ class EmailSenderBy163 { private $_name; public function __construct($name = '') { $this->_name = $name; } public function send() { } } ~~~ 我們看一下如何借用IoC容器操作 ~~~ $container = new Container; $container->set('EmailSenderBy163', function ($name = '') { return new EmailSenderBy163($name); }); $emailSenderBy163 = $container->get('EmailSenderBy163', '163'); echo "<pre>"; print_r($emailSenderBy163); ~~~ 結果 ~~~ EmailSenderBy163 Object ( [_name:EmailSenderBy163:private] => 163 ) ~~~ 簡單分析下上面代碼的含義 首先我們定義了一個容器類 Container 定義了一個私有屬性 $_definitions, 用于保存定義的類 set 方法,添加類及其定義到 $_definitions 屬性中,第一個參數是類名,第二個參數這里是一個回調函數,用于創建類 $class get 方法,傳遞類名,通過 屬性 $_definitions 找到類的定義,并調用 call_user_func 函數調用該定義, 第二個參數 $params 是set時第二個參數即回調函數的參數 當然,這只是一個簡版的實現 下面我們擴展一下,如果要實現有依賴其他對象的類,該如何實現呢? 我們把Container的get方法整理一下 ~~~ Class Container { private $_definitions; public function set($class, $definition) { $this->_definitions[$class] = $definition; } public function get($class, $params = []) { if (isset($this->_definitions[$class]) && is_callable($this->_definitions[$class], true)) { $definition = $this->_definitions[$class]; return call_user_func($definition, $this, $params); } else { throw new Exception("error"); } } } ~~~ 注意同剛才的get方法的區別。相比于簡版的實現,get方法在判斷回調函數上趨于嚴謹。 User類定義如下 ~~~ class User { private $_emailSenderObject; public function __construct(EmailSenderBy163 $emailSenderObject) { $this->_emailSenderObject = $emailSenderObject; } public function register() { // other code $this->_emailSenderObject->send(); } } ~~~ 注意看User類,我們想在實例化User的時候,通過構造函數“注入” EmailSenderBy163 的對象,并賦值給User::$_emailSenderObject屬性。 來看看此時我們應該如何用Container實例化 EmailSenderBy163 和 User 。 ~~~ $container = new Container; $container->set('EmailSenderBy163', function ($container, $name = '') { return new EmailSenderBy163($name); }); $container->set('User', function ($container, $params = []) { return new User($container->get($params[0], $params[1])); }); echo '<pre>'; print_r($container->get('EmailSenderBy163', ['163'])); print_r($container->get('User', ['EmailSenderBy163', '163'])); ~~~ 結果 ~~~ EmailSenderBy163 Object ( [_name:EmailSenderBy163:private] => Array ( [0] => 163 ) ) User Object ( [_emailSenderObject:User:private] => EmailSenderBy163 Object ( [_name:EmailSenderBy163:private] => 163 ) ) ~~~ 似乎沒什么問題,一個類依賴的其他對象我們也解決了。 但是如果我們要解決文中一開始拋出的問題,還是需要先把所有的類全部set進去,然后get的時候指定其所依賴的類,依然很麻煩。 上一節文末我們讓大家課后看一下反射的知識,不知道你熟不熟悉? 我們簡單的聊兩句:反射,是php5增加的功能,通過反射,可以導出或提取出關于類、方法、屬性、參數等的詳細信息。 也就是說,我們可以利用反射相關的一系列API,來分析類所依賴的對象,并做自動實例化處理。 限于篇幅,反射相關的API我們就不多做介紹了,不熟悉的可以看一下手冊,了解即可。 下面我們基于反射,讓我們的Container更強悍一些。 ~~~ Class Container { public function get($class, $params = []) { return $this->build($class, $params); } public function build($class, $params) { $dependencies = []; $reflection = new ReflectionClass($class); $constructor = $reflection->getConstructor(); if ($constructor !== null) { foreach ($constructor->getParameters() as $param) { $c = $param->getClass(); if ($c !== null) { $dependencies[] = $this->get($c->getName(), $params); } } } foreach ($params as $index => $param) { $dependencies[$index] = $param; } return $reflection->newInstanceArgs($dependencies); } } ~~~ 同樣是User類,現在我們可以這樣實例化了 ~~~ $container = new Container; $user = $container->get('User'); echo '<pre>'; print_r($user); ~~~ 結果 ~~~ User Object ( [_emailSenderObject:User:private] => EmailSenderBy163 Object ( [_name:EmailSenderBy163:private] => ) ) ~~~ # 完整的例子 ~~~ <?php class Container { public function get($class, $params = []) { return $this->build($class, $params); } public function build($class, $params) { $dependencies = []; $reflection = new ReflectionClass($class); $constructor = $reflection->getConstructor(); if ($constructor !== null) { foreach ($constructor->getParameters() as $param) { $c = $param->getClass(); if ($c != null) { $dependencies[] = $this->get($c->getName(), $params); } } } if (isset($params[$class])) { $param = $params[$class]; foreach ($param as $index => $value) { $dependencies[$index] = $value; } unset($params[$class]); } return $reflection->newInstanceArgs($dependencies); } } class SendQQ { private $name; public function __construct($name = '未知') { $this->name = $name; } public function send() { echo "發消息給 {$this->name} \n"; } } class User { private $SendQQ; public function __construct(SendQQ $SendQQ) { $this->SendQQ = $SendQQ; } public function register() { $this->SendQQ->send(); // echo "User中的register方法 \n"; } } class login { private $obj; public function __construct(User $user) { $this->obj = $user; } public function login() { echo "login類中login方法 \n"; } } class Test { private $_login; private $_user; public $_message; public function __construct(login $login, User $user, $message) { $this->_login = $login; $this->_user = $user; $this->_message = $message; } public function test() { $this->_user->register(); echo "\n message的值是: {$this->_message} \n"; // echo "test類中test方法 \n"; } } $Container = new Container(); $Test = $Container->get('Test', ['SendQQ' => ['name' => 'jdxia'], 'Test' => ['message' => '成功']]); $Test->test(); print_r($Test); ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看