PHP 用 Object 方式呼叫 static 的 method

Laravel 的 facade 提供了 static 呼叫 object 的方式,可謂是一門藝術,讓呼叫方式變得更簡單,網路讓有很多人在戰這有沒有反 OOP,其實不是很重要,開發快速、好懂、好維護比較重要!不過今天不是要介紹 Laravel 也不是介紹 facade,更不是介紹多麼神奇又漂亮的 coding 方法,而是要解決一些問題…

舊的 code 使用 static 的方式呼叫,因為需求所以要改成 object 的方式呼叫…但是又沒辦法修改所有舊的 code,這種時候只能相容舊的,未來用新的方式,但是 object 方式呼叫!

因為要把 object 呼叫的方式轉換成 static 呼叫,所以必須要透過 magic methods 中的 __call 來把所有的 method 呼叫攔截起來,並且轉換為 static 呼叫,而要轉換成 static 呼叫,就必須要使用 forward_static_call_array,這個 method 有點類似 call_user_function,不過可以呼叫 static method 並帶入 arguments

完整程式碼如下:

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
<?php
Class A {
protected static $name = 'Shiny';
public function __call($name, $arguments) {
forward_static_call_array(array('A', $name), $arguments);
}
public static function setName($name) {
self::$name = $name;
}
public static function getName() {
return self::$name;
}
}
$a = new A();
echo A::getName()."<br>"; // Shiny
echo $a->getName()."<br>"; // Shiny
$a->setName('Ann');
echo $a->getName()."<br>"; // Ann
echo A::getName()."<br>"; // Ann
A::setName('Tracy');
echo $a->getName()."<br>"; // Tracy
echo A::getName()."<br>"; // Tracy
$b = new A();
echo $b->getName()."<br>"; // Tracy

透過已上的設定,就可以達到 object 與 static 呼叫方式等價,髒髒的,但是在需要的時候還挺有用的…

參考資料:

  1. 讓你少打很多字:FACADES。