PHP でライブラリなしウェブサーバ の続き
◆ 前回こうしようかなと思ったのをやってみた
◆ 満足とはいかず まだ改善の余地がありそうだけど やりだすと終わらない
◆ 結局次になにか作るときは使い回さず新しく作りそう
◆ 満足とはいかず まだ改善の余地がありそうだけど やりだすと終わらない
◆ 結局次になにか作るときは使い回さず新しく作りそう
前回のこれ
最後に書いたようにやっぱりこうしたほうがいいかなというのがあって 少しいじってみました
シンプルにする方針で 無くてもいいのは消して 単純な PHP スクリプトに近づけています
phpminweb2
Nginx でルーティングして公開フォルダにある PHP ファイルを実行して ファイルが無い場合はデフォルトの HTML を返すところまで Nginx 側でやろうかと考えてました
しかしそれだと完全にエントリポイントが分かれてしまうので 全ファイルで autoload.php の読み込みから始める必要があります
それも面倒なのでエントリポイントは 1 つにして main.php ファイルを実行するようにしました
main.php は autoload.php の読み込みとルーティングとエラーのキャッチを簡単にやるくらいです
リクエストされたパスに対応する PHP ファイルを routes フォルダ以下から探します
あれば そのファイル なければ errors/not-found.php を require します
前回だと /api 以下かどうかでファイルが見つからない場合やエラーの場合のレスポンスのフォーマットを切り替えてましたが そういう無くても良い機能はなくしました
存在しない API を呼び出しても JSON は返ってきませんが JSON が返ってこないなら何かエラーということです
Router と Route クラスもなくしました
Router 相当の処理は main.php の処理でやってます
各ルートの記述は シンプルな PHP スクリプト風に書くことにして Route クラスを不要にしています
App 以下にあった Request や Csession などは static 関数のみにしています
前回は $app->request や $app->csession という形でのアクセスだったのでインスタンス化していましたが インスタンスが 1 つで良くて状態を保持しないものは static クラスという扱いにしました
全部こうできればよかったのですが データベースにアクセスする系の処理ではインスタンスが必要になりました
PDO インスタンスを毎回作るのは無駄ですし 現在のユーザ情報を毎回取得するのも無駄です
これらを保持する場所としてプロパティを使うのでインスタンス化が必要です
static なものではなくインスタンスに保持されてると 他クラスで使うときにインスタンスを受け取る必要があり 単純にコンストラクタを使うと微妙な感じになりました
PDO インスタンスや現在のユーザなど 1 つのリクエストの処理の中では 1 つしかないものなら静的プロパティにデータを持たせることもできます
そうして極力インスタンス化はしないようにするのもありかもです
それか前回のまま自動でインスタンス化して $app->request などでアクセスできるようにするでいいかもです
今回は前回に比べて use が多いのが面倒に感じました
自動でインスタンス化する方法だと use が不要になるメリットもあります
今回はルートのファイルのトップレベルに処理を書いています
これくらいにシンプルだと問題ないですが if 文で return したいケースに対応できないのでそういう場合は関数の即時実行を使うことになります
それなら最初から前回みたいに関数を返すか 関数の引数として関数を渡すというのもありだと思います
そういう事を考えているとキリがないですし 結局次回なにか作るときは 使いまわしじゃなくてその時の気分と思いつきで新しいものを作ってそうです
最後に書いたようにやっぱりこうしたほうがいいかなというのがあって 少しいじってみました
シンプルにする方針で 無くてもいいのは消して 単純な PHP スクリプトに近づけています
phpminweb2
Nginx でルーティングして公開フォルダにある PHP ファイルを実行して ファイルが無い場合はデフォルトの HTML を返すところまで Nginx 側でやろうかと考えてました
しかしそれだと完全にエントリポイントが分かれてしまうので 全ファイルで autoload.php の読み込みから始める必要があります
それも面倒なのでエントリポイントは 1 つにして main.php ファイルを実行するようにしました
main.php は autoload.php の読み込みとルーティングとエラーのキャッチを簡単にやるくらいです
リクエストされたパスに対応する PHP ファイルを routes フォルダ以下から探します
あれば そのファイル なければ errors/not-found.php を require します
前回だと /api 以下かどうかでファイルが見つからない場合やエラーの場合のレスポンスのフォーマットを切り替えてましたが そういう無くても良い機能はなくしました
存在しない API を呼び出しても JSON は返ってきませんが JSON が返ってこないなら何かエラーということです
Router と Route クラスもなくしました
Router 相当の処理は main.php の処理でやってます
各ルートの記述は シンプルな PHP スクリプト風に書くことにして Route クラスを不要にしています
<?php
use phpminweb2\Utils\Csession;
use phpminweb2\Utils\Response;
$sess = Csession::get();
$count = $sess->count ?? 0;
$sess->count = $count + 1;
Csession::set($sess);
Response::template('page4', $count);
<?php
use phpminweb2\Utils\Request;
use phpminweb2\Utils\Response;
$validated = Request::validate([
'method' => 'GET',
'query' => ['object', [
'keys' => [
'a' => ['int'],
'b' => ['string'],
],
]],
]);
Response::json([
'a' => $validated->query->a,
'b' => $validated->query->b,
]);
App 以下にあった Request や Csession などは static 関数のみにしています
前回は $app->request や $app->csession という形でのアクセスだったのでインスタンス化していましたが インスタンスが 1 つで良くて状態を保持しないものは static クラスという扱いにしました
全部こうできればよかったのですが データベースにアクセスする系の処理ではインスタンスが必要になりました
PDO インスタンスを毎回作るのは無駄ですし 現在のユーザ情報を毎回取得するのも無駄です
これらを保持する場所としてプロパティを使うのでインスタンス化が必要です
static なものではなくインスタンスに保持されてると 他クラスで使うときにインスタンスを受け取る必要があり 単純にコンストラクタを使うと微妙な感じになりました
<?php
use phpminweb2\Utils\Auth;
use phpminweb2\Utils\Db;
use phpminweb2\Utils\Request;
use phpminweb2\Utils\Response;
use phpminweb2\Classes\Item;
use phpminweb2\Classes\User;
$db = new Db();
$auth = new Auth(new User($db));
$user = $auth->requirePermission();
$validated = Request::validate([
'method' => 'POST',
'body' => [
['object', [
'keys' => [
'id' => ['int', ['min' => 1]],
],
]],
],
]);
$item_id = $validated->body->id;
$item = new Item($db);
$item->delete($item_id, $user->id);
Response::json(['success' => true]);
PDO インスタンスや現在のユーザなど 1 つのリクエストの処理の中では 1 つしかないものなら静的プロパティにデータを持たせることもできます
そうして極力インスタンス化はしないようにするのもありかもです
それか前回のまま自動でインスタンス化して $app->request などでアクセスできるようにするでいいかもです
今回は前回に比べて use が多いのが面倒に感じました
自動でインスタンス化する方法だと use が不要になるメリットもあります
今回はルートのファイルのトップレベルに処理を書いています
これくらいにシンプルだと問題ないですが if 文で return したいケースに対応できないのでそういう場合は関数の即時実行を使うことになります
それなら最初から前回みたいに関数を返すか 関数の引数として関数を渡すというのもありだと思います
そういう事を考えているとキリがないですし 結局次回なにか作るときは 使いまわしじゃなくてその時の気分と思いつきで新しいものを作ってそうです