搜尋
首頁後端開發php教程php精粹 php設計模式

1,選擇一個最適合的設計模式

沒有任何事物是完美的,也沒有人說過設計模式一個嚴格的放之四海而皆準的解決方法。因此你可以改變這些模式,使它們更適合手邊的工作。對某些設計模式而言,他們就是所屬程式固有的天性;而對於其他的一些設計模式,你可以改變自己的模式。模式之間互相配合、協同工作已經很常見。它們構成了整個應用(至少一部分)的基礎。

2.單例模式

  1. // The Database class represents our global DB connection

  2. class Database{
  3. // A holdic v. our single instance
  4. private static $_instance = null;
  5. // Make the constructor private to ensure singleton
  6. private function __construct()
  7. {
  8. private function __construct()
  9. { }
  10. // A method to get our singleton instance

  11. public static function getInstance()
  12. {
  13. if (!(self::$_instance instanceof Database)) {
  14. self::$_instance = new Database();
  15. }
  16. return self::$_instance;
  17. }
  18. }
  19. $database = Database::getInstance();

  20. var_dump($database);
複製程式碼

問題:使用單單>複製程式碼

問題:使用單單>複製程式碼
    問題:使用單單>複製程式碼
  1. 問題:使用單單>複製程式碼
  2. 問題:使用單單>複製程式碼
  3. 問題:使用單單>複製程式碼
  4. 問題:使用單單>複製程式碼
  5. 問題:使用單單>複製碼範例模式不能建立兩個實例,可用Traits解決建立兩個不同類型的實例的問題,但仍無法解決建立兩個相同實例的問題(可用登錄模式解決)。
  6. 建立兩個不同類別的實例 程式碼:
  7. trait Singleton {
  8. private static $_instance = null;
  9. public static ftion get getption $ __CLASS__;
  10. if(!(self::$_instance instanceof $class)) {
  11. self::$_instance = new $class;
  12. }
  13. return self:: $_instance;
  14. }
  15. }
  16. class DB {
}
class DBWriteConnection extends DB { s__Svate f🎜>;
echo 'DBWriteConnection
'; } } class DBReadConnection extends DB { use Singleton; private function ) { echo 'DBReadConnection
'; } } $dbWriteConnection = DBWriteConnection::getInstance(); var_dump($dbWriteConnection); 複製程式碼

3.登錄模式 註冊表模式只是一個單獨的全域類,在你需要的時候允許程式碼檢索一個物件的相同實例,也可以在你需要的時創建另一個實例(一經要求將再次存取那些全域實例)。

Registry類別:

  1. class Registry {

  2. /**
  3. * @var array 所有物件的儲存
  4. */
  5. static private $_store = array();
  6. /**
  7. * 將物件新增至登錄機碼
  8. *
  9. * 如果不指定名稱,則使用類別名稱
  10. *
  11. * @param mix $object 要儲存的物件
  12. * @param string $name 用於檢索物件的名稱
  13. * @return void
  14. * @throws Exception
  15. */
  16. static public function add($object, $name = null)
  17. {
  18. // Use the classname if no name given, simulates singleton
  19. $name = (!is_null($name)) ?$name:get_class($object);
  20. if (isset(self::$_store[$name])) {
  21. throw new Exception(" Object already exists in registry");
  22. }
  23. self::$_store[$name]= $object;
  24. }
  25. /**
  26. * 從登錄機碼取得一個物件
  27. *
  28. * @param string $name 物件名稱,{@see self::set()}
  29. * @return mix
  30. * @throws Exception
  31. */
  32. static public function get($name)
  33. {
  34. if (!self::contains($name)) {
  35. throw new Exception("Object does not exist in registry");
  36. }
  37. return self::$_store[$name];

  38. }
  39. /**
  40. * 檢查物件是否在登錄中
  41. *
  42. * @param string $name 物件名稱,{@see self::set()}
  43. * @return bool
  44. */
  45. static public function contains($name )
  46. {
  47. if (!isset(self::$_store[$name])) {
  48. return false;
  49. }
  50. return true;
  51. }
  52. /**
  53. * 從註冊表中刪除一個物件
  54. *
  55. * @param string $name 物件名稱,{@see self::set()}
  56. * @returns void
  57. */
  58. static public function remove($name)
  59. {
  60. if (self::contains($name)) {
  61. unset(self:: $_store[$name]);
  62. }
  63. }
  64. }
複製代碼

在類別外部,使用Registry類別:

  1. require 'Registry.php';

