首頁 後端開發 php教程 ThinkPhp5中關於instance實作的簡單實例

ThinkPhp5中關於instance實作的簡單實例

May 16, 2018 am 11:05 AM
php thinkphp5

這篇文章主要介紹了淺談thinkphp5 instance 的簡單實現,具有一定的參考價值,有興趣的小夥伴們可以參考一下

最近學習ThinkPHP5,第一次看到TestClass: :instance() 就能創建TestClass 實例的方法。感到很好奇,翻閱 ThinkPHP 的源代碼,大體理解了 它的 設計思想,非常的先進。

老規矩,直接上程式碼:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

<?php

class TestClass {

  

 public static function instance() {

  return new self();

 }

  

 public $data = [];

  

 public function __set($name, $val) {

  return $this->data[$name] = $val;

 }

  

 public function __get($name) {

  return $this->data[$name];

 }

}

  

$app1 = TestClass::instance();

$app1->key = 'Application 1';

echo $app1->key . '<br />';

?>

登入後複製

為了方便調用,也模仿 ThinkPHP 寫了一個助手函數

1

2

3

4

5

6

7

8

9

<?php

function app() {

 return TestClass::instance();

}

  

$app2 = app();

$app2->key = 'Application 2';

echo $app2->key . '<br />';

?>

登入後複製

這樣就簡單的實作了 instance。

不過這種方法還有一個小問題,試想以下,呼叫100次,就需要創建100個實例,想想都覺得可怕。

為 Test 類別 增加一個 靜態屬性,將建立的實例儲存到這裡。下次如果需要調用,則直接調用這個實例。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

<?php

class TestClass {

  

 public static $instance; //用于缓存实例

  

 public $data = [];

  

 public static function instance() {

  //如果不存在实例,则返回实例

  if (empty(self::$instance)) {

   self::$instance = new self();

  }

  return self::$instance;

 }

  

 public function __set($name, $val) {

  return $this->data[$name] = $val;

 }

  

 public function __get($name) {

  return $this->data[$name];

 }

  

}

  

function app($option = []) {

 return TestClass::instance($option);

}

  

header('content-type:text/plain');

  

$result = [];

$app1 = app();

$app1->key = "Application 1"; //修改 key 为 Application 1

$result['app1'] = [

 'app1' => $app1->key, //实例中 key 为 Application 1

];

  

// 创建 app2,因为 instance 已经存在实例,直接返回 缓存的实例

$app2 = app();

$result['app2'] = [

 'setp1' => [

  'app1' => $app1->key, // Application 1

  'app2' => $app2->key, //因为直接调用的实例的缓存,所以 key 也是 Application 1

 ],

];

  

// 无论 app1,app2 都对在内存中 对应的同一个实例,无论通过谁修改,都能改变值

$app1->key = "Application 2";

$result['app2']['setp2'] = [

 'app1' => $app1->key, // Application 2

 'app2' => $app2->key, // Application 2

];

print_r($result);

?>

登入後複製

透過上邊的實驗,可以看到 無論呼叫多少次,都會使用同一個實例。這樣就解決了效率低的問題。

到現在基本上就滿足大多數情況了,唯一的小缺陷,就是 可能 實例的 初始參數不同,這樣沒法靈活調用(常見的比如同一個程式調用兩個數據庫)。在 上邊的 例子中稍作改造,以傳入的參數為key,將不通的 實例緩存到數組中 就可以解決。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

<?php

class TestClass {

  

 public static $instance = []; //用于缓存实例数组

 public $data = [];

  

 public function __construct($opt = []) {

  $this->data = $opt;

 }

  

 public static function instance($option = []) {

  // 根据传入的参数 通过 serialize 转换为字符串,md5 后 作为数组的 key

  $instance_id = md5(serialize($option));

  //如果 不存在实例,则创建

  if (empty(self::$instance[$instance_id])) {

   self::$instance[$instance_id] = new self($option);

  }

  return self::$instance[$instance_id];

 }

  

 public function __set($name, $val) {

  return $this->data[$name] = $val;

 }

  

 public function __get($name) {

  return $this->data[$name];

 }

  

}

  

function app($option = []) {

 return TestClass::instance($option);

}

  

header('content-type:text/plain');

  

$result = [];

//传入 初始数据

$app1 = app(['key' => '123']);

$result['init'] = $app1->key; // 使用 传入的数据,即:123

$app1->key = "app1";

$result['app'] = $app1->key; // 现在值改为了 自定义的 app1了

print_r($result);

  

$result = [];

// 创建 app2,注意 初始参数不一样

$app2 = app();

// 因为初始参数不一样,所以还是创建新的实例

$app2->key = "app2";

$result['app1'] = $app1->key; // app1

$result['app2'] = $app2->key; // app2

print_r($result);

  

$result = [];

// 创建 app3,传入的参数 和 app1 一样,所以会直接返回 和app1相同 的 实例

$app3 = app(['key' => '123']);

$result['log'] = [

 'app1' => $app1->key, // app1

 'app2' => $app2->key, // app2

 'app3' => $app3->key, // app1

];

  

// 设置 app3 的key,会自动修改 app1 的值,因为他们两个是同一个实例

$app3->key = 'app3';

$result['app3_set'] = [

 'app1' => $app1->key, // app3

 'app2' => $app2->key, // app2

 'app3' => $app3->key, // app3

];

  

// 同理,设置 app1 的key,app3 的 key 也会修改

$app1->key = 'app1';

$result['app1_set'] = [

 'app1' => $app1->key, // app1

 'app2' => $app2->key, // app2

 'app3' => $app3->key, // app1

];

print_r($result);

?>

登入後複製

以上是ThinkPhp5中關於instance實作的簡單實例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱門文章

倉庫:如何復興隊友
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱門文章

倉庫:如何復興隊友
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱門文章標籤

記事本++7.3.1

記事本++7.3.1

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

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 Dec 24, 2024 pm 04:42 PM

適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南

CakePHP 日期和時間 CakePHP 日期和時間 Sep 10, 2024 pm 05:27 PM

CakePHP 日期和時間

CakePHP 檔案上傳 CakePHP 檔案上傳 Sep 10, 2024 pm 05:27 PM

CakePHP 檔案上傳

CakePHP 路由 CakePHP 路由 Sep 10, 2024 pm 05:25 PM

CakePHP 路由

CakePHP 專案配置 CakePHP 專案配置 Sep 10, 2024 pm 05:25 PM

CakePHP 專案配置

討論 CakePHP 討論 CakePHP Sep 10, 2024 pm 05:28 PM

討論 CakePHP

CakePHP 快速指南 CakePHP 快速指南 Sep 10, 2024 pm 05:27 PM

CakePHP 快速指南

如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 Dec 20, 2024 am 11:31 AM

如何設定 Visual Studio Code (VS Code) 進行 PHP 開發

See all articles