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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # :-: 一、單例模式 * 一個類, 僅允許實例化一次,即僅允許創建一個實例 * 應用場景: 數據庫的連接對象, HTTP請求, 游戲中的主角等 ```php class People{ } $obj1 = new People(); $obj2 = new People(); var_dump($obj1); echo '<br>'; var_dump($obj2); // Temp 類被實例化了二次,創建了二個完全不同的對象 var_dump($obj1 === $obj2); // false, 說明這二個對象完全不相同 ``` * 如何時才能確保一個類僅被實例化一次呢? 使用單例模式可以實現 ```php class Demo{ // 將構造方法私有化, 使用戶在類的外部,無法通過"new"關鍵字來實例化該類 private function __construct(){ } // 此時類外部無法通過new實例化, 所以類的實例化工作只能在類中完成了 // 聲明一個靜態屬性,用來保存當前類的實例 private static $instance = null; // 如果不賦值,默認值就是null, 此處用null初始化僅僅是使代碼更清晰 // 聲明一個實例當前類的靜態方法, 思考一下為什么必須設置靜態的?(因為外部已無法實例化該類創建對象了) public static function getInstance(){ // 如果當前類實例為null,說明當前類尚未被實例化過,那我們就就需要先將類實例化后,再返回調用者 if (is_null(self::$instance)) { self::$instance = new self(); } // 返回當前類實例 return self::$instance; } // 當獲取到當前類實例之后, 外部是可以通過clone方法來快速復制該對象的, 所以類內部也應該將__clone()禁用 // 只需要將__clone()方法的訪問限方式定為私有private即可 private function __clone(){ } } //$obj1 = new Demo(); // 報錯, 因構造方法私有化, 外部已無法用new 來完成類的實例化 $obj1 = Demo::getInstance(); $obj2 = Demo::getInstance(); var_dump($obj1); echo '<br>'; var_dump($obj2); echo '<br>'; // 驗證Demo類是否僅實例化了一次 var_dump($obj1 === $obj2); // true , 完全符合要求 echo '<hr>'; ``` >[info] 數據庫連接為例, 演示單例模式的應用 ```php class Db{ private static $pdo = null; public static function getInstance(...$connectParams){ if (is_null(self::$pdo)) { // 因為構造函數沒有返回值, 所以實例當前類并賦值給靜態屬性的過程,只能在構造方法中完成 // self::$pdo = new self(...$connectParams); new self(...$connectParams); } return self::$pdo; } // 當前構造方法是私有的, 僅表示在類外部不允許調用, 但是在類的內部仍然有效的 private function __construct(...$connectParams){ // 當前$connectParams 是一個索引數組,每一個元素對應著不同的連接參數 $dsn = $connectParams[0]; $username = $connectParams[1]; $password = $connectParams[2]; // 在私有的構造方法中完成類實例的創建過程 // 創建一個PDO類實例, 并賦值給當前類實例self::$pdo self::$pdo = new \PDO($dsn, $username, $password); } // 私有化克隆方法 private function __clone(){ } } // 為簡化代碼, 使用剩余參數來傳參 $connectParams = ['mysql:host=localhost;dbname=ouyangke', 'root', 'root']; $pdo = Db::getInstance(...$connectParams); // 做一個數據表查詢來演示一下, 數據的格式化大家自己完成 print_r($pdo->query('select * from user')->fetchAll()); ``` ***** # :-: 二、工廠模式 * 主要用于批量創建對象,使創建對象的過程剝離出來,標準化 * 適合于一個類有多個實例, 而這些實例會在不同的地方被創建和引用 * 使用工廠模式來創建對象, 可以實現, 一處修改, 全局生效 ```php namespace admin; class Demo{ } $obj = new Demo(); $obj = new Demo(); $obj = new Demo(); # 由于業務需要, Demo2類的類名需要改變,那么所有引用到這個類名的代碼全部需要修改 ``` >[info] Demo的實例化過程剝離出來,由一個專門的類去完成, 將會避免這種情況發生 ```php namespace admin; class Test1{ public function __construct($arg1){ echo '對象創建成功, 參數是: ' . $arg1; } } class Test2{ public function __construct($arg1, $arg2){ echo '對象創建成功, 參數是: ' . implode(', ', [$arg1, $arg2]); } } class Test3{ public function __construct($arg1, $arg2, $arg3){ echo '對象創建成功, 參數是: ' . implode(', ', [$arg1, $arg2, $arg3]); } } class Test4{ public function __construct(){ echo '對象創建成功, 無參數'; } } // 工廠類: 專用于創建類實例 class Factory{ /** * @param [String] 需要實例化的類名稱 * @param [Array] 實例化時需要傳入的參數,使用剩余參數,可以自適應數量變化 * @return [Object] 類實例 */ public static function create($className, ...$arguments){ // 剩余參數的展開規則: $arguuments 是數組,...可以將它展開 return new $className(...$arguments); } } Factory::create(Test1::class, 100); echo '<hr>'; Factory::create(Test2::class, 100, 200); echo '<hr>'; Factory::create(Test3::class, 100, 200, 300); echo '<hr>'; Factory::create(Test4::class); ``` ***** # :-: 三、MVC模式的原理與實現 :-: ![mvc](http://kanyun.8car.net/php/mvc.gif) >[info] Model.php 文件 ```php //模型類: 用于數據庫操作 class Model{ public function getData(){ return [ ['uid'=>1, 'name'=>'歐陽克','phone'=>'18011112222','age'=>18], ['uid'=>2, 'name'=>'黃蓉','phone'=>'13011113333','age'=>16], ['uid'=>3, 'name'=>'郭靖','phone'=>'18722224444','age'=>22], ]; } } ``` >[info] View.php 文件 ```php //視圖類: 渲染數據 //為簡化代碼,這里忽略數據庫操作,直接以二維數組模擬數據庫查詢的結果集 class View{ public function fetch($data){ $table = '<table border="1" cellspacing="0" width="400">'; $table .= '<caption>用戶信息表</caption>'; $table .= '<tr bgcolor="lightblue"><th>ID</th><th>姓名</th><th>手機</th><th>年齡</th></tr>'; foreach ($data as $user) { $table .= '<tr>'; $table .= '<td>' . $user['uid'] . '</td>'; $table .= '<td>' . $user['name'] . '</td>'; $table .= '<td>' . $user['phone'] . '</td>'; $table .= '<td>' . $user['age'] . '</td>'; $table .= '</tr>'; // Heredoc語法實現多行字符串,類似雙引號功能 // $table .= <<< PRODUCT // <tr> // <td>{$user['uid']}</td> // <td>{$user['name']}</td> // <td>{$user['phone']}</td> // <td>{$user['age']}</td> // </tr> // PRODUCT; } $table .= '</table>'; return $table; } } ``` >[info] Controller.php 文件 ```php /** * mvc 思想 * 任務:將商品信息表展示出來 */ // 加載'模型類' require 'Model.php'; // 加載'視圖類' require 'View.php'; // 控制器 class Controller{ public function index(){ //獲取數據 $model = new Model(); $data = $model->getData(); //渲染模板 $view = new View(); return $view->fetch($data); } } //客戶端調用 $controller = new Controller(); echo $controller->index(); ``` * 存在的問題 1. Model類和View類的實例化,都在Controller類中完成,導致Controller類嚴重依賴Model類和View類; 2. Model類和View類的構造方式的變化,將會直接改變實例化的過程,導致Controller類不能獨立于這二個類; 3. 即,Controller類,嚴重依賴Model類和View類,這種現象,就是我們常說的的: 代碼之間的耦合度太高 4. 比較好的解決方案是,將Model和View類的實例化過程放在Controller類之外完成,而將他們的對象以參數方式傳入到 * 解決方案 1. 依賴注入:對象可以像其它普通類型參數一樣,進行傳遞 2. 依賴注入本意:將當前類依賴的其它類實例,以方法參數的形式,注入到當前類中,簡稱:"依賴注入" >[info] 依賴注入:普通方法 >> Controller.php 文件 1. 將外部對象以參數形式注入到控制器的方法中 2. 調用控制器時,先將Model和View實例化,再調用控制器的方法 3. 將Model和View實例做為控制器方法中的參數傳入 ```php // 加載'模型類' require 'Model.php'; // 加載'視圖類' require 'View.php'; // 控制器 class Controller{ // 1. 將外部對象以參數形式注入到控制器的方法中; public function index(Model $model, View $view){ //獲取數據 $data = $model->getData(); //渲染模板 return $view->fetch($data); } } // 2. 調用控制器時,先將Model和View實例化,再調用控制器的方法 $model = new Model(); $view = new View(); //客戶端調用 $controller = new Controller(); //3. 將Model和View實例做為控制器方法中的參數傳入 echo $controller->index($model, $view); ``` * 依賴注入可以很好的解決類之間的代碼耦合 * 其實依賴注入時,對象即可以注入到控制器方法中,也可以注入到控制器構造方法中 * 直接注入到構造方法中,可以極大的簡化代碼,特別是在多個方法中都要用到這些外部對象時 >[info] 依賴注入:構造方法 >> Controller.php 文件 1. Controller中設置一個對象容器屬性用來保存外部注入的對象 2. Controller類中創建構造方法,并將外部對象,做為構造方法的參數注入到類中 3. 修改調用方法index(),刪除注入參數,修改調用語句 4. 調用控制器時,先將Model和View實例化,再調用控制器的方法 5. 客戶端調用時,Controller類直接使用外部對象為參數進行實例化 ```php // 加載'模型類' require 'Model.php'; // 加載'視圖類' require 'View.php'; // 控制器 class Controller { // 1. Controller中設置一個對象容器屬性用來保存外部注入的對象 protected $model = null; protected $view = null; //2. Controller類中創建構造方法,并將外部對象,做為構造方法的參數注入到類中 public function __construct(Model $model, View $view){ $this->model = $model; $this->view = $view; } //3. 修改調用方法index(),刪除注入參數,修改調用語句 public function index(){ //獲取數據 $data = $this->model->getData(); //渲染模板 return $this->view->fetch($data); } } // 4. 調用控制器時,先將Model和View實例化,再調用控制器的方法 $model = new Model(); $view = new View(); //5. 客戶端調用時,Controller類直接使用外部對象為參數進行實例化 $controller = new Controller($model, $view); echo $controller->index(); ```
                  <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>

                              哎呀哎呀视频在线观看