首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Laravel雄辩:关系是如何从查询生成器继承函数的?

Laravel雄辩:关系是如何从查询生成器继承函数的?
EN

Stack Overflow用户
提问于 2021-10-14 02:04:44
回答 1查看 113关注 0票数 0

它们是如何实现的,即Illuminate\Database\Eloquent\Relations\Relation可以访问所有查询生成器函数?

我看到它们有一个$query属性,但是没有解释它的所有方法是如何在关系中可用的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-20 09:25:22

如果您知道php 魔术法,那么当您初始化一个php对象并尝试调用类中不可用的方法时,就会知道这个方法会被调用。通过使用来自类的__call方法,它们将调用转发到Illuminate\Database\Eloquent\Builder。我将通过指出代码来非常清楚地解释它。

在laravel框架中有一个名为ForwardsCalls的特性。这个特性在许多类中被用来处理呼叫转发到另一个类。

下面是如何将来自Relation类的调用转发到Builder类。初始化新的关系类Builder时,类将是已初始化。因此,当您尝试从reltion类调用方法时,它将调用打电话方法。之后,它将寻找一个可用宏。因此,当找不到宏方法时。然后,它将使用forwardDecoratedCallTo来自ForwardsCalls特性。

因此,forwardDecoratedCallTo将接受3个参数,即$object, $method and $parameters。鉴于

  1. $object将是$this->query,它有一个Illuminate\Database\Eloquent\Builder实例。
  2. $method将是您尝试从Builder访问的方法。
  3. $parameters将是传递给该方法的所有参数。

我将试着演示一下will的例子,而不需要laravel的特征和帮助。

代码语言:javascript
运行
复制
class ClassTwo {
  
public function classTwoMethodOne()
    {
      dd(__FUNCTION__.' has been called');
    }  
  
  public function classTwoMethodTwo()
    {
      dd(__FUNCTION__.' has been called');
    }  

  public function classTwoMethodThree()
    {
    //you cannot call this method dynamically 
      dd(__FUNCTION__.' has been called');
    }  

}


class ClassOne {
  
public function classOneMethodOne()
    {
      dd(__FUNCTION__.' has been called');
    }  
  
  public function classOneMethodTwo()
    {
      dd(__FUNCTION__.' has been called');
    }  

  public function __call($methodName, $arguments)
    {
    
    $methodsTobeForwarededtoClassTwo = [
        'classTwoMethodOne',
        'classTwoMethodTwo',
      // 'classTwoMethodThree' 
      //i have commented this method so you cannot access it 
      //from dynamic calls
    ];
    if(in_array($methodName,$methodsTobeForwarededtoClassTwo))
    {
      return (new ClassTwo)->{$methodName}($arguments);
    }
             dd(sprintf(
            'Call to undefined method ClassTwo::%s()',  $methodName
        ));
    }
}

测试部分来了。

代码语言:javascript
运行
复制
$classOneobj = new ClassOne;

基本测试

  1. dump($classOneobj->classOneMethodOne());将以classOneMethodOne被称为的方式输出
  2. dump($classOneobj->classOneMethodTwo());将以classOneMethodTwo被称为的方式输出

动态呼叫测试

  1. dump($classOneobj->classTwoMethodOne());将以classTwoMethodOne被称为的方式输出
  2. dump($classOneobj->classTwoMethodTwo());将以classOneMethodTwo被称为的方式输出
  3. dump($classOneobj->classTwoMethodThree());将作为对未定义方法dump($classOneobj->classTwoMethodThree());调用输出,因为我已经在ClassOne中的__call函数中注释了该方法。

如果你还需要澄清,请发表评论

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69564270

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档