解决使用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();
    }
相关推荐
Blossom.1183 小时前
大模型推理优化实战:连续批处理与PagedAttention性能提升300%
大数据·人工智能·python·神经网络·算法·机器学习·php
编程大师哥5 小时前
Boost C++
java·c++·php
fiveym6 小时前
PXE启动菜单配置完全指南:打造高效网络装机入口
开发语言·网络·php
fiveym7 小时前
PXE装机遇DHCP错误:ICMP echo reply导致IP分配失败原理解析
网络协议·tcp/ip·php
BingoGo9 小时前
使用 PHP 和 WebSocket 构建实时聊天应用:完整指南
后端·php
JaguarJack9 小时前
使用 PHP 和 WebSocket 构建实时聊天应用 完整指南
后端·php
LCG米9 小时前
基于LoRa的远距离低功耗农业传感器网络设计与实现(SX1278+STM32L071)
网络·stm32·php
ai_xiaogui10 小时前
Debian系统PVE虚拟机安装详解:ISO镜像上传+硬件配置+图形化安装指南
运维·debian·php·panelai兼容测试·图形化安装指南·iso镜像上传配置·debian pve虚拟机安装
梦想要有20 小时前
盲盒无限功能分享
php
北里闻箫1 天前
Java spinrg 4.x 及 jsp 简单心得(PHP转JAVA视角)
java·php·jsp