このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン 前のリビジョン 次のリビジョン | 前のリビジョン | ||
slim:4:cookbook [2020/10/09 10:29] y2sunlight [The simple solution] |
slim:4:cookbook [2020/10/13 21:59] y2sunlight [Uploading files using POST forms] |
||
---|---|---|---|
行 22: | 行 22: | ||
----- | ----- | ||
- | ===== Trailing | + | ===== ルートパターンの末尾のスラッシュ(/) ===== |
- | Slim treats a URL pattern with a trailing slash as different to one without. That is, ''/ | + | Slimは、末尾にスラッシュがあるURLパターンを、無いものとは異なるものとして扱います。つまり、''/ |
For GET requests a permanent redirect is fine, but for other request methods like POST or PUT the browser will send the second request with the GET method. To avoid this you simply need to remove the trailing slash and pass the manipulated url to the next middleware. | For GET requests a permanent redirect is fine, but for other request methods like POST or PUT the browser will send the second request with the GET method. To avoid this you simply need to remove the trailing slash and pass the manipulated url to the next middleware. | ||
- | If you want to redirect/ | + | GETリクエストの場合、パーマネント(permanent)リダイレクトは問題ありませんが、POSTやPUTなどの他のリクエストメソッドの場合、ブラウザはGETメソッドを使用して2番目のリクエストを送信します。これを回避するには、単に、末尾のスラッシュを削除し、操作されたURLを次のミドルウェアに渡す必要があります。 |
- | Slimは、末尾にスラッシュがあるURLパターンを、ないものとは異なるものとして扱います。 つまり、''/ | + | ''/'' |
- | + | ||
- | GETリクエストの場合、永続的なリダイレクトは問題ありませんが、POSTやPUTなどの他のリクエストメソッドの場合、ブラウザはGETメソッドを使用して2番目のリクエストを送信します。 これを回避するには、末尾のスラッシュを削除し、操作されたURLを次のミドルウェアに渡す必要があります。 | + | |
- | + | ||
- | ''/'' | + | |
<code php> | <code php> | ||
行 73: | 行 69: | ||
</ | </ | ||
- | Alternatively, | + | あるいは、[[https:// |
- | + | ||
- | または、[[https:// | + | |
<code php> | <code php> | ||
行 85: | 行 79: | ||
\\ | \\ | ||
- | ===== Retrieving Current Route ===== | + | ===== 現在のルートの取得 |
- | + | ||
- | If you ever need to get access to the current route within your application, | + | |
アプリケーション内の現在のルートにアクセスする必要がある場合は、着信時の '' | アプリケーション内の現在のルートにアクセスする必要がある場合は、着信時の '' | ||
- | |||
- | From there you can get the route via $routeContext-> | ||
そこから、'' | そこから、'' | ||
- | Note: If you need to access the '' | + | 注:ルート(route)ハンドラーに到達する前にミドルウェアサイクル中に '' |
- | + | ||
- | 注:ルートハンドラーに到達する前にミドルウェアサイクル中に '' | + | |
- | + | ||
- | Example: | + | |
例: | 例: | ||
行 146: | 行 132: | ||
\\ | \\ | ||
- | ===== Setting up CORS ===== | + | ===== CORSの設定 |
- | ==== The simple solution ==== | + | CORS - クロス オリジンリソース シェアリング(オリジン間リソース共有) |
+ | * CORSサポートを実装するための適切なフローチャートリファレンス: \\ [[https:// | ||
+ | * CORSサポートはここでテストできます:[[http:// | ||
+ | * ここで仕様を読むことができます:[[https:// | ||
+ | > 参考:https:// | ||
+ | ==== シンプル ソリューション ==== | ||
- | < | + | 単純なCORSリクエストの場合、サーバーはレスポンスに次のヘッダーを追加するだけで済みます。 |
+ | |||
+ | < | ||
+ | Access-Control-Allow-Origin: | ||
</ | </ | ||
+ | |||
+ | The following code should enable lazy CORS. | ||
+ | |||
+ | 次のコードは、Lazy CORS を有効にする必要があります。 | ||
<code php> | <code php> | ||
+ | $app-> | ||
+ | return $response; | ||
+ | }); | ||
+ | |||
+ | $app-> | ||
+ | $response = $handler-> | ||
+ | return $response | ||
+ | -> | ||
+ | -> | ||
+ | -> | ||
+ | }); | ||
</ | </ | ||
+ | |||
+ | 最後のルートとして次のルートを追加します: | ||
<code php> | <code php> | ||
+ | <?php | ||
+ | use Slim\Exception\HttpNotFoundException; | ||
+ | |||
+ | /** | ||
+ | * Catch-all route to serve a 404 Not Found page if none of the routes match | ||
+ | * NOTE: make sure this route is defined last | ||
+ | */ | ||
+ | $app-> | ||
+ | throw new HttpNotFoundException($request); | ||
+ | }); | ||
</ | </ | ||
行 164: | 行 185: | ||
==== Access-Control-Allow-Methods ==== | ==== Access-Control-Allow-Methods ==== | ||
+ | |||
+ | 次のミドルウェアを使用して、Slimのルーターにクエリを実行し、特定のパターンが実装するメソッドのリストを取得できます。 | ||
+ | |||
+ | これが完全なサンプルアプリケーションです: | ||
<code php> | <code php> | ||
+ | <?php | ||
+ | |||
+ | use Psr\Http\Message\ResponseInterface as Response; | ||
+ | use Psr\Http\Message\ServerRequestInterface as Request; | ||
+ | use Psr\Http\Server\RequestHandlerInterface; | ||
+ | use Slim\Factory\AppFactory; | ||
+ | use Slim\Routing\RouteCollectorProxy; | ||
+ | use Slim\Routing\RouteContext; | ||
+ | |||
+ | require_once __DIR__ . '/ | ||
+ | |||
+ | $app = AppFactory:: | ||
+ | |||
+ | $app-> | ||
+ | |||
+ | // This middleware will append the response header Access-Control-Allow-Methods with all allowed methods | ||
+ | $app-> | ||
+ | $routeContext = RouteContext:: | ||
+ | $routingResults = $routeContext-> | ||
+ | $methods = $routingResults-> | ||
+ | $requestHeaders = $request-> | ||
+ | |||
+ | $response = $handler-> | ||
+ | |||
+ | $response = $response-> | ||
+ | $response = $response-> | ||
+ | $response = $response-> | ||
+ | |||
+ | // Optional: Allow Ajax CORS requests with Authorization header | ||
+ | // $response = $response-> | ||
+ | |||
+ | return $response; | ||
+ | }); | ||
+ | |||
+ | // The RoutingMiddleware should be added after our CORS middleware so routing is performed first | ||
+ | $app-> | ||
+ | |||
+ | // The routes | ||
+ | $app-> | ||
+ | $response-> | ||
+ | |||
+ | return $response; | ||
+ | }); | ||
+ | |||
+ | $app-> | ||
+ | $userId = (int)$arguments[' | ||
+ | $response-> | ||
+ | |||
+ | return $response; | ||
+ | }); | ||
+ | |||
+ | $app-> | ||
+ | // Retrieve the JSON data | ||
+ | $parameters = (array)$request-> | ||
+ | |||
+ | $response-> | ||
+ | |||
+ | return $response; | ||
+ | }); | ||
+ | |||
+ | $app-> | ||
+ | $userId = (int)$arguments[' | ||
+ | $response-> | ||
+ | |||
+ | return $response; | ||
+ | }); | ||
+ | |||
+ | // Allow preflight requests | ||
+ | // Due to the behaviour of browsers when sending a request, | ||
+ | // you must add the OPTIONS method. Read about preflight. | ||
+ | $app-> | ||
+ | // Do nothing here. Just return the response. | ||
+ | return $response; | ||
+ | }); | ||
+ | |||
+ | // Allow additional preflight requests | ||
+ | $app-> | ||
+ | return $response; | ||
+ | }); | ||
+ | |||
+ | // Using groups | ||
+ | $app-> | ||
+ | $group-> | ||
+ | // Your code here... | ||
+ | $userId = (int)$arguments[' | ||
+ | $response-> | ||
+ | |||
+ | return $response; | ||
+ | }); | ||
+ | |||
+ | $group-> | ||
+ | $userId = (int)$arguments[' | ||
+ | $response-> | ||
+ | |||
+ | return $response; | ||
+ | }); | ||
+ | |||
+ | // Allow preflight requests | ||
+ | $group-> | ||
+ | return $response; | ||
+ | }); | ||
+ | }); | ||
+ | |||
+ | $app-> | ||
</ | </ | ||
行 171: | 行 300: | ||
==== Access-Control-Allow-Credentials ==== | ==== Access-Control-Allow-Credentials ==== | ||
+ | |||
+ | リクエストに資格情報(Cookie、承認ヘッダー、またはTLSクライアント証明書)が含まれている場合は、レスポンスオブジェクトに '' | ||
<code php> | <code php> | ||
+ | $response = $response-> | ||
</ | </ | ||
\\ | \\ | ||
- | ===== Uploading files using POST forms ===== | + | ===== POSTフォームを使ったファイルのアップロード |
+ | |||
+ | POSTリクエストのフォームを使用してアップロードされたファイルは、Requestメソッド '' | ||
+ | |||
+ | POSTリクエストを使用してファイルをアップロードする場合は、ファイルアップロードフォームに属性 '' | ||
+ | |||
+ | 同じ input name に対して複数のファイルがアップロードされる場合は、HTMLのinput nameの後に鍵括弧( '' | ||
+ | |||
+ | 以下は、単一ファイルと複数ファイルの両方のアップロードを含むHTMLフォームの例です。 | ||
<code php> | <code php> | ||
+ | <!-- make sure the attribute enctype is set to multipart/ | ||
+ | <form method=" | ||
+ | <!-- upload of a single file --> | ||
+ | <p> | ||
+ | < | ||
+ | <input type=" | ||
+ | </p> | ||
+ | |||
+ | <!-- multiple input fields for the same input name, use brackets --> | ||
+ | <p> | ||
+ | < | ||
+ | <input type=" | ||
+ | <input type=" | ||
+ | </p> | ||
+ | |||
+ | <!-- one file input field that allows multiple files to be uploaded, use brackets --> | ||
+ | <p> | ||
+ | < | ||
+ | <input type=" | ||
+ | </p> | ||
+ | |||
+ | <p> | ||
+ | <input type=" | ||
+ | </p> | ||
+ | </ | ||
</ | </ | ||
+ | |||
+ | アップロードされたファイルは、'' | ||
<code php> | <code php> | ||
+ | <?php | ||
+ | |||
+ | use DI\ContainerBuilder; | ||
+ | use Psr\Http\Message\ResponseInterface; | ||
+ | use Psr\Http\Message\ServerRequestInterface; | ||
+ | use Psr\Http\Message\UploadedFileInterface; | ||
+ | use Slim\Factory\AppFactory; | ||
+ | |||
+ | require __DIR__ . '/ | ||
+ | |||
+ | $containerBuilder = new ContainerBuilder(); | ||
+ | $container = $containerBuilder-> | ||
+ | |||
+ | $container-> | ||
+ | |||
+ | AppFactory:: | ||
+ | $app = AppFactory:: | ||
+ | |||
+ | $app-> | ||
+ | $directory = $this-> | ||
+ | $uploadedFiles = $request-> | ||
+ | |||
+ | // handle single input with single file upload | ||
+ | $uploadedFile = $uploadedFiles[' | ||
+ | if ($uploadedFile-> | ||
+ | $filename = moveUploadedFile($directory, | ||
+ | $response-> | ||
+ | } | ||
+ | |||
+ | // handle multiple inputs with the same key | ||
+ | foreach ($uploadedFiles[' | ||
+ | if ($uploadedFile-> | ||
+ | $filename = moveUploadedFile($directory, | ||
+ | $response-> | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // handle single input with multiple file uploads | ||
+ | foreach ($uploadedFiles[' | ||
+ | if ($uploadedFile-> | ||
+ | $filename = moveUploadedFile($directory, | ||
+ | $response-> | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return $response; | ||
+ | }); | ||
+ | |||
+ | /** | ||
+ | * Moves the uploaded file to the upload directory and assigns it a unique name | ||
+ | * to avoid overwriting an existing uploaded file. | ||
+ | * | ||
+ | * @param string $directory The directory to which the file is moved | ||
+ | * @param UploadedFileInterface $uploadedFile The file uploaded file to move | ||
+ | * | ||
+ | * @return string The filename of moved file | ||
+ | */ | ||
+ | function moveUploadedFile(string $directory, UploadedFileInterface $uploadedFile) | ||
+ | { | ||
+ | $extension = pathinfo($uploadedFile-> | ||
+ | |||
+ | // see http:// | ||
+ | $basename = bin2hex(random_bytes(8)); | ||
+ | $filename = sprintf(' | ||
+ | |||
+ | $uploadedFile-> | ||
+ | |||
+ | return $filename; | ||
+ | } | ||
+ | |||
+ | $app-> | ||
</ | </ | ||
\\ | \\ | ||