2014-07-22 31 views
10

在PHP laravel,我們有像爲什麼在PHP的laravel模型類中使用靜態方法?

$user = User::find(1); 
var_dump($user->name); 

我不是關於如何使用find方法的代碼,我就爲什麼laravel使用靜態方法?不應該使用靜態方法使該方法難以測試?

會不會是更好,如果他們使用設計的單?

例如

$user = User::getInstance()->find(1); 
var_dump($user->name); 

回答

2

這將限制系統只有一個用戶。雖然find方法可能是靜態的,但用戶類將具有其他方法和屬性,例如:$user->name

一種不依賴於任何實例變量的方法,即變量的值是特定於特定的對象實例,而是提供適用於所有實例的通用功能,可以並且可能應該是靜態的。這就是爲什麼$this運算符在靜態方法內是不合法的,因爲它不能引用特定的對象實例。

11

事實上,你的例子非常相似,Laravel做幕後。當你做User::find()時,你實際上是要求一個新的實例,一個Collection實例或一個QueryBuilder。

照亮\數據庫\雄辯\模型(reference):

public static function find($id, $columns = array('*')) 
{ 
    if (is_array($id) && empty($id)) return new Collection; 

    $instance = new static; 

    return $instance->newQuery()->find($id, $columns); 
} 

作爲一個側面說明,你還可以看到在Laravel例如使用靜態方法的另一種方式Input::get()。這些被稱爲立面。

Facades爲應用程序的IoC容器中提供的類提供「靜態」接口... Laravel「Facades」充當IoC容器中基礎類的「靜態代理」,提供了簡潔的好處,表達的語法,同時保持比傳統靜態方法更多的可測試性和靈活性。

當使用者參照上...門面任何靜態方法,Laravel解決了高速緩存從IoC容器綁定和運行要求的方法(在這種情況下,獲取)針對該對象。

您可以閱讀更多關於Larave的外牆:http://laravel.com/docs/facades

+0

'class User extends Illuminate \ Database \ Eloquent \ Model','User'不是門面類 – Razor

+1

正確的你發現了一個巨大的錯誤。修改我的答案。 – Unnawut

+0

另外,Facades(設計模式)不需要是靜態的。 –

13

Unnawut有一個很好的答案,但我覺得有必要在進一步的解釋中添加。

在您的例子

$user = User::find(1); 
var_dump($user->name); 

Laravel沒有使用靜態方法,你是。另一種可能的方法是使用依賴注入,Laravel非常簡單,因爲它可以自動完成。所以在任何你使用User模型的課程中,你都應該在構造函數中設置這樣的東西......

public function __construct(User $user) 
{ 
    $this->user = $user; 
} 

然後你可以修改你的代碼來不使用靜態綁定。

$user = $this->user->find(1); 
var_dump($user->name); 
+2

Whaaaat !!我們可以在每個外牆都做到這一點嗎?我可以注入Mail facade,然後執行$ this-> mail-> send? * 0 * –

+0

是的,你可以做任何事情。 https://laravel.com/docs/5.1/container – user3158900

+1

太棒了!謝謝! – mpemburn

-2

GRASP patterns之後,User對象不具備能夠搜索用戶的知識。

您需要一種Filter或Collection對象,::find()方法可以幫助您創建Collection過濾器並將結果轉換爲有用的實體。

對於User實體的用法,您只需更改屬性的值並檢索值即可。實體沒有責任根據條件搜索實例。

有了這個邏輯,你將能夠在原子代碼中解耦代碼中的邏輯。

相關問題