在PHP laravel,我們有像爲什麼在PHP的laravel模型類中使用靜態方法?
$user = User::find(1);
var_dump($user->name);
我不是關於如何使用find
方法的代碼,我就爲什麼laravel使用靜態方法?不應該使用靜態方法使該方法難以測試?
會不會是更好,如果他們使用設計的單?
例如
$user = User::getInstance()->find(1);
var_dump($user->name);
在PHP laravel,我們有像爲什麼在PHP的laravel模型類中使用靜態方法?
$user = User::find(1);
var_dump($user->name);
我不是關於如何使用find
方法的代碼,我就爲什麼laravel使用靜態方法?不應該使用靜態方法使該方法難以測試?
會不會是更好,如果他們使用設計的單?
例如
$user = User::getInstance()->find(1);
var_dump($user->name);
這將限制系統只有一個用戶。雖然find
方法可能是靜態的,但用戶類將具有其他方法和屬性,例如:$user->name
一種不依賴於任何實例變量的方法,即變量的值是特定於特定的對象實例,而是提供適用於所有實例的通用功能,可以並且可能應該是靜態的。這就是爲什麼$this
運算符在靜態方法內是不合法的,因爲它不能引用特定的對象實例。
事實上,你的例子非常相似,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
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);
Whaaaat !!我們可以在每個外牆都做到這一點嗎?我可以注入Mail facade,然後執行$ this-> mail-> send? * 0 * –
是的,你可以做任何事情。 https://laravel.com/docs/5.1/container – user3158900
太棒了!謝謝! – mpemburn
繼GRASP patterns之後,User對象不具備能夠搜索用戶的知識。
您需要一種Filter或Collection對象,::find()
方法可以幫助您創建Collection過濾器並將結果轉換爲有用的實體。
對於User
實體的用法,您只需更改屬性的值並檢索值即可。實體沒有責任根據條件搜索實例。
有了這個邏輯,你將能夠在原子代碼中解耦代碼中的邏輯。
'class User extends Illuminate \ Database \ Eloquent \ Model','User'不是門面類 – Razor
正確的你發現了一個巨大的錯誤。修改我的答案。 – Unnawut
另外,Facades(設計模式)不需要是靜態的。 –