Красноречивые методы используют дочерний класс вместо родительского при вызове из дочернего класса - PullRequest
0 голосов
/ 14 мая 2018

Думаю, я мог найти причуду кода, которая позволяет статически вызывать методы модели Laravel Eloquent, но может помочь с некоторой помощью.

У меня есть модель под названием FormSubmission, которая расширяет Eloquent\Model.

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;

class FormSubmission extends Model 
{

    /**
     * Should always return a Collection of FormSubmissions
     *
     * @param $formSubmissionIds
     *
     * @return Collection
     */
    protected function getFormSubmissions(array $formSubmissionIds) : Collection
    {
        return FormSubmission::whereIn('id', $formSubmissionIds)->get();
    }

}

Мне нужно было место для логики, уникальной только для 1 типа FormSubmission. Поскольку это не относится ко всем формам, я не хотел загрязнять модель FormSubmission, поэтому я сделал EmployeeFormSubmission, который расширяет FormSubmission.

namespace App;

class EmployeeFormSubmission extends FormSubmission 
{

    /**
     * 
     */
    public function getTest()
    {
        $employeeFormSubmission = new EmployeeFormSubmission();

        // The resulting Collection will contain instances 
        // of EmployeeFormSubmission (not FormSubmission).
        return $employeeFormSubmission->getFormSubmissions([86]);
    }

}

Eloquent Модель -> расширенная FormSubmission -> расширенная EmployeeFormSubmission

Проблема ...

Странное поведение, которое мне трудно понять, заключается в том, что если я вызову метод whereIn() для FormSubmission из EmployeeFormSubmission, как в примере getTest () выше, результирующая коллекция будет содержать экземпляры EmployeeFormSubmission , хотя я явно вызываю метод whereIn() на модели FormSubmission.

Поведение такое же, если я использую parent::whereIn()

Однако, если я изменю FormSubmission::getFormSubmissions() метод на открытый статический, он будет работать как положено и вернет коллекцию экземпляров FormSubmission.

Как будто Laravel / PHP заменяет "FormSubmission ::" на "self ::", когда он находится внутри нестатического метода на FormSubmission.

Когда он не статичен, он удерживается в контексте, в котором выполняется код, и инициализирует элементы как экземпляры этого класса. Но когда он статичен, он учитывает имя модели, на которое есть ссылка в строке кода.

Пожалуйста, помогите, я немного озадачен.

1 Ответ

0 голосов
/ 14 мая 2018

Причина в том, что вызовы неопределенных статических методов, таких как FormSubmission::whereIn(), обрабатываются не __callStatic(), а __call() ( PHP неправильно обрабатывает мой статический вызов ).

Это работает:

return FormSubmission::query()->whereIn('id', $formSubmissionIds)->get();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...