Как и почему этот код работает?

Мой вопрос основан на Просмотр данных с помощью Laravel 5.3 и Vue.js

Этот чувак создает признак DataViewer и кодирует его следующим образом:

trait DataViewer
{
// $query should be a Query Builder
public function scopePaginateAndOrder($query)
{
// Validation ...

// Where, Pagination, Order etc ...
return $query->where('foo', 'like', 'bar');
}
}

Теперь вы можете использовать эту черту в любой модели Eloquent для добавления функций поиска.

class Customer extends Model
{
use DataViewer;
}

Все обычные вещи, ничего особенного …
но есть некоторая «магия», которую я еще не видел в PHP.

В контроллере он делает что-то вроде

$model = App\Customer::paginateAndOrder();

Последний фрагмент кода имеет много аспектов, которые я не могу понять.

  1. Почему я могу вызывать этот нестатический метод статическим способом, используя ::?
  2. Почему я могу опустить объем из названия метода?
  3. Мне не нужно передавать объект Query Builder в качестве параметра. Так как же черта «узнает», какую модель я хочу разбить на страницы / заказать?

Спасибо за вашу помощь, ребята!

0

Решение

Laravel хорошо использует несколько магических методов PHP, особенно в этом случае __call() а также __callStatic,

http://php.net/manual/en/language.oop5.overloading.php#object.callstatic

С callStaticЕсли вызывается статический метод, который либо не существует, либо недоступен, то вызов будет делегирован __callStatic() метод в этом классе (если таковой существует). То же самое справедливо __call() и методы экземпляра.

Если вы посмотрите в Illuminate\Database\Eloquent\Model ты найдешь:

/**
* Handle dynamic method calls into the model.
*
* @param  string  $method
* @param  array  $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
if (in_array($method, ['increment', 'decrement'])) {
return call_user_func_array([$this, $method], $parameters);
}

$query = $this->newQuery();

return call_user_func_array([$query, $method], $parameters);
}

/**
* 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);
}

В приведенном выше, если __callStatic вызывается, то это создаст new экземпляр модели и попробуйте вызвать метод для этого экземпляра, поэтому при вызове App\Customer::paginateAndOrder() тогда он попытается позвонить paginateAndOrder() как метод экземпляра.

(Не включено increment а также decrement) __call() метод на модели затем попытается вызвать этот метод на Illuminate\Database\Eloquent\Builder, Builder тогда есть свой __call() метод, который имеет следующее:

if (method_exists($this->model, $scope = 'scope' . ucfirst($method))) {
return $this->callScope([$this->model, $scope], $parameters);
}

callScope тогда просто позвоните фактическому scopePaginateAndOrder и передает Builder через.

Надеюсь это поможет!

1

Другие решения

Это магия Laravel .. вообще не php.

Laravel использует то, что известно с магические функции

  1. Почему я могу вызывать этот нестатический метод статическим методом, используя ::?

Я перечислю только два здесь __call() а также __callStatic()эти функции вызываются, когда вы вызываете несуществующие нестатические статические функции соответственно ..

Так в Illuminate\Database\Eloquent\Model который является суперклассом для всех моделей, проверьте это ссылка на сайт.

  1. Почему я могу опустить область из имени метода?

Просто Laravel позволяет вам пропустить префиксы имен функций, которые представляют то, что он делает. например. scope префикс в вашем случае .. И продолжает добавлять префиксы в определенном порядке, пока не найдет его.
Прочитайте код если вы хотите поближе.

  1. Мне не нужно передавать объект Query Builder в качестве параметра. Так как же черта «узнает», какую модель я хочу разбить на страницы / заказать?

Я считаю, что это связано с контейнером Laravel IoC и инъекцией зависимости.

Примечание: Q3 нуждается в дополнительном исследовании, чтобы быть уверенным, когда & как делается инъекция

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector