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

20230315のPHP勉強会(Slimをオススメしてみる)

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for gallu gallu
March 15, 2023

 20230315のPHP勉強会(Slimをオススメしてみる)

Avatar for gallu

gallu

March 15, 2023
Tweet

More Decks by gallu

Other Decks in Technology

Transcript

  1. Slimいいよ!!  https://www.slimframework.com/  Slim is a PHP micro framework

    that helps you quickly write simple yet powerful web applications and APIs.  Slim は、シンプルかつ強力な Web アプリケーションと API をすばやく作 成するのに役立つ PHP マイクロ フレームワークです。(Google)  Slimは、シンプルかつパワフルなWebアプリケーションやAPIを素早く作 成できるPHPマイクロフレームワークです。(DeepL)  Slimいいです!!  micro framework いいです!!  シンプルでいいです!!  っていう個人の感想と妄想を垂れ流してみます(笑
  2. 実際どんな所が好きなのか?  軽量(なので早い)  メモリは、なんだかんだ無視しにくいリソースです  手元で var_dump(memory_get_peak_usage(true)) 仕込んだ結果 

    Slim: 2,097,152 / Laravel: 16,777,216  学習コストが(とりあえず)低い  「とりあえず」(笑  「素のPHPのみ」でWebアプリ書ければ大体なんとかなる!!  柔軟性と拡張性がある(というか全部自力で書け)  「全部自分で書け」なので「実装箇所がわかりやすい」(笑  「FWが何をやっているか」が理解しやすい  FWのコードもコンパクトなので、読みやすいです  「コンパクトだから読みやすいのか?」って欺瞞は棚の上にw
  3.  まずは適当なディレクトリで最低限をinstall  composer require slim/slim  composer require slim/psr7

     公開用ディレクトリ作成  mkdir public  index.phpを書く(公式サイトのコピペ)  次のページに記載  動かしてみる  php -S 0.0.0.0:8080 -t public public/index.php  http://ドメイン名/hello/gallu
  4.  public/index.php <?php use Psr¥Http¥Message¥ResponseInterface as Response; use Psr¥Http¥Message¥ServerRequestInterface as

    Request; use Slim¥Factory¥AppFactory; require __DIR__ . '/../vendor/autoload.php'; $app = AppFactory::create(); $app->get('/hello/{name}', function (Request $request, Response $response, array $args) { $name = $args['name']; $response->getBody()->write("Hello, $name"); return $response; }); $app->run();
  5.  元のpublic/index.php <?php use Psr¥Http¥Message¥ResponseInterface as Response; use Psr¥Http¥Message¥ServerRequestInterface as

    Request; use Slim¥Factory¥AppFactory; require __DIR__ . '/../vendor/autoload.php'; $app = AppFactory::create(); $app->get('/hello/{name}', function (Request $request, Response $response, array $args) { $name = $args['name']; $response->getBody()->write("Hello, $name"); return $response; }); $app->run();
  6.  public/index.php <?php use Slim¥Factory¥AppFactory; require __DIR__ . '/../vendor/autoload.php'; $app

    = AppFactory::create(); // ルーティングの読み込み require __DIR__ . '/../config/routes.php'; $app->run();
  7.  config/routes.php <?php declare(strict_types=1); use Psr¥Http¥Message¥ResponseInterface as Response; use Psr¥Http¥Message¥ServerRequestInterface

    as Request; // 初期に書いてあるルーティング $app->get('/hello/{name}', function (Request $request, Response $response, array $args) { $name = $args['name']; $response->getBody()->write("Hello, $name"); return $response; });
  8.  元 config/routes.php <?php declare(strict_types=1); use Psr¥Http¥Message¥ResponseInterface as Response; use

    Psr¥Http¥Message¥ServerRequestInterface as Request; // 初期に書いてあるルーティング $app->get('/hello/{name}', function (Request $request, Response $response, array $args) { $name = $args['name']; $response->getBody()->write("Hello, $name"); return $response; });
  9.  config/routes.php <?php declare(strict_types=1); use Psr¥Http¥Message¥ResponseInterface as Response; use Psr¥Http¥Message¥ServerRequestInterface

    as Request; // 初期に書いてあるルーティング $app->get('/hello/{name}', function (Request $request, Response $response, array $args) { $name = $args['name']; $response->getBody()->write("Hello, $name"); return $response; }); // 追加のルーティング $app->get('/', function (Request $request, Response $response, array $args) { $response->getBody()->write("Top Page"); return $response; });
  10. Controllerを切り出してみる  普通に考えて「routingん中にコードを書く」とか、常軌を 逸脱しているので  いわゆる「Controller」的なクラスを切り出してみましょう  まず「Controllerクラスを入れる」ディレクトリを作ります。 これもまぁどこでもよいのですが、慣習も考えてこんな風 にしてみましょう

     mkdir -p app/Controller  autoloaderとかないと色々面倒なので設定しましょう  composer.jsonに追記します(コードは次のページで)  requireのバージョンとかちょっと違ってもキニシナイ!!  composer dump-autoload
  11.  元 config/routes.php <?php declare(strict_types=1); use Psr¥Http¥Message¥ResponseInterface as Response; use

    Psr¥Http¥Message¥ServerRequestInterface as Request; // 初期に書いてあるルーティング $app->get('/hello/{name}', function (Request $request, Response $response, array $args) { $name = $args['name']; $response->getBody()->write("Hello, $name"); return $response; }); // 追加のルーティング $app->get('/', function (Request $request, Response $response, array $args) { $response->getBody()->write("Top Page"); return $response; });
  12.  config/routes.php <?php declare(strict_types=1); use Psr¥Http¥Message¥ResponseInterface as Response; use Psr¥Http¥Message¥ServerRequestInterface

    as Request; // 初期に書いてあるルーティング $app->get('/hello/{name}', ¥App¥Controller¥HelloController::class . ':index'); // 追加のルーティング $app->get('/', ¥App¥Controller¥HomeController::class);
  13.  app/Controller/HelloController.php <?php declare(strict_types=1); namespace App¥Controller; use Psr¥Http¥Message¥ServerRequestInterface as Request;

    use Psr¥Http¥Message¥ResponseInterface as Response; class HelloController { // 多分「よくある」系の書き方 public function index(Request $request, Response $response, $args) { $name = $args['name']; $response->getBody()->write("Hello, $name"); return $response; } }
  14.  app/Controller/HomeController.php <?php declare(strict_types=1); namespace App¥Controller; use Psr¥Http¥Message¥ServerRequestInterface as Request;

    use Psr¥Http¥Message¥ResponseInterface as Response; class HomeController { // XXX 1クラスに「1つしかメソッドを書くつもりがない」場合、こういった書き方もできる public function __invoke(Request $request, Response $response, $args) { // 出力 $response->getBody()->write("Top Page"); return $response; } }
  15. Controllerとして許容される形式は?  https://www.slimframework.com/docs/v4/objects/routi ng.html#container-resolution 以降に大体書いてあるの ですが  $app->get('/', '¥HomeController:home'); 

    $app->get('/', ¥HomeController::class . ':home');  $app->get('/', [¥HomeController::class, 'home']);  $app->get('/', ¥HomeAction::class);  __invoke() メソッドがある場合  となります  あと実際には「関数」も通りますね
  16. その辺のコードをざっくり見てみましょう  vendor/slim/slim/Slim/CallableResolver.phpの超訳 private function resolveSlimNotation(string $toResolve): array { [$class,

    $method] = :で文字列をsplit(:なかったらmethodには null) if (containerがclassを持ってたら) { $instance = containerからclassのインスタンスをげと インスタンスがげとれなければ例外を投げて終了 } else { if (クラスが存在していなかったら) { if (メソッドがnullじゃなければ) { $class .= '::' . $method . '()'; } $classないよ~、って例外をぶん投げて終了 } $instance = new $class($this->container); } return [$instance, $method]; }
  17. で……  vendor/slim/slim/Slim/CallableResolver.php public function resolve($toResolve): callable { $toResolve =

    $this->prepareToResolve($toResolve); if (is_callable($toResolve)) { return $this->bindToContainer($toResolve); } $resolved = $toResolve; if (is_string($toResolve)) { $resolved = $this->resolveSlimNotation($toResolve); $resolved[1] ??= '__invoke'; } $callable = $this->assertCallable($resolved, $toResolve); return $this->bindToContainer($callable); }