当从子内部调用时,雄辩的方法使用子类而不是父类

时间:2018-05-14 11:32:55

标签: laravel laravel-5.6

我想我可能已经找到了一个代码的怪癖,它允许静态调用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]);
    }

}

雄辩模型 - >通过 FormSubmission 扩展 - >由 EmployeeFormSubmission

扩展

问题......

我无法理解的奇怪行为是,如果我在whereIn()FormSubmission上调用EmployeeFormSubmission方法,就像上面的getTest()示例中那样,生成的集合将会包含EmployeeFormSubmission的实例,即使我在whereIn()模型上明确调用FormSubmission方法。

如果我使用parent::whereIn()

,行为是一样的

但是,如果我将FormSubmission::getFormSubmissions()方法更改为公共静态,它将按预期工作并返回FormSubmission实例的集合。

就像在FormSubmission上的非静态方法中,Laravel / PHP将“FormSubmission ::”替换为“self ::”。

当非静态时,它会继续执行代码的上下文,并在该类的实例中初始化项目。但是当静态时,它会尊重代码行中引用的模型名称。

请帮助我有点难过。

1 个答案:

答案 0 :(得分:1)

原因是调用未定义的静态方法(如FormSubmission::whereIn())不会由__callStatic()处理,而是由__call()PHP is handling incorrectly my static call)处理。

这有效:

return FormSubmission::query()->whereIn('id', $formSubmissionIds)->get();