  2. class DBReadConnection {}

  3. class DBWrite {}
  4. $read = new DBReadConnection;

  5. Registry::add($read);
  6. $write = new DBWriteConnection;

  7. Registry ::add($write);
  8. // To get the instances, anywhere in our code:

  9. $read = Registry::get('DBReadConnection');
  10. $ write = Registry::get('DBWriteConnection');
  11. var_dump($read);

  12. var_dump($write);
複製程式碼

在類別內部使用Registry表類,使用者不與Registry互動。

範例程式碼:

  1. require 'Registry.php';

  2. abstract class DBConnection {

  3. static public function getInstance($name = null)
  4. {
  5. // Get the late-static-binding version of __CLASS__
  6. $class = get_called_class();
  7. // Allow passing in a name to get multiple instances
  8. // If you do not pass a name, it functions as a singleton
  9. $name = (!is_null($name)) ? $name:$class;
  10. if (!Registry::contains ($name)) {
  11. $instance = new $class();
  12. Registry::add($instance, $name);
  13. }
  14. return Registry::get($name);
  15. }
  16. }
  17. class DBWriteConnection extends DBConnection {

  18. public function __construct()
  19. {
  20. echo 'DBWConnectiona
    ';
  21. {
  22. echo 'DBWConnectiona
    ';
  23. ';
  24. }
  25. }
  26. class DBReadConnection extends DBConnection {

  27. public function __construct()
  28. {
  29. echo 'DBRead
    ';
  30. Connection
  31. echo 'DBRead
    ';
  32. Connection
  33. Connection
}

$dbWriteConnection = DBWriteConnection::getInstance('abc');var_dump($dbWriteConnection);$dbReadConnection = DBRead::getInstance(); var_dump($dbReadConnection);

複製程式碼

4.工廠模式 工廠(factory)模式製造對象,就像工業界與它同名的鋼筋混泥土產業一樣。通常,我們將工廠模式用於初始化相同抽象類別或介面的具體實作。

在通常方式下,雖然人們極少採用工廠模式,但是它仍是最適合初始化基於驅動安裝的許多變種的一種。例如不同的配置、會話或快取儲存引擎。工廠模式的最大價值在於它可以將多個物件設定封裝成單一、簡單的方法呼叫。

  1. /**
  2. * 日誌工廠
  3. *
  4. * 設定並傳回檔案、mysql 或 sqlite 記錄器
  5. */
  6. class Log_Factory {
  7. /**
  8. * 取得日誌物件
  9. *
  10. * @param string $type 日誌記錄後端的類型,檔案、mysql 或 sqlite
  11. * @param array $options 日誌類別選項
  12. */
  13. public function Log( $type = 'file', array $options)
  14. {
  15. // Normalize the type to lowercase
  16. $type = strtolower($type);
  17. // Figure out the class name and include it
  18. $class = "Log_" .ucfirst($type);
  19. require_once str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
  20. // Instantiate the class and set the appropriate options
  21. $log = new $class($options);
  22. switch ($type) {
  23. case 'file':
  24. $log->setPath($options[' location']);
  25. break;
  26. case 'mysql':
  27. $log->setUser($options['username']);
  28. $log->setPassword($options['password ']);
  29. $log->setDBName($options['location']);
  30. break;
  31. case 'sqlite':
  32. $log->setDBPath($otions['location' ]);
  33. break;
  34. }
  35. return $log;
  36. }
  37. }
複製代碼

5.迭代模式 迭代模式允許我們將foreach的性能添加到任何物件的內部儲存數據,而不僅僅添加到公共屬性。它覆蓋了預設的foreach行為,並允許我們為循環注入業務邏輯。

(1)使用Iterator迭代器接口

  1. class BasicIterator implements Iterator {

  2. private $key = 0;
  3. private $data = array( "world",
  4. );
  5. public function __construct() {

  6. $this->key = 0;
  7. }
  8. public function rewind() {

  9. $this->key = 0;
  10. }
  11. public function current() {

  12. return $this ->data[$this->key];
  13. }
  14. public function key() {

  15. return $this->key;
  16. }
  17. public function next() {

  18. $this->key++;
  19. return true;
  20. }
  21. public function valid() {

  22. return isset($this->data[$this->key]);
  23. }
  24. }
  25. $iterator = new BasicIterator();

  26. $iterator->rewind ();
  27. do {

  28. $key = $iterator->key();
  29. $value = $iterator->current();
  30. echo $key . ': ' .$value . PHP_EOL;
  31. } while ($iterator->next() && $iterator->valid());
  32. $iterator = new BasicIterator ();
  33. foreach ($iterator as $key => $value) {
  34. echo $key .': ' .$value . PHP_EOL;
  35. }
複製程式碼
(2)使用RecursiveIteratorIterator迭代器遍歷數組

  1. $array = array(

  2. "Hello", // Level 1
  3. array(
  4. "World " // Level 2
  5. ),
  6. array(
  7. "How", // Level 2
  8. array(
  9. "are", // Level 3
  10. "you" // Level 3
  11. )
  12. ),
  13. "doing?" // Level 1
  14. );
  15. $recursiveIterator = new RecursiveArrayIterator($array);

  16. $recursiveIteratorIterator = new RecursiveIteratorIterator($recursiveIterator);

  17. foreach ($recursiveIteratorIterator as $key => $value) {

  18. echo "Depth: " value. recursiveIteratorIterator->getDepth() . PHP_EOL;
  19. echo "Key: " . $key . PHP_EOL;
  20. echo "Value: " .$value . PHP_EOL;
  21. }
複製程式碼

(3)用FilterIterator迭代器實現過濾

  1. class EvenFilterIterator extends FilterIterator {

  2. /**
  3. * 僅接受偶數鍵值
  4. *
  5. * @return bool
  6. > / {
  7. // 取得實際的迭代器
  8. $iterator = $this->getInnerIterator();
  9. // 取得目前的key
  10. $ key = $iterator->key();
  11. // 檢查偶數鍵
  12. if ($key % 2 == 0) {
  13. return true;
  14. }
  15. return false;
  16. }
  17. }
  18. $array = array(

  19. 0 => "你好",
  20. 1 => "每個人都是”,
  21. 2 => 「我」,
  22. 3 => 「太棒了」,
  23. 4 => 「那個」,
  24. 5 => 「誰」,
  25. 6 => "Doctor" ,
  26. 7 => "Lives"
  27. );
  28. // 從我們的陣列建立一個迭代器

  29. $ iterator = new ArrayIterator($array); p>
  30. // 建立FilterIterator

  31. $filterIterator = new EvenFilterIterator($iterator);
  32. foreach ($filterIterator as $key => $value) {

  33. echo $key .': '. $價值。 PHP_EOL;
  34. }
  35. ?>
複製程式碼
(4)RegexIterator迭代器

  1. // 建立一個RecursiveDirectoryIterator

  2. $directoryIterator = 建立一個RecursiveDirectoryIterator
  3. $directoryIterator = 建立一個RecursiveDirectoryIterator
  4. $directoryIterator = 建立一個RecursiveDirectoryIterator
  5. // 建立一個RecursiveIteratorIterator 進行遞歸迭代

  6. $recursiveIterator = new RecursiveIteratorIterator($directoryIterator);
  7. //ator 建立一個過濾器*. php 檔案

  8. $regexFilter = new RegexIterator($recursiveIterator, '/(.*?)Iterator(.*?).php$/');
  9. // 迭代
  10. foreach ($regexFilter as $key => $file) {
  11. /* @var SplFileInfo $file */
  12. echo $file->getFilename() . PHP_EOL;
  13. }
複製程式碼

功能:找到所有的php檔案

(4)LimitItertor迭代器,像SQL中的LIMIT
  1. //定義數組

  2. $array = array(
  3. 'Hello',
  4. '$array = array(
  5. 'Hello',
  6. ' ',,,
  7. '怎麼樣',
  8. '是',
  9. '你',
  10. '做什麼? 🎜>$iterator = new ArrayIterator($array);
  11. // 建立限制迭代器,取得前2 個元素

  12. $limitIterator = new LimitIterator($ iterator, 0, 2) ;
  13. //迭代

  14. foreach ($limitIterator as $key => $value) {
  15. echo $key .': '. $值。 PHP_EOL;
  16. }
複製程式碼

6.觀察者模式(observer)

觀察者模式的核心在於雲霄你的應用程式註冊一個回調,當某個特定的事件發生時便會促發它

  1. /**

  2. * 事件類
  3. *
  4. * 使用這個類,您可以註冊將
  5. * 為給定事件調用(先進先出)的回調。
  6. */
  7. class Event {
  8. /**
  9. * @var array 事件的多維數組 =>回呼
  10. */
  11. class Event {
  12. /**
  13. * 註冊回呼
  14. *
  15. * @param string $eventName 觸發事件的名稱
  16. * @param mix $callback Event_Callback 或 Closure 的實例
  17. */
  18. class Event {
  19. /**
  20. * 觸發事件
  21. *
  22. * @param string $eventName 要觸發的事件名稱
  23. * @param mix $data 要傳送到回呼的資料
  24. */
  25. class Event {
  26. /**
  27. * 執行回呼
  28. *
  29. * @param mix $callback Event_Callback 或閉包的實例
  30. * @param mix $data 傳送到回調的資料
  31. */
  32. class Event {
  33. /**
  34. * 事件回呼介面
  35. *
  36. * 如果你不想使用閉包
  37. * 你可以定義一個擴充
  38. * this 的類別。 run 方法將
  39. * 當事件觸發時被呼叫。
  40. */
  41. static protected $callbacks = array();
  42. /**
  43. * 記錄器回呼
  44. */
  45. static public function registerCallback($eventName, $call>back)
  46. back {
  47. if (!($callback instanceof Event_Callback) && !($callback instanceof Closure)) {
  48. throw new Exception("Invalid callback!");
  49. }
  50. self::$callbacks[$eventName][] = $callback;
  51. }
  52. /***/
  53. static public function trigger ($eventName, $data)
  54. {
  55. $eventName = strtolower($eventName);
  56. if (isset(self::$callbacks[$eventName])) {
  57. foreach ( self::$callbacks[$eventName] as $callback) {
  58. self::callback($callback, $data);
  59. }
  60. }
  61. }
  62. /** */
  63. static protected function callback($callback, $data)
  64. {
  65. if ($callback instanceof Closure) {
  66. $callback($data);
  67. }
  68. }
  69. }
  70. }
  71. }
  72. }
  73. }
  74. }
  75. }
  76. }
  77. }
  78. }
  79. }
  80. }
  81. }
  82. }
  83. }
  84. }
  85. }
  86. }
  87. } else
  88. $callback->run($data);
  89. }
  90. }
  91. }
  92. /***/

  93. interface Event_Callback { public function run($data);
  94. }
  95. /***/

