PHP – 設計模式



在軟體工程理論中,術語“設計模式”通常指的是一種可重用的解決方案,可以用作開發應用程式的模板,以解決常見問題。您可以將軟體設計模式視為開發軟體解決方案時的正式最佳實踐。

大多數標準設計模式可以非常有效地應用於開發 PHP 應用程式。在本章中,我們將學習如何在開發 PHP 應用程式中應用一些流行的設計模式。

單例模式

當您希望將某個類的物件例項化限制為僅一個例項時,單例設計模式很有用。“單例模式”這個名稱來自數學中單例的概念。單例模式確保只有一個例項,並在整個應用程式中全域性訪問它。

單例模式的典型應用是建立資料庫連線物件,該物件必須在應用程式的生命週期中建立一次。

示例

在以下程式碼中,DataBaseConnector 類只能例項化一次,否則將發出不允許重複物件的提示。

<?php
   class DataBaseConnector {				
      private static $obj;				
      private final function __construct() {
         echo __CLASS__ . " object created for first time ". PHP_EOL;
      }
      public static function getConnect() {
         if (!isset(self::$obj)) {
            self::$obj = new DataBaseConnector();
            return self::$obj;
         } else {
            echo "connection object could not be created again" . PHP_EOL;
         }
      }
   }

   $obj1 = DataBaseConnector::getConnect();
   $obj2 = DataBaseConnector::getConnect();

   var_dump($obj1 == $obj2);
?>

它將產生以下輸出 -

DataBaseConnector object created for first time 
connection object could not be created again
bool(false)

工廠模式

這是最常用的設計模式之一。在這種模式下,您不會直接宣告所需類的物件,而是提供另一個類的靜態方法來建立所需的物件。

示例

以下示例演示了工廠設計模式的工作原理 -

<?php
   class Automobile {
      private $bikeMake;
      private $bikeModel;

      public function __construct($make, $model) {
         $this->bikeMake = $make;
         $this->bikeModel = $model;
      }

      public function getMakeAndModel() {
         return $this->bikeMake . ' ' . $this->bikeModel;
      }
   }

   class AutomobileFactory {
      public static function create($make, $model) {
         return new Automobile($make, $model);
      }
   }

   $pulsar = AutomobileFactory::create('ktm', 'Pulsar');
   print_r($pulsar->getMakeAndModel());
?>

它將產生以下輸出 -

ktm Pulsar

策略模式

策略模式推薦一種方法,其中您封裝特定系列的演算法,允許負責例項化特定演算法的客戶端類。實現該模式的類不知道實際的實現。

示例

這是一段演示策略模式用法的程式碼。我們有一個介面,其 case() 方法由兩個不同的類以不同的方式實現。testdata 類的物件透過其自己的 process() 方法間接呼叫相應的 case() 方法。

<?php
   interface example {
      public function case($str);
   }

   class ucase implements example {
      public function case($str) {
         return strtoupper($str);
      } 
   }

   class lcase implements example {
      public function case($str) {
         return strtolower($str);
      }
   }

   class testdata {
      private $data;

      public function __construct($input) {
         $this->data = $input;
      }
      public function process(example $type) {
         return $this->data = $type->case($this->data);
      }
   }
   $str = "hello";
   $obj = new testdata($str);
   echo $obj->process(new ucase) . PHP_EOL;  
   $str = "HELLO";
   echo $obj->process(new lcase);
?>

它將產生以下輸出 -

HELLO
Hello

MVC 設計模式

MVC 代表模型、檢視和控制器,是一種非常流行的軟體架構模式。大多數 PHP 框架(如 Laravel、Symfony 等)都實現了 MVC 架構。

應用程式中每個層的作用分離如下 -

  • 模型 - 指資料結構。在本例中,是資料庫。

  • 檢視 - 指使用者介面。HTML 和 CSS。

  • 控制器 - “中間人”執行處理。接受來自檢視的輸入,並與模型互動。不言而喻,PHP 指令碼和庫本身。

檢視充當 GUI,模型充當後端,控制器充當介面卡。在這裡,三個部分相互連線。它將在彼此之間傳遞資料和訪問資料。

示例

讓我們在下面的示例中使用純 PHP、JavaScript 和 HTML 實現 MVC 設計模式 -

