<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之旅 廣告
                # :-: 一、容器與門面 >[info] 容器: 類與類實例的集合, 至少包括類實例的綁定與創建二個功能 * 設計模式中的容器的原理與應用場景 1. 容器可以簡單的理解為類與類實例的集合 2. 本例中,我們將模型與視圖的實例放在一個容器中進行統一管理 3. 容器本身也是一個類, 類中至少要提供二個方法: 創建實例和取出實例 >[info] 容器 >> Controller.php 文件 ```php // 加載'模型類' require 'Model.php'; // 加載'視圖類' require 'View.php'; /****************************************************************************/ // 創建容器類,容器中可保存很多類型,這里僅以類實例方法來演示 class Container{ // 創建容器屬性,保存著類實例的創建方法 protected $instance = []; // $alias: 類實例別名, $process: 類的實例化過程/函數/Closure閉包類型 public function bind($alias, Closure $process){ // 將類實例方法存入到容器中 $this->instance[$alias] = $process; } // 創建類的實例: 執行容器中的類的實例方法,$alias參數是容器中的類實例別名 public function make($alias, $params=[]) { return call_user_func_array($this->instance[$alias], $params); } } // 將要用到的類實例(Mode/View)綁定到容器中 $container = new Container(); // 將Model類實例的方法綁定到容器中,標識為'model' $container->bind('model', function () { return new Model(); }); // 將View類實例的方法綁定到容器中,標識為'view' $container->bind('view', function() { return new View(); }); /****************************************************************************/ // 控制器 class Controller { // 將容器對象注入到控制器方法中 public function index(Container $container){ //獲取數據: 容器對象的make()方法 $data = $container->make('model')->getData(); //渲染模板 return $container->make('view')->fetch($data); } } //客戶端調用 $controller = new Controller(); //以容器對象$container為實參調用 echo $controller->index($container); ``` * 將類的實例過程使用容器進行包裝,是一個非常不錯的解決方案 * 但是我還是覺得在控制器中充斥著大量的make()方法,吃相太難看,能不能再進行簡化呢? * 當然可以,現在有請"Facade門面模式"閃亮登場 >[info] 門面: 給容器中的類方法調用,提供一個統一的靜態訪問接口 >> Controller.php 文件 ```php // 加載'模型類' require 'Model.php'; // 加載'視圖類' require 'View.php'; /********************************************************************************/ // 創建容器類,容器中可保存很多類型,這里僅以類實例方法來演示 class Container { // 創建容器屬性,保存著類實例的創建方法 protected $instance = []; // $alias: 類實例別名, $process: 類的實例化過程/函數/Closure閉包類型 public function bind($alias, Closure $process){ // 將類實例方法存入到容器中 $this->instance[$alias] = $process; } // 創建類的實例: 執行容器中的類的實例方法,$alias參數是容器中的類實例別名 public function make($alias, $params=[]){ return call_user_func_array($this->instance[$alias], []); } } // 將要用到的類實例(Mode/View)綁定到容器中 $container = new Container(); // 將Model類實例的方法綁定到容器中,標識為'model' $container->bind('model', function () { return new Model(); }); // 將View類實例的方法綁定到容器中,標識為'view' $container->bind('view', function() { return new View(); }); /****************************************************************************/ //聲明Facade類,來接管對容器中類實例方法的調用 class Facade { // 控制器中調用到了Model類中的getData()方法, View類中的view()方法 // 我們就為這二個訪問創建一個統一訪問的靜態接口 // 調用方法使用的關鍵字static: 可以實現在靜態繼承上下文環境中,實現靜態成員調用者的動態設置 // 后面的Product 就是 Facade類的子類,如果不使用static::就無法動態調用子類中的成員 // 如果你用不到子類,這里可以不用static后期靜態綁定,可以使用self::替代 // 但是使用static , 會使代碼更具健壯性,能用性 protected static $container = null; protected static $data = []; public static function initialize(Container $container) { static::$container = $container; // static::是后期靜態綁定的語法 } // 設置獲取數據的靜態代理方法:getDate() public static function getData(){ // static::$container 是當前引用類'Model'的實例 static::$data = static::$container->make('model')->getData(); } // 設置渲染模板的靜態代理方法:fetch() public static function fetch(){ // static::$container 是當前引用類'View'的實例 return static::$container->make('view')->fetch(static::$data); } } // 聲明一個商品類 class Product extends Facade { // 自定義的業務邏輯 } /***************************************************************************/ // 控制器 class Controller { //在構造方式中調用Facade中初始化方式,完成容器的實例化: 依賴注入 public function __construct(Container $container) { Product::initialize($container); } // 將容器對象注入到控制器方法中 public function index(){ Product::getData(); // 獲取數據 return Product::fetch(); // 渲染模板 } } //客戶端調用 $controller = new Controller($container); //以容器對象$container為實參調用 echo $controller->index(); ``` * 門面Facade模式,使類方法調用更加的優雅,全部采用靜態方式統一調用 * 相當于給類中的方法戴了一個靜態面具/靜態代理 * 在Larval、ThinkPHP6.0 大量的使用到了Facade模式,請一定要掌握,否則會成為框架學習的最大障礙 ***** # :-: 二、路由的原理與實現 ### 1、從pathinfo地址切割為獨立的數組單元 * pathinfo: 用目錄分隔符組成一個URL地址, 注意?后面的查詢字符串不屬于它 * 以請求地址: http://www.ouyangke.com/route.php/admin/index/hello 為例 * 可能大家對模塊的概念不是很清楚, 模板可以理解為一個應用, 例如一個網站會有一個前臺模塊, 一個后臺模塊, 各司其責 ```php $uri = $_SERVER['REQUEST_URI']; $request = explode(DIRECTORY_SEPARATOR, $uri); // 框架的基本原理,就是根據HTTP請求的URL地址, 從中解析出對應的函數進行處理 // 而操作函數有二個載體, 一是函數本身, 二是類方法 // 路由到函數, 其實這個函數就是所謂的閉包, 所謂路由到閉包, 就是由一個函數來執行HTTP請求 // 路由到類方法最為常用, 這個類, 就是控制器, 方法就是控制器類中的某個操作方法(本質仍是函數) // 大家現在是否發現, 路由就是一個請求分發器, 要么將HTTP請求交給一個函數處理, 要么交給一個類方法來處理 echo '<pre>' . print_r($request,true); ``` ### 2、從pathinfo數組中解析出:模塊,控制器和操作 ```php $uri = $_SERVER['REQUEST_URI']; $request = explode(DIRECTORY_SEPARATOR, $uri); // 我們所關心的只是模塊,控制器和方法,所以從數組的第3項開始來獲取數據 $route = array_slice($request,2,3); // 查看獲取到的module/controller/action echo '<pre>' . print_r($route,true); // list()語法結構, 可以從將一個索引數組中每個元素,設置一個字符串鍵名,并轉為獨立變量使用 // list()并非函數, 因為它可以用到等號左邊, 接受賦值操作, 而函數是絕對不允許也不可能用在等號左邊的 list($module, $controller, $action) = $route; echo "模塊:{$module}<br>控制器: {$controller}<br>操作: {$action}<br>"; // 將pathinfo內容解析到一個數組中保存 $pathinfo['module'] = $module; $pathinfo['controller'] = $controller; $pathinfo['action'] = $action; // 使用數組函數: compace()簡化, 該函數可以將多個變量轉為關聯數組 $pathinfo = compact('module','controller', 'action'); echo '<pre>' . print_r($pathinfo,true); ``` >[info] 因為路由最終會指向一函數或類方法, 該函數/類方法是允許有參數的,并且可能不止一個。所以,路由必須要具備從URL中解析出正確的參數鍵值對的能力 ### 3、從pathinfo數組中解析出:參數鍵值對 * 以請求地址: http://www.ouyangke.com/route.php/admin/index/hello/name/peter/position/lecture 為例 ```php $uri = $_SERVER['REQUEST_URI']; $request = explode(DIRECTORY_SEPARATOR, $uri); $values = array_slice($request,5); for ($i=0; $i<count($values); $i+=2) { // 將鍵值對中的第一個做為鍵,第二個做為值,該操作僅在第二個值存在的情況下執行 if( isset($values[$i+1])) { $params[$values[$i]] = $values[$i+1]; } } // 查看解析出來的參數 echo '<pre>' . print_r($params,true); ``` ### 4、創建與pathinfo中的`控制器/操作/參數鍵值對`對應的類和方法 ```php $uri = $_SERVER['REQUEST_URI']; $request = explode(DIRECTORY_SEPARATOR, $uri); $route = array_slice($request,2,3); list($module, $controller, $action) = $route; $pathinfo = compact('module','controller', 'action'); $values = array_slice($request,5); for ($i=0; $i<count($values); $i+=2) { // 將鍵值對中的第一個做為鍵,第二個做為值,該操作僅在第二個值存在的情況下執行 if( isset($values[$i+1])) { $params[$values[$i]] = $values[$i+1]; } } class Index{ public function hello($id,$name){ return "Index控制器hello()操作: $id= {$id}, $name= {$name}"; } public function demo($a, $b, $c){ return "Index控制器demo()操作,它的參數是: $a = {$a}, $b={$b}, $c={$c}"; } } echo call_user_func_array([(new $pathinfo['controller']()), $pathinfo['action']], $params); ``` ***** # :-: 三、模板引擎的原理與實現 * 模板引擎應該具備的基本功能: * 存儲一組變量 * 讀取模板文件 * 組成前二者生成輸出 >[info] index.php文件 ```php // 模板引擎的調用腳本 // 加載模板引擎類 require 'template.php'; // 實例化模板引擎類 $template = new template('hello.php'); // 模板賦值: $hello = 'php模板引擎很簡單', 變量不存在則顯示默認值 $template->set('hello','php模板引擎很簡單'); // 輸出模板 echo $template->display(); // 瀏覽器訪問: index.php, 輸出: php模板引擎很簡單 ``` >[info] hello.php文件 ```php <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>模板文件</title> </head> <body> <h2> <?php echo isset($hello) ? $hello : '歡迎訪問' ?> </h2> </body> </html> ``` >[info] template.php文件 ```php // 模板引擎 class template{ private $data = []; private $file; // 獲取模板文件名 public function __construct($file){ $this->file = $file; } // 設置模板變量 public function set($name,$value){ $this->data[$name] = $value; } // 生成并輸出模板 public function display(){ // 提取模板變量: 關聯數組轉變量名值對 extract($this->data); // 開啟輸出緩沖, 只生成數組,并不會立即輸出到瀏覽器 ob_start(); // 加載模板文件 include $this->file; // 返回緩沖區中的內容 $string = ob_get_contents(); // 清空緩沖區并關閉輸出緩沖 ob_end_clean(); // 返回模板HTML return $string; } } ```
                  <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>

                              哎呀哎呀视频在线观看