4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

HTTPのやりとりに使うデータを扱う、 "HttpFoundation"

Last updated at Posted at 2022-11-30

Symfony Component Advent Calendar 2022の1日目の記事です。

最初に

SymfonyはPHPのフレームワークのひとつです。しかし、公式サイトの説明文には

Symfony is a set of PHP Components, a Web Application framework, a Philosophy, and a Community — all working together in harmony.
(SymfonyはPHPコンポーネントのセットで、Webアプリケーションフレームワークで、哲学、そしてコミュニティです。それらがハーモニーを奏でながら動作しています。)

と書かれている通り、PHPコンポーネントのセットで、たくさんのコンポーネントを提供しており、それらを組み合わせてひとつのフレームワークとして動作しています。Symfonyのコンポーネントは、Symfony上だけで動作するのではなく、他のPHPフレームワークやアプリケーションでも動作している強力なものが揃っています。

今回はそれらの中から、役立ちそうなもの・お薦めしたいものを紹介していきたいと思います。

※記事内ではautoloadのインポートは省略します。

HTTPのやりとりに使うデータを扱う、 "HttpFoundation"

HttpFoundationは、HTTPで扱うデータをオブジェクトとして扱うことができるようになるコンポーネントです。Symfony以外のフレームワークやアプリケーションでも動作します。Symfonyではフレームワークインストール時に初期インストールされているコンポーネントです。

インストール

composer require symfony/http-foundation

リクエスト

PHPでは$_GET, $_POST, $_COOKIE など、標準のリクエスト用の変数が用意されています。それらをHttpFoundationではオブジェクトとして扱えるようにします。


use Symfony\Component\HttpFoundation\Request;

$request = Request::createFromGlobals();

$request->query->get('hoge'); // $_GET['hoge']にアクセス

$request->request->get('hoge'); // $_POST['hoge']にアクセス

$request->cookies->get('hoge'); // $_COOKIE['hoge']にアクセス

$request->files->get('hoge'); // $_FILE['hoge']にアクセス

$request->attributes->get('hoge'); // HTTPリクエストではない追加した値にアクセス

$request->server->get('hoge'); // $_SERVER['hoge']にアクセス

$request->headers->get('hoge'); // $_SERVER['hoge']にアクセス

$request->getContent(); // POSTの生データにアクセス

上記のように、リクエストオブジェクトの中にそれぞれ対応したプロパティがあり、それを使ってHTTPリクエストの値にアクセスします。
この中で特殊なのはattributegetContent()です。

attribute

HTTPリクエストにはないけど、一緒に扱うと便利そうなデータを追加するためにあります。

$request = Request::createFromGlobals();
$request->attributes->set('hoge', 'abcde');
echo($request->attributes->get('hoge')); // 'abcde'

また、Symfonyコントローラーで、リクエストを使うとデフォルトで以下の値が追加されています。


class TestController extends AbstractController
{
    #[Route('/test/{id}, name: 'app_test')]
    public function index(Request $request)
    {
        dd($request->attributes);
    }
}
^ Symfony\Component\HttpFoundation\ParameterBag {#13 ▼
  #parameters: array:5 [▼
    "_route" => "app_test" // ルーティング名
    "_controller" => "App\Controller\TestController::index" // 呼び出したコントローラー::アクション
    "id" => "1" // ルーティングでパスに設定したパラメータ属性の値(/test/1でアクセスした場合、"1")
    "_route_params" => array:1 [▼ //  ルーティングでパスに設定したパラメータ属性の値の配列
      "id" => "1"
    ]
  ]
}

getContent()

getContent() は、POSTされた生データを扱います。XMLやJSONなどの生データを使う必要があるときに便利です。さらにJSONの場合はtoArray()を使うと配列にしたJSONデータを受け取ることができます。

$rawData = $request->getContent(); // 生データ
$data = $request->toArray(); // JSONが連想配列になったデータ

レスポンス

レスポンスも、ヘッダーやコンテンツなどをオブジェクトとして扱えます。

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Cookie;

$response = new Response(
    'コンテンツ',
    Response::HTTP_OK, // 200
    ['Content-Type' => 'text/html']
);

$response->headers->get('Content-Type'); // ヘッダーのContent-Typeにアクセス
$response->headers->set('Content-Type', 'text/html');// ヘッダーのContent-Typeを設定

$response->getContent(); // コンテンツにアクセス
$response->setContent('コンテンツ'); // コンテンツを設定

$response->getStatusCode(); // ステータスコードにアクセス
$response->setStatusCode(200); // ステータスコード設定

$response->headers->getCookie('hoge'); // クッキー hoge にアクセス
$response->headers->setCookie(Cookie::create('hoge', 'foo')); // クッキー hoge を設定

$response->send(); // レスポンスを出力

send()は内部でecho() などの出力処理をしてたりするので、send()を呼ぶだけで出力されます。
また、レスポンスはそれぞれの出力形式によって便利なクラスが用意されています。

リダイレクト

リダイレクト用にRedirectResponseが用意されています。

use Symfony\Component\HttpFoundation\RedirectResponse;

$response = new RedirectResponse('http://qiita.com');

ストリーミング

ストリーミング出力もあります。setCallback() 内で出力処理は書く必要があります。

use Symfony\Component\HttpFoundation\StreamedResponse;

$response = new StreamedResponse();
$response->setCallback(function() {
    for (i = 0; i < 10; i ++) {
        echo("${i}<br>");
        flush();
    }
});
$response->send();

ファイル

ファイル出力の場合、環境内のファイルを出力する場合はBinaryFileResponse, 動的に作った値を出力する場合はResponseを使います。

use Symfony\Component\HttpFoundation\BinaryFileResponse;

$file = 'public/images/image.png';
$response = new BinaryFileResponse($file);

$response->send();
use Symfony\Component\HttpFoundation\HeaderUtils;
use Symfony\Component\HttpFoundation\Response;

$csv = "a,b,c\nd,e,f\n";
$response = new Response($csv);

$disposition = HeaderUtils::makeDisposition(
    HeaderUtils::DISPOSITION_ATTACHEMENT,
    'result.csv'
);
$response->headers->set('Content-Disposition', $disposition);

$response->send();

JSON

JSONを出力する場合は JsonResponseを使います。APIとか作ったときに便利です。

use Symfony\Component\HttpFoundation\JsonResponse;

$data = [
    'hoge' => 'foo',
    'bar' => [
        1,
        2,
    ],
];

$response = new JsonResponse($data);

$response->send();

まとめ

上記のような感じで、HTTPリクエスト、レスポンスをオブジェクトで扱えるようになります。
素のPHPにこれだけインストールして使うだけでもだいぶ作りやすくなるんじゃないかなと思います。

※2日目からは、もうちょっと記述量減らしてエコでやっていくとおもいます。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?