解决使用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();
    }
相关推荐
TlSfoward10 小时前
抓包代理链路下的 TLS 指纹变化分析 TLSFOWARD抓包工具
数据库·爬虫·网络协议·搜索引擎·php
—Miss. Z—13 小时前
计算机二级MySQL——简单应用题(存储过程&存储函数)
数据库·oracle·php
故乡de云14 小时前
AWS 添加付款方式失败排查清单:卡片、银行风控与账号状态逐项定位
开发语言·php
梦梦代码精15 小时前
基于ThinkPHP6 + Vue3的家政预约系统全解析:从LBS定位到自动派单的完整实现
java·docker·开源·php·代码规范
郑州光合科技余经理15 小时前
家政O2O平台解析:从0搭建上门预约小程序解决方案
android·java·开发语言·前端·小程序·架构·php
lxw184491251417 小时前
PHP后端(CI框架方向)面试题库,分为基础必问、MySQL、Redis、工程运维、高阶加分、场景实操六大模块,适配该JD全部考点,附带标准答案
ci/cd·面试·php
郑州光合科技余经理17 小时前
家政预约小程序后端源码深度剖析:支付回调实战
java·开发语言·前端·git·小程序·架构·php
weixin_408099671 天前
2026 图片去水印 API 接口完全指南:一键去除图片水印(附 Python/Java/PHP/C# 示例)
java·python·php·图片处理·api调用·图片去水印·石榴智能
王莎莎-MinerU2 天前
MCP 解决的是工具接入,科研 Agent 还缺的是科学证据接口标准化
开发语言·网络·人工智能·深度学习·pdf·c#·php
AC赳赳老秦2 天前
OpenClaw 采集任务日志审计:全程记录采集行为,满足合规溯源与企业审计要求
java·大数据·python·数据挖掘·数据分析·php·openclaw