<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] * * * * * ## 1 Container實現 ### 0 實現文件 ~~~ /lirary/think/Container.php ~~~ ### 1 核心方法 #### bind() 注冊內容到容器 ~~~ public function bind($abstract, $concrete = null) { if (is_array($abstract)) { $this->bind = array_merge($this->bind, $abstract); } elseif ($concrete instanceof \Closure) { $this->bind[$abstract] = $concrete; } elseif (is_object($concrete)) { $this->instances[$abstract] = $concrete; } else { $this->bind[$abstract] = $concrete; } return $this; } ~~~ > 主要分為四種綁定 > * 批量綁定 > * 閉包綁定 > * 對象綁定 > * 類標識/接口綁定 > 其中對象綁定添加綁定內容到Container的instances。 > 其他三種綁定添加綁定內容到Container的bind中 * * * * * #### make() 獲取綁定內容 ~~~ public function make($abstract, $vars = [], $newInstance = false) { if (true === $vars) { // 總是創建新的實例化對象 $newInstance = true; $vars = []; } if (isset($this->instances[$abstract]) && !$newInstance) { $object = $this->instances[$abstract]; } else { if (isset($this->bind[$abstract])) { $concrete = $this->bind[$abstract]; if ($concrete instanceof \Closure) { $object = $this->invokeFunction($concrete, $vars); } else { $object = $this->make($concrete, $vars, $newInstance); } } else { $object = $this->invokeClass($abstract, $vars); } if (!$newInstance) { $this->instances[$abstract] = $object; } } return $object; } ~~~ > * 首先判斷$vars值是否為true。用來判斷是強制創建新的對象實例 > * 然后 讀取Container中的instances中是否已有實例內容 > * 如果Container的instance沒有實例內容,則讀取Container的bind中綁定的實現 > 1. 如果bind中的是閉包Closure則執行閉包,獲取執行結果 > 2. 不是閉包(類,接口)則繼續重新調用make,這時則會執行 $object = $this->invokeClass($abstract, $vars); > * 將執行的結果保存到Container的instances中作為緩存。 > * 然后執行結果的object。 > make()主要是用來讀取instances中緩存的實例內容。 > 如果沒有則從bind中綁定的內容進行創建。 > 然后緩存到instances中,緩存后下次則讀取instances中緩存的內容 > 如果強制創建新的,則從bind重新創建實例,緩存到instances中 * * * * * ### 2 上層方法 #### get() 獲取綁定內容 ~~~ public static function get($abstract, $vars = [], $newInstance = false) { return static::getInstance()->make($abstract, $vars, $newInstance); } ~~~ > 直接調用make()方法,與make方法過程一致。 * * * * * #### set() 注冊內容到容器 ~~~ public static function set($abstract, $concrete = null) { return static::getInstance()->bind($abstract, $concrete); } ~~~ > 直接調用bind()方法,與bind方法過程一致。 * * * * * #### instance() 綁定實例 ~~~ public function instance($abstract, $instance) { if (isset($this->bind[$abstract])) { $abstract = $this->bind[$abstract]; } $this->instances[$abstract] = $instance; return $this; } ~~~ > 注冊實例到Container的instances中 * * * * * #### bound() 檢測是否綁定 ~~~ public function bound($abstract) { return isset($this->bind[$abstract]) || isset($this->instances[$abstract]); } ~~~ > 檢測是否已綁定過程。 * * * * * ### 3 底層實現 #### getInstance() ~~~ public static function getInstance() { if (is_null(static::$instance)) { static::$instance = new static; } return static::$instance; } ~~~ > 獲取全局唯一容器對象。 > 經典的單例模式。 * * * * * #### invokeFunction() 反射執行函數或閉包 ~~~~ public function invokeFunction($function, $vars = []) { $reflect = new \ReflectionFunction($function); $args = $this->bindParams($reflect, $vars); return $reflect->invokeArgs($args); } ~~~~ > ReflectionFunction反射執行函數或閉包。 * * * * * #### invokeMethod() 反射執行類方法或對象方法 ~~~ public function invokeMethod($method, $vars = []) { if (is_array($method)) { $class = is_object($method[0]) ? $method[0] : $this->invokeClass($method[0]); $reflect = new \ReflectionMethod($class, $method[1]); } else { // 靜態方法 $reflect = new \ReflectionMethod($method); } $args = $this->bindParams($reflect, $vars); return $reflect->invokeArgs(isset($class) ? $class : null, $args); } ~~~ > ReflectionMethod 反射執行類方法或靜態方法 * * * * * #### invoke() 反射執行(上面兩個的封裝) ~~~ public function invoke($callable, $vars = []) { if ($callable instanceof \Closure) { $result = $this->invokeFunction($callable, $vars); } else { $result = $this->invokeMethod($callable, $vars); } return $result; } ~~~ > 調用invokeFunction()或者invokeMethod()反射執行callable * * * * * #### invokeClass() 創建類實例 ~~~ public function invokeClass($class, $vars = []) { $reflect = new \ReflectionClass($class); $constructor = $reflect->getConstructor(); if ($constructor) { $args = $this->bindParams($constructor, $vars); } else { $args = []; } return $reflect->newInstanceArgs($args); } ~~~ > ReflectionClass 反射創建類的對象實例 * * * * * #### bindParams() 合并參數 ~~~ protected function bindParams($reflect, $vars = []) { $args = []; if ($reflect->getNumberOfParameters() > 0) { // 判斷數組類型 數字數組時按順序綁定參數 reset($vars); $type = key($vars) === 0 ? 1 : 0; $params = $reflect->getParameters(); foreach ($params as $param) { $name = $param->getName(); $class = $param->getClass(); if ($class) { $className = $class->getName(); $args[] = $this->make($className); } elseif (1 == $type && !empty($vars)) { $args[] = array_shift($vars); } elseif (0 == $type && isset($vars[$name])) { $args[] = $vars[$name]; } elseif ($param->isDefaultValueAvailable()) { $args[] = $param->getDefaultValue(); } else { throw new \InvalidArgumentException('method param miss:' . $name); } } } return $args; } ~~~ > 合并多個參數到一個數組中。 * * * * * ## 2 助手函數 #### app() 讀取實例 ~~~ function app($name = 'think\App', $args = [], $newInstance = false) { return Container::get($name, $args, $newInstance); } ~~~ > 調用Container的get方法獲取容器中的實例 #### bind() 注冊內容到容器 ~~~ function bind($abstract, $concrete = null) { return Container::getInstance()->bind($abstract, $concrete); } ~~~ > 調用Conatiner的bind()到注冊內容到容器
                  <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>

                              哎呀哎呀视频在线观看