Laravel-ide-helper 是否破坏了 Laravel 本身的特性

作为 PhpStorm 的忠实用户,使用 Laravel 的时候也是在使用 PhpStrom 来进行开发。然而我却发现了一些令我不解的问题。

Laravel 本身的依赖注入,服务提供者等特性使得 IDE 很难做到代码检查和智能提示,我理所当然地使用了 laravel-ide-helper,然而有些地方还是不能提示。

就拿一个 create_table 的文件来说。

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('users');
    }
}

这是 Laravel 自己生成的代码,然后我在 IDE 中发现 Schema 这个类还是没有实现智能提示,而且还有一个 method not found 的警告。
网上搜索之后发现,需要使用 \Schema 这个命名空间,而不是 Illuminate\Support\Facades\Schema 这个命名空间。这就很尴尬了,原本好好的命名空间机制,直接就回到了原始全是根命名空间的时代。
当然这也仅仅是一个例子,事实上还有很多类似的例子,需要使用根命名空间才能进行代码提示。

那么问题来了,laravel-ide-helper 这样的库,是否破坏了 Laravel 本身的特性(命名空间细化)。如果造成了破坏,如何能够优雅地解决这个矛盾,在不破坏 Laravel 本身特性的前提下,能够使用 IDE 进行代码提示,提高生产效率?

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 7
leo

之前给作者提交了一个PR来解决这个问题,然而并没有被接受 :sleepy:

8年前 评论

个人认为 ide-helper 之类的工具,目标应该是更少的代码侵入性。
如果为了使用这个工具,而去大量修改我们本身的源代码,就得不偿失了。

8年前 评论

我记得 Facades 是不用写命名空间的吧,不用 use Illuminate\Support\Facades\Schema; 或者是直接 use Schema;这样就行。

laravel-ide-helper 实现可以对 Facades 代码提示的处理方式是在根文件生成一个 _ide_helper.php 的文件,这个文件就包含了所有的 Facades ,比如 Schema的:

class Schema extends \Illuminate\Support\Facades\Schema{
    public static function create($table, $callback){
            //Method inherited from \Illuminate\Database\Schema\Builder            
            return \Illuminate\Database\Schema\MySqlBuilder::create($table, $callback);
        }
}

这个文件是在顶级命名空间的,并且只会被 ide 加载,所以如果使用 Facades 按照 use Schema; 这种写法的话,在 ide 中会当作是 _ide_helper.php 里面定义的类,并且有相应的方法,不会导致有问题,而在实际运行的时候,由于不会加载 _ide_helper.php 这个文件,所以还是用的 Illuminate\Support\Facades\Schema 这一个。

应该是这样吧。。。。

8年前 评论

你说的什么侵入性有点严重了。这个 ide helper 并不影响你的代码,只不过在 phpstorm 构建索引的时候会把这个文件加进去,其实就是 app.php 下面的 aliases 所有对应的类的别名都给找出说有的静态方法并做对应的映射。而你说的 Schema 其实在这个 aliases 也能找到,已经将 Illuminate\Support\Facades\Schema 别名为了 Schema,也就是说 Schema 作为了全局的类了。

我想你用的应该是 5.3 版本生成的迁移文件吧,其实可以直接把迁移文件的 use Illuminate\Support\Facades\Schema; 直接删除了。:swimmer:

8年前 评论

对的,是我的问题。
因为我对 Laravel 还不够熟悉,所以不知道 Schema 在根命名空间也有。
这样的话 laravel-ide-helper 就没有什么副作用了。
@zhuzhichao @oustn

8年前 评论

@XhinLiang 看看 config/app里面的aliases数组,是在程序启动的时候才注册的,之所以现在很多人用 facade 都会写完整的命名空间,估计也是因为 phpstorm 的 ‘功劳’ 了,因为他的自动导入会导入完整的类名。没有用laravel-ide-helper的情况下 phpstorm 是没办法直接导入根命名空间的facade 的。之前用sublime的时候为了少写点代码,所以每次直接用 use Schema这种写法。。。

8年前 评论

:sun_with_face: sdfas :100:

8年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!