在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/PHP  網(wǎng)絡(luò)安全/ Laravel 里為什么可以用Model::where(),卻不能用Model:

Laravel 里為什么可以用Model::where(),卻不能用Model::getTable()

我理解是:

調(diào)用 Model::where(),
Model 里沒有靜態(tài)方法 where(),于是會(huì)觸發(fā) __callStatic(),
__callStatic() 中會(huì)試圖去調(diào)用實(shí)例方法 where()Model 也沒有 where(),于是觸發(fā) __call(),
__call() 中實(shí)例化 \Illuminate\Database\Eloquent\Builder,然后調(diào)用 Builder 的實(shí)例方法 where()。

調(diào)用 Model::getTable()
Model 里沒有靜態(tài)方法 getTable(),于是會(huì)觸發(fā) __callStatic(),
__callStatic() 中會(huì)試圖去調(diào)用實(shí)例方法 getTable(),Model 有定義,所以應(yīng)該直接調(diào)用getTable()

但是卻報(bào)錯(cuò)

Non-static method Illuminate\Database\Eloquent\Model::getTable() should not be called statically, assuming $this from incompatible context


查了一下錯(cuò)誤的原因,鳥哥在這篇文章解釋了,PHP 的 Calling Scope


問題是,那為什么可以用 Model::where()?

回答
編輯回答
失魂人

getTable方法在Model里面定義的是非靜態(tài)方法

public function getTable()

直接調(diào)用PHP就會(huì)跳出了一個(gè)Strict錯(cuò)誤。

而調(diào)用Model::where的時(shí)候,由于where沒有在Model里面定義,PHP會(huì)找Model里面的__callStatic,將where方法代理到目標(biāo)類里面。

Model的__callStatic方法注釋也解釋的很清楚

/**
 * Handle dynamic static method calls into the method.
 *
 * @param  string  $method
 * @param  array  $parameters
 * @return mixed
 */
public static function __callStatic($method, $parameters)
{
    $instance = new static;

    return call_user_func_array([$instance, $method], $parameters);
}
2018年5月2日 21:45
編輯回答
莫小染

因?yàn)?code>getTable 不是靜態(tài)的方法
public function getTable()
所以報(bào)

Non-static method Illuminate\Database\Eloquent\Model::getTable() should not be called statically, assuming $this from incompatible context

又因?yàn)椋琾hp 在檢查類的方法存不存在時(shí)不會(huì)考慮是否靜態(tài)類.所以又不會(huì)進(jìn)__callStatic.

又看了一下,你的問題是為什么可以用 model::where ? 可以用modle::where的原因是 model類里沒有一個(gè) where的方法所以進(jìn)了 __callStatic. 請(qǐng)用getTable時(shí)modle里有這個(gè)類。所以進(jìn)不了__callStatic.

回頭去看了一下鳥個(gè)說的那個(gè)文章, 下面是文章的例子。https://segmentfault.com/q/10...

<?php

class A
{
    public function __call($name, $args)
    {
        echo "NO\n";
    }

    public static function __callStatic($name, $args)
    {
        echo "YES\n";
    }
}

class B extends A
{
    public function test()
    {
        A::test();
    }

    public static function stest()
    {
        A::test();
    }
}

A::test();

$b = new B();
$b->test();

B::stest();

他有三個(gè)輸出

A::test();

$b = new B();
$b->test();

B::stest();

需要看清楚的是第一個(gè)用的是 A::test() .

2018年1月15日 07:49
編輯回答
拮據(jù)

因?yàn)槲覀兌x的 Model 直接繼承于 Eloquent/Model

鳥哥在博客中這樣說

因?yàn)槟阍谝粋€(gè)有 calling scope 的上下文中采用”靜態(tài)的形式”調(diào)用了一個(gè)類的非靜態(tài)方法所致.

我的理解是你在一個(gè)定義了 __callStatic 的類中(如 User)調(diào)用非靜態(tài)方法 User::getTable

where 等方法是在 Builder 類中的,Eloquent/Model 不直接繼承 Builder

2017年10月18日 11:27
編輯回答
初念

在Model中,where方法是不存在的,而getTable方法卻是存在的。之所以這么說,是php因?yàn)榧嫒菪缘目紤],在檢查方法是否存在的時(shí)候,并不會(huì)去檢查是不是靜態(tài)方法,只要方法存在,不管是靜態(tài)還是非靜態(tài),都認(rèn)為是方法存在的,因此就不會(huì)調(diào)用__callStatic方法了。

這也就造成了調(diào)用Model::where的時(shí)候,由于where方法是在Illuminate\Database\Eloquent\Builder中定義的,__call將該方法的調(diào)用代理到了Builder上,因此可以調(diào)用。而getTable方法,則因?yàn)槭?code>Model中的實(shí)例方法,做方法存在性判斷的時(shí)候發(fā)現(xiàn)方法有了,就不會(huì)去調(diào)用__callStatic,直接對(duì)該方法進(jìn)行靜態(tài)調(diào)用,所有就拋出了

Non-static method IlluminateDatabaseEloquentModel::getTable() should not be called statically, assuming $this from incompatible context

2017年6月23日 05:40