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

PHP8時代のWebアプリケーションフレームワークの話をしよう

n1215
December 12, 2020

 PHP8時代のWebアプリケーションフレームワークの話をしよう

2020/12/12 PHPカンファレンス2020の登壇資料です

n1215

December 12, 2020
Tweet

More Decks by n1215

Other Decks in Technology

Transcript

  1. ⾃⼰紹介 京都から配信しています - 中榮健⼆ (なかえけんじ) - twitter: @n_1215  - 株式会社Nextat

    取締役 - Laravel/Unityでソーシャルゲーム開発 - → ここ最近はECサイト開発多め。Lambda + AppSync なども Nextat Inc. 2
  2. Webアプリケーション ⼊⼒:HTTPリクエスト POST /path HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded this=is&request=body

    出⼒:HTTPレスポンス HTTP/1.1 200 OK Host: example.com Content-Type: text/plain;charset=UTF-8 X-Powered-By: PHP/8.0.0 This is response body Nextat Inc. 8
  3. PHPでのHTTPメッセージの処理 <?php header('X-Powered-By: NonFramework/0.1'); $name = $_GET["name"] ?? 'World'; echo

    'Hello ' . htmlspecialchars($name, ENT_QUOTES) . '!'; スーパーグローバル( $_GET , $_POST ...)に⼊った値からHTTPリクエストの値が 取れる echoやheader()関数でHTTPレスポンスを組み⽴てる とてもお⼿軽だが…… Nextat Inc. 10
  4. HTTPリクエストハンドラ Webアプリケーションの抽象化 PSR-15の例 interface RequestHandlerInterface { public function handle(ServerRequestInterface $request):

    ResponseInterface; } 利⽤ $request = $requestCreator->createFromGlobal(); $handler = new MyRequestHandler(); $response = $handler->handle($request); Nextat Inc. 19
  5. 馴染み深い例 HTTPリクエストハンドラ ≒ コントローラのアクション class GreetingController { public function hello(ServerRequestInterface

    $request) : ResponseInterface { $name = $request->getAttribute('name', 'world'); return new JsonResponse(['message' => "Hello, {$name}!"]); } } Nextat Inc. 21
  6. 実際はもう少し簡略化されているケースが多い // ルータでパスパラメータが定義される $router->get('/hello/{name}', [GreetingController::class, 'hello']); class GreetingController { public

    function hello(string $name): array { return ['message' => "Hello, {$name}!"]; } } (HTTPリクエスト →) ルートパラメータ → 配列 (→ JSONレスポンス) 暗黙的な変換でリクエストハンドラ相当の処理が導出されている Nextat Inc. 22
  7. match式で⾒る簡易Routerのイメージ function router(ServerRequestInterface $request): Response $path = $request->getUri()->getPath(); $response =

    match ($path) { 'hello' => $helloHandler->handle($request), 'ping' => $pingHandler->handle($request), default => $notFoundHandler->handle($request) } return $response; } Routerで複数のHTTPリクエストハンドラをまとめる Routerを再起的にHTTPリクエストハンドラとして扱うことが可能 Nextat Inc. 24
  8. コードで⾒ると class MyMiddleware implements MiddlewareInterface { public function process( SeverRequestInterface

    $request, RequestHandlerInterface $handler ): ResponseInterface { // 前処理 // ... // ハンドラがリクエストを処理 $response = $handler->handle($request); // 後処理 // ... return $response; } } Nextat Inc. 26
  9. 3-1. Constructor Property Promotion Before class PostController { private PostService

    $service; public function __construct(PostService $service) { $this->service = $servuce; } public function show(int $postId): JsonResponse { $post = $this->service->find($postId); // 略 } } Nextat Inc. 34
  10. After class PostController { public function __construct(PostService $service) {} public

    function show(int $postId): JsonResponse { $post = $this->service->find($postId); // 略 } } Nextat Inc. 35
  11. Attributesのシンタックス #[ ORM\Entity, ORM\Table("user") ] class User { #[ORM\Id, ORM\Column("integer"),

    ORM\GeneratedValue] private $id; #[ORM\Column("string", ORM\Column::UNIQUE)] #[Assert\Email(["message" => "The email '{{ value }}' is not a valid email."])] private $email; } https://wiki.php.net/rfc/shorter_attribute_syntax_change Nextat Inc. 41
  12. 3-3. Union Typesなど型に関する機能 Union Types Static return type (PHP7.4ですが) Typed

    Properties 静的解析ブーム IDEの静的解析の強化 PHPStan, Psalmなど静的解析ツールの進化 静的解析フレンドリーなFWも増えるはず Nextat Inc. 45
  13. Write Once, Deploy Anyware (したい) FaaSへのデプロイの⾃動化は⼤変 コードだけ書いたら最⼩限の設定でいい感じにしてほしい Serverless Framework https://www.serverless.com/https://www.serverless.com/

    Bref https://bref.sh/ Laravel Vapor https://vapor.laravel.com/ 我々のコードとインフラとのつなぎ⽬をカバーしてくれるフレームワークに期待 Nextat Inc. 52
  14. protobuf-net.Grpcの例(アノテーションを活⽤) [DataContract] public class User { [DataMember(Order = 1)] public

    uint id { get; set; } [DataMember(Order = 2)] public string name { get; set; } } 対応するgRPCのメッセージ message User { uint32 id = 1; string name = 2; } Nextat Inc. 62
  15. OpenAPIについて詳しく学ぶ → ゼロベースから Laravel を⽤いた API 実装オートメーション https://speakerdeck.com/memory1994/zerobesukara-laravel-woyong-ita-api- shi-zhuang-otomesiyon GraphQLについて詳しく学ぶ

    → Laravel + Lighthouseで始める低コストなGraphQL⼊⾨ https://speakerdeck.com/d_endo/laravel-plus-lighthousedeshi-merudi- kosutonagraphqlru-men Nextat Inc. 65
  16. 参考フレームワーク(PHP) API Platform (REST、GraphQL)https://api-platform.com/ Siler (GraphQL、Swoole)https://github.com/leocavalcante/siler Hyperf (Swoole、coroutine)https://hyperf.wiki/2.0/ Symlex (RoadRunner、Symfony

    component)https://symlex.org/ Swoft (Swoole、coroutine) http://en.swoft.org/ Spiral Framework (PHP/Go、RoadRunner) https://spiral.dev/ Bref (Lambda) https://bref.sh/ Nextat Inc. 77
  17. 参考フレームワーク(PHP) Igni (PSR、Swoole) https://github.com/igniphp/framework Comet (Slim + Workerman) https://github.com/gotzmann/comet BEAR.Sundy

    (REST、AOP) https://bearsunday.github.io Laravel (Fullstack、Symfony component)https://laravel.com/ CakePHP (規約、PSR)https://cakephp.org Laminas Mezzio (Middleware) https://docs.mezzio.dev/mezzio/ Lighthouse (Laravel + GraphQL) https://lighthouse-php.com/ Railt (Laravel + GraphQL) https://github.com/railt/railt Nextat Inc. 78
  18. 参考フレームワーク(他⾔語) Quarkus (Java、GraalVM対応、コンテナ)https://quarkus.io/ Micronaut (Java、GraalVM対応、コンテナ)https://micronaut.io/ Spring WebFlux(Java、リアクティブプログラミング) https://spring.pleiades.io/spring- framework/docs/current/reference/html/web-reactive.html Rocket

    (Rust、 Extractor、Responders)https://rocket.rs/ Blitz.js (JavaScript、Next.js + ORM、isomorphic)https://blitzjs.com/ NestJS (TypeScript、Fullstack、Decorator) https://nestjs.com/ frourio (TypeScript、One TypeScript) https://frourio.io/ Nextat Inc. 79