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

                ### App Construct 先來看看在 __construct 中做了什么,基本任何框架都會在這里做一些基本的操作,也就是從這里開始延伸出去。 ```php public function __construct(string $rootPath = '') { $this->thinkPath = dirname(__DIR__) . DIRECTORY_SEPARATOR; $this->rootPath = $rootPath ? rtrim($rootPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $this->getDefaultRootPath(); $this->appPath = $this->rootPath . 'app' . DIRECTORY_SEPARATOR; $this->runtimePath = $this->rootPath . 'runtime' . DIRECTORY_SEPARATOR; if (is_file($this->appPath . 'provider.php')) { $this->bind(include $this->appPath . 'provider.php'); } static::setInstance($this); $this->instance('app', $this); $this->instance('think\Container', $this); } ``` - 從魔術的方法的參數`rootPath`來看,是支持自定義根目錄路徑的。 - 設置了 `thinkPath`, `rootPath`, `appPath`, `runtimePath` - 綁定了默認的服務提供者,一共提供了兩個,`app\Reques` 和 `app\ExceptionHandle`,實際上你使用的 `Request` 就是它。具體到 `appPath` 查看 - 設置當前容器實例 `APP` - 將 `App($this)` 實例 綁定到容器中,分別是 `app` 和 `think\Container` 這里需要注意的是 App 類是繼承 Container 的,所以就是將自身實例綁定到容器中。 在這里似乎整個應用就已經初始化結束了?這里我需要把一部分 `Request run` 的內容放在這里說,因為那里才是框架主要的初始化工作,我并不認為將這一部分初始化工作放在 `Request run` 中是合理的。 ## 主要的初始化 ``` public function initialize() { $this->initialized = true; $this->beginTime = microtime(true); $this->beginMem = memory_get_usage(); // 加載環境變量 if (is_file($this->rootPath . '.env')) { $this->env->load($this->rootPath . '.env'); } $this->configExt = $this->env->get('config_ext', '.php'); $this->debugModeInit(); // 加載全局初始化文件 $this->load(); // 加載框架默認語言包 $langSet = $this->lang->defaultLangSet(); $this->lang->load($this->thinkPath . 'lang' . DIRECTORY_SEPARATOR . $langSet . '.php'); // 加載應用默認語言包 $this->loadLangPack($langSet); // 監聽AppInit $this->event->trigger('AppInit'); date_default_timezone_set($this->config->get('app.default_timezone', 'Asia/Shanghai')); // 初始化 foreach ($this->initializers as $initializer) { $this->make($initializer)->init($this); } return $this; } ``` - 加載 .env 環境變量文件 - 加載配置文件以及應用內的文件 - 加載應用內的 common.php - 加載助手函數 在 `thinkPath` 目錄下的 `helper.php` - 加載配置文件 - 加載應用目錄下的 event.php 事件 - 注冊應用目錄下的 service.php 服務 - 加載語言包 - 監聽 AppInit 事件,利用該事件可以做一些請求前的工作 - 設置時區 - 注入所有服務并且啟動服務 ## 服務注冊 初始化過程中,進行服務注冊,那么服務注冊做了哪些事情呢?該如何使用的服務呢? ``` public function register($service, bool $force = false) { $registered = $this->getService($service); if ($registered && !$force) { return $registered; } if (is_string($service)) { $service = new $service($this); } if (method_exists($service, 'register')) { $service->register(); } if (property_exists($service, 'bind')) { $this->bind($service->bind); } $this->services[] = $service; } ``` - 服務是否注冊過,如果需要強制重新注冊 - 實例化服務 - 如果實現了 `register` 方法,則需要執行 `register` 方法 - 如果設置了 `bind` 屬性,則需要將 `service `實例綁定到容器 - 最后合并到整個 `service` 數組中,等待 `boot` ## 服務啟動 目前在初始化的時候只有下面三個服務,在 `$this->initializers` 數組中 ``` foreach ($this->initializers as $initializer) { $this->make($initializer)->init($this); } ``` 這三個服務分別是: ``` think\initializer\BootService think\initializer\Error think\initializer\RegisterService ``` - `Error` 服務是用來處理框架異常和錯誤的 - `RegisterService` 從字面的意思就是注冊服務的 - `BootService ` 就是啟用服務的 `Error` 處理在之后再說,這里說一下 `RegisterService` 和 `BootService`。 當從 `Container` 中 `make` 出 `RegisterService` 的時候 > 這里有個隱藏的**靜態方法** __make,每次如果首次從 Container 中 make 出來的實例對象都會執行 __make 方法,當然首先必須你實現了該方法。 隨后會執行 Init 方法。當你進入到 `RegisterService` 的時候,你會看到該方法。方法內容如下: ``` public function init(App $app) { $file = $app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . 'services.php'; $services = $this->services; if (is_file($file)) { $services = array_merge($services, include $file); } foreach ($services as $service) { if (class_exists($service)) { $app->register($service); } } } ``` 該方法就很奇怪了,和我想象的有點不一樣。服務是直接從 `runtime` 目錄下面獲取的,而非在 `config` 目錄下的 `service.php` 中。為什么會這樣呢?由于 composer 的發展,TP 框架也可以提供包的自動發現的功能,這也證明了開發組在不斷向社區靠攏。下面來看一下是如何實現的。 因為這都是得益于 composer 的,所以來看一下 `rootPath` 下的 composer.json,到最下面,你會發現下面的配置 ``` "scripts": { "post-autoload-dump": [ "@php think service:discover", "@php think vendor:publish" ] } ``` 從配置來看,框架一共提供了兩個指令,`service:discover `和 `vendor:publish`。具體實現這里就不說了,你只需要知道包的發現是由 `service:discover` 實現的。 還有就是這里默認注入了三個服務。 ``` PaginatorService::class, ValidateService::class, ModelService::class, ``` 最后再來看看 `BootService`,這個就很簡單了。從命名來講就不難看出,下面就是代碼,正常的啟動服務,但是這里要說明的是,服務類中必須實現了 `boot` 方法才會啟動。 ``` public function init(App $app) { $app->boot(); } ``` 以上就是整個應用的初始化,具體細節在之后討論
                  <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>

                              哎呀哎呀视频在线观看