搜尋
首頁後端開發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
PHP如何識別用戶的會話?PHP如何識別用戶的會話?May 01, 2025 am 12:23 AM

phpIdentifiesauser'ssessionSessionSessionCookiesAndSessionId.1)whiwsession_start()被稱為,phpgeneratesainiquesesesessionIdStoredInacookInAcookInAcienamedInAcienamedphpsessIdontheuser'sbrowser'sbrowser.2)thisIdallowSphptpptpptpptpptpptpptpptoretoreteretrieetrieetrieetrieetrieetrieetreetrieetrieetrieetrieetremthafromtheserver。

確保PHP會議的一些最佳實踐是什麼?確保PHP會議的一些最佳實踐是什麼?May 01, 2025 am 12:22 AM

PHP會話的安全可以通過以下措施實現:1.使用session_regenerate_id()在用戶登錄或重要操作時重新生成會話ID。 2.通過HTTPS協議加密傳輸會話ID。 3.使用session_save_path()指定安全目錄存儲會話數據,並正確設置權限。

PHP會話文件默認存儲在哪裡?PHP會話文件默認存儲在哪裡?May 01, 2025 am 12:15 AM

phpsessionFilesArestoredIntheDirectorySpecifiedBysession.save_path,通常是/tmponunix-likesystemsorc:\ windows \ windows \ temponwindows.tocustomizethis:tocustomizEthis:1)useession_save_save_save_path_path()

您如何從PHP會話中檢索數據?您如何從PHP會話中檢索數據?May 01, 2025 am 12:11 AM

ToretrievedatafromaPHPsession,startthesessionwithsession_start()andaccessvariablesinthe$_SESSIONarray.Forexample:1)Startthesession:session_start().2)Retrievedata:$username=$_SESSION['username'];echo"Welcome,".$username;.Sessionsareserver-si

您如何使用會議來實施購物車?您如何使用會議來實施購物車?May 01, 2025 am 12:10 AM

利用會話構建高效購物車系統的步驟包括:1)理解會話的定義與作用,會話是服務器端的存儲機制,用於跨請求維護用戶狀態;2)實現基本的會話管理,如添加商品到購物車;3)擴展到高級用法,支持商品數量管理和刪除;4)優化性能和安全性,通過持久化會話數據和使用安全的會話標識符。

您如何在PHP中創建和使用接口?您如何在PHP中創建和使用接口?Apr 30, 2025 pm 03:40 PM

本文解釋瞭如何創建,實施和使用PHP中的接口,重點關注其對代碼組織和可維護性的好處。

crypt()和password_hash()有什麼區別?crypt()和password_hash()有什麼區別?Apr 30, 2025 pm 03:39 PM

本文討論了PHP中的crypt()和password_hash()的差異,以進行密碼哈希,重點介紹其實施,安全性和對現代Web應用程序的適用性。

如何防止PHP中的跨站點腳本(XSS)?如何防止PHP中的跨站點腳本(XSS)?Apr 30, 2025 pm 03:38 PM

文章討論了通過輸入驗證,輸出編碼以及使用OWASP ESAPI和HTML淨化器之類的工具來防止PHP中的跨站點腳本(XSS)。

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脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具