Переопределить метод Class из trait и вызвать его снова в trait - PullRequest
0 голосов
/ 15 октября 2018

Я пытаюсь переопределить метод (это на самом деле не метод, а несуществующий метод, который вызывает callStatic ()) из класса, использующего черту.Но внутри метода из черты мне нужно иметь возможность вызывать базовый метод из класса.(см. код)

namespace Foundation\Traits;

use Foundation\Cache\ModelCache;

trait Cacheable
{
    public static function find($id, $columns = ['*'])
    {
        if ((bool)config('model.caching')) {
            $model = ModelCache::findOrRequery($id, get_called_class());
            return self::filterFromColumns($model, $columns);
        }
        return self::findWithoutCache($id, $columns);
    }

    public static function findWithoutCache($id, $columns = ['*'])
    {
        return parent::find($id, $columns);
    }

    private static function filterFromColumns($model, $columns)
    {
        if ($columns !== ['*']) {
            return collect($model)->first($columns);
        }
        return $model;
    }
}

Проблема в том, что метод find застрял в бесконечном цикле, потому что он вызывает метод find для признака, а не класса, использующего признак.

Это также не решает проблему:

    public static function findWithoutCache($id, $columns = ['*'])
    {
        return parent::__callStatic('find', [$id, $columns]);
    }

Как мне обойти эту проблему?

1 Ответ

0 голосов
/ 15 октября 2018

Я думаю, что у вас есть что-то еще, черты могут определенно вызывать методы родительского класса, которые переопределяются чертой, точно так же, как вы можете непосредственно в наследующем классе.Вот пример:

<?php
trait MyTrait
{
    public static function find()
    {
        echo 'MyTrait::find'.PHP_EOL;
        self::findWithoutCache();
    }

    public static function findWithoutCache()
    {
        echo 'MyTrait::findWithoutCache'.PHP_EOL;

        parent::find();
    }
}

class MyBaseClass
{
    public static function find()
    {
        echo 'MyBaseClass::find'.PHP_EOL;
    }
}

class MyClass extends MyBaseClass
{
    use MyTrait;
}

$myClass = new MyClass();
$myClass::find();

Редактировать:

Исходя из ваших комментариев об этом, происходящих в модели Laravel, вы не можете вызывать метод find статически, у вас должен быть экземпляртвоя модельЕсли вы посмотрите на код в методах __call и __callStatic в классе 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);
}

Статический вызов find для родительского объекта просто вызываетметод в вашей характеристике, но если вы вызовете find для экземпляра вашей модели, будет создан экземпляр Illuminate\Database\Eloquent, будет вызван его метод find, и результаты будут возвращены.

Суть в том, что Eloquent, похоже, не создан для статической работы так, как вы этого хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...