class LogCallback implements Event_Callback {
public function run($data) { echo "Log Data" . PHP_EOL;
var_dump($data); }}

// Register the log callbackEvent::registerCallback('save', new LogCallback());

// Register the clear cache callback as a closureEvent::registerCallback('save', function ( $data) { echo "Clear Cache" . PHP_EOL; var_dump($data); });

class MyDataRecord { public function save( ) { // Save data // Trigger the save event Event::trigger('save', array("Hello", "World")); }}

// Instantiate a new data record$data = new MyDataRecord();$data->save(); // 'save' Event is triggered here

複製程式碼

7.依賴注入模式 依賴注入模式允許類別的使用這為這個類別注入依賴的行為。

  1. /**

  2. * 日誌類別
  3. */
  4. class Log {
  5. /**
  6. * @var Log_Engine_Interface
  7. */
  8. protected $engine = false;
  9. /**
  10. * 將事件新增至日誌
  11. *
  12. * @param string $message
  13. */
  14. public function add($message)
  15. {
  16. if (!$this->engine) {
  17. throw new Exception('Unable to write log. No Engine set.');
  18. }
  19. $data['datetime'] = time();
  20. $data['message' ] = $message;
  21. $session = Registry::get('session');
  22. $data['user'] = $session->getUserId();
  23. $ this->engine->add($data);
  24. }
  25. /**
  26. * 設定日誌資料儲存引擎
  27. *
  28. * @param Log_Engine_Interface $Engine
  29. */
  30. public function setEngine(Log_Engine_Interface $engine)
  31. {
  32. $this ->engine = $engine;
  33. }
  34. /**
  35. * 擷取資料儲存引擎
  36. *
  37. * @return Log_Engine_Interface
  38. */
  39. public function getEngine()
  40. {
  41. return $this->engine>;
  42. ; }
  43. }
  44. interface Log_Engine_Interface {

  45. /**
  46. * 將事件新增至日誌
  47. *
  48. * @param string $message
  49. */
  50. public function add(array $data);
  51. }
  52. class Log_Engine_File implements Log_Engine_Interface {

  53. /**
  54. * 將事件新增至日誌
  55. *
  56. * @param string $message
  57. */
  58. public function add(array $data)
  59. {
  60. $line = '[' .data('r ', $data['datetime']). '] ' .$data['message']. ' User: ' .$data['user'] . PHP_EOL;
  61. $config = Registry:: get('site-config');
  62. if (!file_put_contents($config['location'], $line, FILE_APPEND)) {
  63. throw new Exception("An error occurred writing to file. ");
  64. }
  65. }
  66. }
  67. $engine = new Log_Engine_File();

