Input.php 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. <?php
  2. declare(strict_types=1);
  3. namespace app\miniapi\http;
  4. use Webman\Http\Request;
  5. use app\miniapi\exception\ApiException;
  6. final class Input
  7. {
  8. /** JSON object only: never merge URL parameters into a command body. */
  9. public static function json(Request $request): array
  10. {
  11. if (strtolower(trim(explode(';', (string) $request->header('content-type', ''))[0])) !== 'application/json') {
  12. throw new ApiException(41501, '请使用 application/json 提交参数', 415);
  13. }
  14. $raw = $request->rawBody();
  15. if (strlen($raw) > self::bodyLimit($request)) {
  16. throw new ApiException(41301, '请求内容过大', 413);
  17. }
  18. try {
  19. $value = json_decode($raw, false, 64, JSON_THROW_ON_ERROR);
  20. } catch (\JsonException) {
  21. throw new ApiException(40001, 'JSON格式不正确', 400);
  22. }
  23. if (!$value instanceof \stdClass) {
  24. throw new ApiException(40001, '请求内容必须为JSON对象', 400);
  25. }
  26. // Validate the root as an object, then convert nested objects for service validators.
  27. return json_decode($raw, true, 64, JSON_THROW_ON_ERROR);
  28. }
  29. public static function bodyLimit(Request $request): int
  30. {
  31. return preg_match('#^/api/mini/v1/drivers/\d+/tasks/\d+/photos$#D', $request->path())
  32. ? (int) config('mini_api.max_photo_body_bytes', 3000000) : (int) config('mini_api.max_body_bytes', 65536);
  33. }
  34. public static function integer(mixed $value, string $field, int $min, int $max): int
  35. {
  36. if ((!is_int($value) && !is_string($value)) || filter_var($value, FILTER_VALIDATE_INT) === false || (int) $value < $min || (int) $value > $max) {
  37. throw new ApiException(42201, '参数校验失败', 422, [$field => "必须为{$min}至{$max}之间的整数"]);
  38. }
  39. return (int) $value;
  40. }
  41. }