クソ雑魚のワイ、symfonyのコードリーディングしてみた①

自分は25卒の学生です。
この時期に内定がまだなく、流石に焦っています。

__「この時期に内定ないのヤバいって。危機感持て。」__
とあるメンズコーチの言葉が脳裏をよぎります。

これまで就職活動に力を入れ、技術勉強は中断していました。
ですが就職活動の時間を振り返り、このように思いました。

__時間の無駄だったな。__

ということで、何かしらの技術勉強も並行しようと思い、コードリーディングに挑みます。
クソ雑魚エンジニア、いや、エンジニアですらない僕ですが、アウトプットを目的として記事を書きます。

優しい目で見守ってください。

## Symfonyとは

READMEには以下のように書いてあります。

<dl>
    <dt>英語</dt>
    <dd>Symfony is a PHP framework for web and console applications and a set of reusable PHP components. Symfony is used by thousands of web applications and most of the popular PHP projects.
    </dd>
    <dt>和訳</dt>
    <dd>ウェブアプリケーションとコンソールアプリケーションのためのPHPフレームワークであり、一連の再利用可能なPHPコンポーネントです。Symfonyは、何千ものウェブアプリケーションや、多くの人気のPHPプロジェクトで使用されています。</dd>
</dl>


どうやらPHPフレームワークの根幹をなしているようです。
普段からLaravelを使用しており、Symfonyの名前には馴染みがありました。

__Laravelは、Symfonyにあるコンポーネントを活用しているようです。__

## ソースコードを読んでみよう

正直どこから読み始めれば良いのか、分かりません！
コンポーネントという言葉からヒントを得て、 "./src/Symfony/Component" から読み始めてみます。

代表的なコンポーネントには、以下の役割があるようです。
※ChatGPTに聞きました。間違いがありましたら、すみません。

<dl>
    <dt>Component\Routing</dt>
    <dd>ルーティング機能を提供し、HTTPリクエストを適切なコントローラーにマッピングします。</dd>
    <dt>Component\HttpFoundation</dt>
    <dd>HTTPリクエストとレスポンスの処理を行うためのクラスを提供します。リクエストの取得、レスポンスの送信、セッション管理などをサポートします。</dd>
    <dt>Component\Validator</dt>
    <dd>データのバリデーションを行うためのコンポーネントです。フォームデータやビジネスロジックの検証に使用します。</dd>
    <dt>Component\Form</dt>
    <dd>フォームの作成、バリデーション、データバインディングを簡単にするためのコンポーネントです。ユーザー入力の処理を効率的に行います。</dd>
    <dt>Component\Security</dt>
    <dd>アプリケーションのセキュリティ機能を提供します。ユーザー認証、認可、セキュリティの設定などが可能です。</dd>
    <dt>Component\DependencyInjection</dt>
    <dd>依存性注入（DI）をサポートし、オブジェクトの依存関係を管理するためのコンポーネントです。これにより、コードのモジュール性とテスト性が向上します。
</dd>
    <dt>Component\Twig</dt>
    <dd>Twigテンプレートエンジンを使用して、ビューのレンダリングを行います。強力で柔軟なテンプレートシステムを提供します。</dd>
</dl>

なんとなくで僕は "./src/Symfony/Component/HttpFoundation"を読み進めていこうと思います。

## Symfony/Component/HttpFoundation

まずはSymfony/Component/HttpFoundation/Request.phpについて少し
```
public function __construct(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null)
{
    $this->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
}
```
自分はクソ雑魚なのであまり偉そうなことは言えませんが、クラスで初期化したプロパティをコンストラクタで宣言し直す処理を関数を用いて行っています。そこまで大したことのないものであれば、通常は1つ1つのプロパティを宣言し直す処理を書くでしょう。

このRequestクラスでは多くのプロパティが宣言されているのですが、私はクソ雑魚なので以下のことについて復習させてください。

| アクセス権|許容範囲|
|:-:|:-:|
|public|どこからでもアクセス可能|
|protected|そのクラス自身と継承クラスからアクセス可能|
|private|そのクラス自身からのみアクセス可能|

```
public static function createFromGlobals(): static
{
    $request = self::createRequestFromFactory($_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER);

    if (str_starts_with($request->headers->get('CONTENT_TYPE', ''), 'application/x-www-form-urlencoded')
            && \in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), ['PUT', 'DELETE', 'PATCH'], true)
        ) {
            parse_str($request->getContent(), $data);
            $request->request = new InputBag($data);
        }

    return $request;
}
```
次にこちらの関数です。
まずは返り値にstaticを型づけしています。このRequestクラスのインスタンスが返されるというわけですね。
そしてこちらの関数内で処理している内容を言語化すると以下の文脈になると思います。

:::note
　まずは自クラス内の静的メソッドを呼び出し、要求されているHTTPメソッドやcookie、ファイル、サーバなどを元にRequestインスタンスを作成します。
　その後、HTTPヘッダのContent-Typeに問題がなく、またHTTPメソッドがPUT,DELETE、PATCHのいずれかであれば、Requestインスタンスに渡されてきたデータなどを追加するみたいです。
:::

以下のコードは、Laravelを利用されている方には馴染みがあると思います。
```
Request::all()
Request::get()
```
これらのメソッドはインスタンス化されているInputBagクラス、またその親クラスに宣言されているメソッドでした。

Requestインスタンスのall,getメソッドを呼び出すと、InputBagクラスのall,getメソッドを呼び出すという仕組みになっているようです。

## とりあえずまとめ
少し疲れたので、ここで区切ります。
細かい挙動を全て把握することはできませんが、ソースコードを読んでいくと、オブジェクトの考え方や仕組みを少しづつ理解できている感覚はあります。

これをインプットしたままではきっとダメなのでしょう。
エンジニアたるもの、アウトプット至上主義でなければいけません。

やったるで。

まだまだソースコードの紹介は続けていきます！