2014-10-29 28 views
6

不知道如何正確標題。雖然挖到Laravel 4班怎麼看外牆工作,我偶然發現了這一點:PHP Laravel Facade __callStatic參數列表

Illuminate\Support\Facades\[email protected]__callStatic 

public static function __callStatic($method, $args) 
{ 
    $instance = static::getFacadeRoot(); 

    switch (count($args)) 
    { 
     case 0: 
      return $instance->$method(); 

     case 1: 
      return $instance->$method($args[0]); 

     case 2: 
      return $instance->$method($args[0], $args[1]); 

     case 3: 
      return $instance->$method($args[0], $args[1], $args[2]); 

     case 4: 
      return $instance->$method($args[0], $args[1], $args[2], $args[3]); 

     default: 
      return call_user_func_array(array($instance, $method), $args); 
    } 
} 

現在從我可以告訴這個方法調用任何類的既定方法門面引用,並一起傳遞的參數。我可能是錯的,但這是我迄今爲止的理解。

真正讓我感到困惑的部分是開關。

爲什麼情況0到4需要默認情況下工作不管。

即使case 0類型在沒有參數的情況下有意義,爲什麼會有case 1-4,而不僅僅是case 10的例子。有沒有合理的論點呢,還是僅僅是一個過早優化的案例?

回答

4

我懷疑這是一個微型優化。我也懷疑大多數靜態調用Facade會需要4個或更少的參數,在這種情況下,大多數靜態調用不會跳轉到默認情況。

我能找到這個用戶提交的報價從上call_user_func_array手工錄入「的例子沒有人點com」:

對於那些你必須考慮性能:它需要大約3倍只要以這種方式調用函數而不是通過直接聲明,那麼只要避免這種方法是可行的,那麼這樣做是明智的想法。

做一個非常簡單的基準也似乎印證這一有效性。在結果中,1直接調用實例上的方法,2調用實例上的變量方法名稱,3使用call_user_func_array,輸出時間以秒爲單位。每種方法的迭代次數爲1,000,000次。

$ php test.php 
(1) total: 0.51281404495239 
(2) total: 0.51285219192505 
(3) total: 1.1298811435699 
$ php test.php 
(1) total: 0.49811697006226 
(2) total: 0.5209321975708 
(3) total: 1.1204349994659 
$ php test.php 
(1) total: 0.48825788497925 
(2) total: 0.51465392112732 
(3) total: 1.156769990921 

以上的結果表明,避免call_user_func_array至少可以通過圍繞的2倍加快到靜態門面方法的調用,除非靜態方法具有多於4個參數。至於爲什麼選擇4個參數的截止數,只有泰勒知道。自從Laravel 4.0的first commit以來,該方法一直(大部分)沒有變化,我懷疑它有點武斷。

3

因爲$instance->$method()的方式快於call_user_func_array

鑑於這段代碼可以在單個循環中多次調用,因此儘可能優化它是有意義的。

4

你是對的,呼籲call_user_func_array();完美的作品,沒有使用switch聲明。 ,根據本benchmark,這似乎非常緩慢:

function html($value) 
{ 
    return htmlentities($value); 
} 

name   : diff  : total : description 
native   : 0.614219 : 0.613295 : htmlentities($value) 
literal_func : 0.745537 : 1.346594 : html($value) 
variable_func : 0.826048 : 2.162376 : $func($value) 
literal_method : 0.957708 : 3.127519 : $object->html($value) 
variable_method : 0.840837 : 3.970290 : $object->$func($value) 
call_func  : 1.006599 : 4.993930 : call_user_func($func, $value) 
call_object  : 1.193323 : 6.215677 : call_user_func((array($object, $func), $value) 
cufa_func  : 1.232891 : 7.320287 : call_user_func_array($func, array($value)) 
cufa_object  : 1.309725 : 8.769755 : call_user_func_array((array($object, $func), array($value) 

所以基本上,當你使用call_user_func_array()很多次了(這是Laravel的情況下),這隻能成爲一個問題。這就是他們使用switch聲明的原因。