解决使用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();
    }
相关推荐
郑州光合科技余经理1 小时前
出海外卖平台:支付对接为什么要和下单收款分开
android·java·开发语言·前端·后端·php·ai编程
谢亮_vipxieliang1 小时前
PHP 异常处理全解析:try-catch、自定义异常与全局异常处理器
开发语言·php
JaguarJack2 小时前
免费可商用 PHP 管理后台 CatchAdmin V5.4.1 发布,新增 MCP 支持
后端·php·laravel·服务端
BingoGo2 小时前
免费可商用 PHP 管理后台 CatchAdmin V5.4.1 发布,新增 MCP 支持
后端·php
谢亮_vipxieliang2 小时前
多智能体系统的“TCP/IP时刻”:MCP与A2A协议如何定义Agent时代
网络·tcp/ip·ai·php
cleble2 小时前
怎么用用 PowerShell 下载文件
开发语言·php
北京盛世宏博13 小时前
工业环境监测选型:Modbus TCP以太网温湿度传感器部署、调试、避坑全指南
开发语言·网络·php
4SAPI13 小时前
AI API Gateway平台哪个好?从架构视角看企业多模型网关选型与实践
java·大数据·人工智能·gateway·php
ly768914 小时前
MongoDB 副本集选举风暴排查:从心跳超时到 Journal 刷盘阻塞
数据库·mongodb·php·mongodb 副本集·选举风暴·journal 刷盘·writeconcern
源图客14 小时前
浏览器开发者工具使用
开发语言·php