應用程式的表示層是 view.php,它呈現一個 HTML 表單。使用者將資料提交到控制器指令碼。控制器返回的結果使用一些 JavaScript 在網頁上呈現

view.php

<!DOCTYPE html>
<html>
<head>
   <title>View (User Interface)</title>
   <link rel="stylesheet" href="style.css">
</head>
<body>
   <form id="mysearch" action="controller.php" method="POST">
      <input type="text" id = "nm" name="search" required>
      <input type="submit" value="Search">
   </form>
   <div id="results"></div>
   <script>
      let results = document.getElementById("results");
      results.innerHTML = "";
   </script>
   <?php
      session_start();
      if (isset($_SESSION['result'])) {
         $arr=$_SESSION['result'];

         foreach ($arr as $obj) {?>
            <script>
               results.innerHTML += "<div><?php echo $obj['id'] . "-" . 
			      $obj['name'] . "</div>"; ?>";
            </script>
            <?php
         }
      }
   ?>
</body>
</html>

控制器指令碼需要 model.php,並使用資料庫物件,呼叫 select 方法從資料庫中獲取資料。結果儲存在當前會話中,以便可以在檢視頁面上訪問它。

controller.php

<?php
   session_start();
   require "model.php";
   $results = $_DB->select(
      "SELECT * FROM `users` WHERE `name` LIKE ?",
      ["%{$_POST["search"]}%"]
   );
   $_SESSION['search'] = $_POST['search'];
   $_SESSION['result'] = $results;
   Header("Location: view.php", true);
?>

應用程式的模型層在“model.php”中編碼。它使用 PDO 擴充套件與名為 mydb 的 mysql 資料庫建立連線。

model.php

<?php
   class DB {
      public $error = "";
      private $pdo = null;
      private $stmt = null;
      var $dsn="localhost";  
      var $dbName="myDB";  
      var $username="root";       
      var $password=""; 
      function __construct () {
         $this->pdo = new PDO("mysql:host=$this->dsn;dbname=$this->
		    dbName",$this->username,$this->password); 
      }
      function __destruct () {
         if ($this->stmt!==null) { $this->stmt = null; }
         if ($this->pdo!==null) { $this->pdo = null; }
      }
      function select ($sql, $data=null) {
         $this->stmt = $this->pdo->prepare($sql);
         $this->stmt->execute($data); 
         return $this->stmt->fetchAll();
      }
   }
   $_DB = new DB();
?>

後端 mydb 資料庫必須有一個 users 表,其中包含 ID 和 NAME 欄位。

-- Table structure for table `users`
--
CREATE TABLE `users` (
   `id` bigint(20) NOT NULL,
   `name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

--
-- Dumping data for table `users`
--
INSERT INTO `users` (`id`, `name`) VALUES
(21, 'Ahmad Shaikh'),
(24, 'Akshay Wadkar'),
(26, 'Bridget Wooten'),
(10, 'Coby Kelleigh'),
(20, 'Dashan Shah'),
(12, 'Elizabeth Taylor'),
(41, 'Issac Newton'),
(34, 'Julia Roberts'),
(31, 'Junior Mahmood'),
(32, 'Kailas Bende'),
(47, 'Karan Sharma'),
(16, 'Kenneth Sanders'),
(28, 'Kirstie Thomas'),
(33, 'Lawrence Murphy'),
(14, 'Leah Shan'),
(51, 'Marcus Best'),
(29, 'Maya Pande'),
(50, 'Nathaniel Khan'),
(6, 'Richard Breann'),
(54, 'Rowan Avalos'),
(3, 'Rusty Terry'),
(37, 'Sacha Gross'),
(27, 'Sally Castillo'),
(11, 'Sarah Sanders'),
(18, 'Seth Sonnel'),
(38, 'Shannon Peterson'),
(25, 'Shayan Clements'),
(49, 'Shoaib Vickers'),
(43, 'Simran Kaur'),
(35, 'Sulaiman Gilmour'),
(44, 'Taran Morin'),
(48, 'Taran Morin'),
(22, 'Thelma Kim'),
(8, 'Tillie Sharalyn'),
(36, 'Virgil Collier');

透過在瀏覽器中訪問“https:///view.php”啟動應用程式。輸入與具有所需字母的名稱相對應的搜尋詞。

PHP Design Patterns
廣告