Laravel4でエディタ・IDEで補完されないクラスの対応


[Laravel](http://laravel.com/)ではアプリケーションから使う基本的な機能がFacadeパターンで用意されていて、そのクラスがaliasの設定によって長いnamespaceを意識しなくても使えるようになっている。

こういったaliasを含めてLaravelのautoload機能で解決しているクラスはエディタやIDEから補完が効かないとか、実装の中身を見たいときに実装にジャンプできないとか面倒なことがある。

補完するためのエディタやIDEに読ませるだけのphpファイルを作っておくと良い。

## [Laravel IDE Helper Generator](https://github.com/Barryvdh/laravel-ide-helper) を使う

生成済みファイルがgist[5227822](https://gist.github.com/barryvdh/5227822)に上がっているのでてっとり早くプロジェクトディレクトリで以下を実行して解決する。

Revisionによって内容が変わっているので注意。

### 4.0

```:bash
wget https://gist.github.com/barryvdh/5227822/raw/b58c5d26351acce3f8a5094d6a21c7d2eefc968e/_ide_helper.php
```

### 4.1.8

```:bash
wget https://gist.github.com/barryvdh/5227822/raw/df741117a6d1c36d667f63cb40d409c0e1008f5e/_ide_helper.php
```


##  ボツネタ

Laravel IDE Helper Generatorを教えてもらう前に自力で解決しようとしたネタ。

ただ結局のところFacadeクラスのマジックメソッド__callStaticで動的に解決しているスタティックメソッドや、``Auth``など処理の一部をマジックメソッドでdriverに委譲しているManagerクラスは補完が効かないし、あんまり嬉しくないかも。

```php:Laravel4.php
<?php
class App extends Illuminate\Foundation\Application {}
class Artisan extends Illuminate\Foundation\Artisan {}
class Auth extends Illuminate\Auth\AuthManager {}
class Blade extends Illuminate\View\Compilers\BladeCompiler {}
class Cache extends Illuminate\Cache\CacheManager {}
class ClassLoader extends Illuminate\Support\ClassLoader {}
class Config extends Illuminate\Config\Repository {}
class Controller extends Illuminate\Routing\Controllers\Controller {}
class Cookie extends Illuminate\Cookie\CookieJar {}
class Crypt extends Illuminate\Encryption\Encrypter {}
class DB extends Illuminate\Database\DatabaseManager {}
class Eloquent extends Illuminate\Database\Eloquent\Model {}
class Event extends Illuminate\Events\Dispatcher {}
class File extends Illuminate\Filesystem\Filesystem {}
class Form extends Illuminate\Html\FormBuilder {}
class Hash extends Illuminate\Hashing\BcryptHasher {}
class HTML extends Illuminate\Html\HtmlBuilder {}
class Input extends Illuminate\Http\Request {}
class Lang extends Illuminate\Translation\Translator {}
class Log extends Illuminate\Log\Writer {}
class Mail extends Illuminate\Mail\Mailer {}
class Paginator extends Illuminate\Pagination\Environment {}
class Password extends Illuminate\Auth\Reminders\PasswordBroker {}
class Queue extends Illuminate\Queue\QueueManager {}
class Redirect extends Illuminate\Routing\Redirector {}
class Redis extends Illuminate\Redis\Database {}
class Request extends Illuminate\Http\Request {}
class Response extends Illuminate\Support\Facades\Response {}
class Route extends Illuminate\Routing\Router {}
class Schema extends Illuminate\Database\Schema\MySqlBuilder {}
class Seeder extends Illuminate\Database\Seeder {}
class Session extends Illuminate\Session\Store {}
class Str extends Illuminate\Support\Str {}
class URL extends Illuminate\Routing\UrlGenerator {}
class Validator extends Illuminate\Validation\Factory {}
class View extends Illuminate\View\Environment {}
```

出力するために以下のようなコードを書きました。

```php:
Route::get(
    'classes',
    function () {
        $classDefines = array('<?php','');
        $aliases = Config::get('app.aliases');
        foreach ($aliases as $className => $targetClassName) {
            $parentClassName = $targetClassName;
            if (str_contains($targetClassName, 'Facades')) {
                $f = new $targetClassName();
                if (is_subclass_of($f, 'Illuminate\Support\Facades\Facade')) {
                    $instance = $targetClassName::getFacadeRoot();
                    $parentClassName = get_class($instance);
                }
            }
            $classDefines[] = sprintf('class %s extends %s {}', $className, $parentClassName);
        }
        $response = Response::make(implode(PHP_EOL, $classDefines));
        $response->header('Content-Type', 'text/plain');
        return $response;
    }
);

```