解决使用IDE开发laravel项目无法智能提示eloquent的可调用方法的问题

1.官方推荐使用eloquent的方式

laravel官方文档关于eloquent的使用方式的介绍有两种,一种是静态调用,一种是实例化。但是这两种方式在使用IDE(phpstorm)开发时,都有点不便-IDE不提示可调用的方法。
官方静态调用示例
官方实例化调用示例

2.解决IDE不提示eloquent可调用的方法的问题

要解决这个问题很简单,只需要在使用这两种方式调用链式方法前调用另一个方法就可以了。

用于静态调用的方式

在静态调用其他链式方法前调用`query`方法,之后IDE就能提示其他可调用的链式方法了。
优化静态调用

用于实例化调用的方式

接收实例化Model后再调用`newQuery`方法的返回值,这样IDE就能提示可调用的链式方法了。
优化实例化调用

3.分析原因

现在解释一下为什么用官方文档方式IDE不会提示可调用的链式方法,而经过这样的调整,IDE又行了。

主要因为`\Illuminate\Database\Eloquent\Model`类中的两个魔术方法的作用:`__call`、`__callStatic`。

官方文档的调用方式最后都会由`__call`处理,所以我们只要理解`Model`类的`__call`方法具体做了什么就能理解为什么上面的解决方式有效了。

`Model`类中`__call`的具体代码
php 复制代码
/**
     * 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 $this->$method(...$parameters);
        }

        if ($resolver = (static::$relationResolvers[get_class($this)][$method] ?? null)) {
            return $resolver($this);
        }
       
        return $this->forwardCallTo($this->newQuery(), $method, $parameters);
    }
`forwardCallTo`的具体代码
php 复制代码
/**
     * Forward a method call to the given object.
     *
     * @param  mixed  $object
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     *
     * @throws \BadMethodCallException
     */
    protected function forwardCallTo($object, $method, $parameters)
    {
        try {
            return $object->{$method}(...$parameters);
        } catch (Error|BadMethodCallException $e) {
            $pattern = '~^Call to undefined method (?P<class>[^:]+)::(?P<method>[^\(]+)\(\)$~';

            if (! preg_match($pattern, $e->getMessage(), $matches)) {
                throw $e;
            }

            if ($matches['class'] != get_class($object) ||
                $matches['method'] != $method) {
                throw $e;
            }

            static::throwBadMethodCallException($method);
        }
    }

可以发现关键代码`forwardCallTo `,结合`forwardCallTo`的方法参数可以发现,最终由`**this-\>newQuery()**\`创建的对象,调用链式的方法名。因此可以得出官方文档中的链式调用方法其实都是\`this->newQuery()`方法返回值可调用的方法。

到这里就可以了。如果我们能直接持有`newQuery()`的返回值,那么就能直接调用它的方法了,而不用再经过`__call`了。

很幸运`newQuery()`方法的修饰符是`public`。

刚好`Model`类有一个静态的`query()`方法,这个方法主要代码就是返回`newQuery()`的值,这也解决了静态调用的问题了。

静态`query()`方法的代码
php 复制代码
/**
     * Begin querying the model.
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function query()
    {
        return (new static)->newQuery();
    }
相关推荐
不会摸鱼的小鱼10 小时前
WSL 安装 Ubuntu 22.04 到指定磁盘
数据库·postgresql·php
淼淼爱喝水14 小时前
DVWA和Pikachu命令注入漏洞检测实验
安全·web安全·php·pikachu·dvwa
专注VB编程开发20年15 小时前
json和python元组,列表,字典对比
开发语言·python·json·php
怀旧,15 小时前
【Linux网络编程】15. Reactor 反应堆模式
linux·网络·php
Dylan的码园16 小时前
2026年免费远程控制软件哪个好?ToDesk向日葵UU远程免费版横评,不限次数不限时长
服务器·开发语言·php
dog25016 小时前
解析几何的力量(1)
服务器·开发语言·网络·php
号码认证服务17 小时前
如何让来电显示公司名代替陌生数字号码?企业号码认证开通指南
服务器·c语言·网络·经验分享·智能手机·云计算·php
一念春风17 小时前
QwenPaw(替代小龙虾)大模型
开发语言·php
是有头发的程序猿18 小时前
AI Agent自动化交易流程:1688定制交易API全链路开发实战教程(Python源码)
python·自动化·php
极梦网络无忧19 小时前
# 从零打造 Composer 依赖包:ThinkPHP 项目开发实战指南
php·composer