Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Laravelコアファイルのコードリーディング/Reading the core code of Laravel

y_sone
December 21, 2022

Laravelコアファイルのコードリーディング/Reading the core code of Laravel

Laravelコアファイルのコードリーディングのまとめです。
DB接続についてModel::all()からnew PDO()までコードを追ってみました。
2022年12月21日「PHP勉強会」にて初登壇。

y_sone

December 21, 2022
Tweet

More Decks by y_sone

Other Decks in Programming

Transcript

  1. Laravelコアファイルの
    コードリーディング
    Model::all()からnew PDO()まで追ってみた
    Presented by y_sone
    @20221221_PHP勉強会

    View full-size slide

  2. 自己紹介
    y_sone
    ● エンジニア5年目
    ● たまにイベントのスタッフをやってます
    ● @yukinofu815

    View full-size slide

  3. 今日話すこと
    ● なぜコアファイルを読もうと思ったか
    ● Model::all()からnew PDO()まで追ってみた
    ● コアファイルを読むメリット

    View full-size slide

  4. なぜコアファイルを読もうと思ったか
    ● 好奇心
    ● 仕事ではコアファイルの奥底まで読むことがないから
    ● コードリーディングの練習

    View full-size slide

  5. Model::all()からnew PDO()まで追ってみた
    ● PHPのDB接続といえばnew PDO()
    ● new PDO()はどこ?

    View full-size slide

  6. DB接続に関連するクラス一覧

    View full-size slide

  7. new PDO()はここで実行されている

    View full-size slide

  8. Model::all()から追ってみよう

    View full-size slide

  9. ※ 注意(説明上の呼び方)
    EloquentBuilder
    QueryBuilder

    View full-size slide

  10. 呼び出し元のArticleController.phpのindex()
    // app/Http/Controllers/ArticleController.php
    class ArticleController extends Controller
    {
    public function index(Request $request)
    {
    $articles = Article::all();
    return view('article.index', compact('articles'));
    }
    }

    View full-size slide

  11. Article.phpの親クラスModel.phpのall()
    // vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php
    public static function all($columns = ['*'])
    {
    return static::query()->get(
    is_array($columns) ? $columns : func_get_args()
    );
    }

    View full-size slide

  12. query()でやること
    ● Connectionインスタンスの取得
    ○ Connectionインスタンスはindex.php実行時にKernelのhandle()で生成済み
    ○ シングルトンで生成される
    ● Builderインスタンスの生成
    ○ ConnectionインスタンスからQueryBuilderインスタンスを生成
    ○ QueryBuilderインスタンスからEloquentBuilderインスタンスを生成

    View full-size slide

  13. get()でやること
    ● SQLの実行
    ● SQLの結果をModelのCollectionとして取得
    ● このget()はEloquentBuilderのメソッド
    ● このget()の中でQueryBuilderのget()も呼ばれる

    View full-size slide

  14. get()でやること(EloquentBuilder編)
    ● EloquentBuilderはQueryBuilderのインスタンスを保有している
    ● QueryBuilderのget()を実行
    ● QueryBuilderのget()で取得したデータをModelのCollectionに変換

    View full-size slide

  15. get()でやること(EloquentBuilder編)
    // vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php
    public function get($columns = ['*'])
    {
    $builder = $this->applyScopes();
    if (count($models = $builder->getModels($columns)) > 0) {
    $models = $builder->eagerLoadRelations($models);
    }
    return $builder->getModel()->newCollection($models);
    }

    View full-size slide

  16. get()でやること(EloquentBuilder編)
    // vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php
    public function getModels($columns = ['*'])
    {
    return $this->model->hydrate(
    $this->query->get($columns)->all()
    )->all();
    }

    View full-size slide

  17. get()でやること(QueryBuilder編)
    ● PDOの生成
    ● PDOを利用したSQLの実行

    View full-size slide

  18. get()でやること(QueryBuilder編)
    // vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php
    public function get($columns = ['*'])
    {
    return collect($this->onceWithColumns(Arr::wrap($columns), function () {
    return $this->processor->processSelect($this, $this->runSelect());
    }));
    }

    View full-size slide

  19. get()でやること(QueryBuilder編)
    一部のメソッドです。名前から役割が想像しやすいです。
    1. QueryBuilder::runSelect()
    2. Connection::select()
    3. Connection::run()
    4. Connection::getPdo()
    5. ConnectionFactory::createConnector()
    6. Connector::createPdoConnection()

    View full-size slide

  20. new PDO()を発見!
    // vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php
    protected function createPdoConnection($dsn, $username, $password, $options)
    {
    if (class_exists(PDOConnection::class) && ! $this->isPersistentConnection($options)) {
    return new PDOConnection($dsn, $username, $password, $options);
    }
    return new PDO($dsn, $username, $password, $options);
    }

    View full-size slide

  21. フレームワークはPHPメソッドの集合体
    公式ドキュメントのメソッドをコアファイルで見つけるとフレーム
    ワークが身近になった気がします!

    View full-size slide

  22. コアファイルを読むメリット
    ● フレームワークのありがたみが分かる
    ● 生のコードがフレームワーク内でどのように使われているか知ることできる
    ● フレームワークの設計思想を味わえる
    ● バグなどの原因究明がし易くなる

    View full-size slide

  23. ご清聴ありがとうございました!

    View full-size slide