Laravelコアファイルのコードリーディングのまとめです。 DB接続についてModel::all()からnew PDO()までコードを追ってみました。 2022年12月21日「PHP勉強会」にて初登壇。
LaravelコアファイルのコードリーディングModel::all()からnew PDO()まで追ってみたPresented by y_sone@20221221_PHP勉強会
View Slide
自己紹介y_sone● エンジニア5年目● たまにイベントのスタッフをやってます● @yukinofu815
今日話すこと● なぜコアファイルを読もうと思ったか● Model::all()からnew PDO()まで追ってみた● コアファイルを読むメリット
なぜコアファイルを読もうと思ったか● 好奇心● 仕事ではコアファイルの奥底まで読むことがないから● コードリーディングの練習
Model::all()からnew PDO()まで追ってみた● PHPのDB接続といえばnew PDO()● new PDO()はどこ?
DB接続に関連するクラス一覧
new PDO()はここで実行されている
Model::all()から追ってみよう
※ 注意(説明上の呼び方)EloquentBuilderQueryBuilder
呼び出し元のArticleController.phpのindex()// app/Http/Controllers/ArticleController.phpclass ArticleController extends Controller{public function index(Request $request){$articles = Article::all();return view('article.index', compact('articles'));}}
Article.phpの親クラスModel.phpのall()// vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.phppublic static function all($columns = ['*']){return static::query()->get(is_array($columns) ? $columns : func_get_args());}
query()でやること● Connectionインスタンスの取得○ Connectionインスタンスはindex.php実行時にKernelのhandle()で生成済み○ シングルトンで生成される● Builderインスタンスの生成○ ConnectionインスタンスからQueryBuilderインスタンスを生成○ QueryBuilderインスタンスからEloquentBuilderインスタンスを生成
get()でやること● SQLの実行● SQLの結果をModelのCollectionとして取得● このget()はEloquentBuilderのメソッド● このget()の中でQueryBuilderのget()も呼ばれる
get()でやること(EloquentBuilder編)● EloquentBuilderはQueryBuilderのインスタンスを保有している● QueryBuilderのget()を実行● QueryBuilderのget()で取得したデータをModelのCollectionに変換
get()でやること(EloquentBuilder編)// vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.phppublic function get($columns = ['*']){$builder = $this->applyScopes();if (count($models = $builder->getModels($columns)) > 0) {$models = $builder->eagerLoadRelations($models);}return $builder->getModel()->newCollection($models);}
get()でやること(EloquentBuilder編)// vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.phppublic function getModels($columns = ['*']){return $this->model->hydrate($this->query->get($columns)->all())->all();}
get()でやること(QueryBuilder編)● PDOの生成● PDOを利用したSQLの実行
get()でやること(QueryBuilder編)// vendor/laravel/framework/src/Illuminate/Database/Query/Builder.phppublic function get($columns = ['*']){return collect($this->onceWithColumns(Arr::wrap($columns), function () {return $this->processor->processSelect($this, $this->runSelect());}));}
get()でやること(QueryBuilder編)一部のメソッドです。名前から役割が想像しやすいです。1. QueryBuilder::runSelect()2. Connection::select()3. Connection::run()4. Connection::getPdo()5. ConnectionFactory::createConnector()6. Connector::createPdoConnection()
new PDO()を発見!// vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.phpprotected 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);}
フレームワークはPHPメソッドの集合体公式ドキュメントのメソッドをコアファイルで見つけるとフレームワークが身近になった気がします!
コアファイルを読むメリット● フレームワークのありがたみが分かる● 生のコードがフレームワーク内でどのように使われているか知ることできる● フレームワークの設計思想を味わえる● バグなどの原因究明がし易くなる
ご清聴ありがとうございました!