  68. $log = new Log() ;

  69. $log->setEngine($engine);
  70. // Add it to the registry

  71. Registry::add($log);
複製程式碼

依賴注入不想工廠模式,日之類無需了解每一個不同的儲存引擎的相關知識。這意味著任何使用日誌類別的開發者可以添加他們自己的儲存引擎,主要他們複合介面就行。

8.模型-視圖-控制器 模型-視圖-控制器又稱為MVC模式,是描述應用程式3個不同層次之間關係的一種方式。 模型-資料層 所有的輸出資料都來自模型。它可能是一個資料庫、web服務或文件。 視圖-表現層 負責將資料從模型中取出並輸出給使用者。 控制器-應用程式流程層 根據使用者的請求呼叫對應的模型檢索出請求的數據,然後呼叫視圖將操作的結果顯示給使用者。

一個典型的MVC架構圖: php mvc架构图

9.對模式的理解
模式是許多常見問題的最佳解決方法。

您可能感興趣的文章:

  • php設計模式單例模式、工廠模式與觀察者模式
  • 深入php設計模式實例詳解
  • php設計模式實例之指令模式
  • php設計模式實例之觀察者模式(2)
  • PHP設計模式實例之觀察者模式
  • php設計模式實例之工廠模式
  • php設計模式實例之單例模式
  • PHP設計模式之觀察者模式的例子
  • php設計模式之工廠模式的實例代碼
  • php設計模式之單例模式的實例程式碼
  • php常用設計模式之工廠模式與單例模式介紹
  • 學習php設計模式之單例模式
  • php常用的三種設計模式的學習筆記
  • php設計模式之單例模式學習


陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
在Laravel中使用Flash會話數據在Laravel中使用Flash會話數據Mar 12, 2025 pm 05:08 PM

Laravel使用其直觀的閃存方法簡化了處理臨時會話數據。這非常適合在您的應用程序中顯示簡短的消息,警報或通知。 默認情況下,數據僅針對後續請求: $請求 -

php中的捲曲:如何在REST API中使用PHP捲曲擴展php中的捲曲:如何在REST API中使用PHP捲曲擴展Mar 14, 2025 am 11:42 AM

PHP客戶端URL(curl)擴展是開發人員的強大工具,可以與遠程服務器和REST API無縫交互。通過利用Libcurl(備受尊敬的多協議文件傳輸庫),PHP curl促進了有效的執行

簡化的HTTP響應在Laravel測試中模擬了簡化的HTTP響應在Laravel測試中模擬了Mar 12, 2025 pm 05:09 PM

Laravel 提供简洁的 HTTP 响应模拟语法,简化了 HTTP 交互测试。这种方法显著减少了代码冗余,同时使您的测试模拟更直观。 基本实现提供了多种响应类型快捷方式: use Illuminate\Support\Facades\Http; Http::fake([ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

PHP記錄:PHP日誌分析的最佳實踐PHP記錄:PHP日誌分析的最佳實踐Mar 10, 2025 pm 02:32 PM

PHP日誌記錄對於監視和調試Web應用程序以及捕獲關鍵事件,錯誤和運行時行為至關重要。它為系統性能提供了寶貴的見解,有助於識別問題並支持更快的故障排除

在Codecanyon上的12個最佳PHP聊天腳本在Codecanyon上的12個最佳PHP聊天腳本Mar 13, 2025 pm 12:08 PM

您是否想為客戶最緊迫的問題提供實時的即時解決方案? 實時聊天使您可以與客戶進行實時對話,並立即解決他們的問題。它允許您為您的自定義提供更快的服務

解釋PHP中晚期靜態結合的概念。解釋PHP中晚期靜態結合的概念。Mar 21, 2025 pm 01:33 PM

文章討論了PHP 5.3中介紹的PHP中的晚期靜態結合(LSB),允許靜態方法的運行時間分辨率調用以更靈活的繼承。 LSB的實用應用和潛在的觸摸

自定義/擴展框架:如何添加自定義功能。自定義/擴展框架:如何添加自定義功能。Mar 28, 2025 pm 05:12 PM

本文討論了將自定義功能添加到框架上,專注於理解體系結構,識別擴展點以及集成和調試的最佳實踐。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具