Skip to content

[QUESTION] 关于表单验证中的array验证规则的实际效果的疑问 #4747

@wilbur-yu

Description

@wilbur-yu

Hyperf version: ~2.2.0
Hyperf Validation versin: v2.2.13

在OrderRequest中的定义如下

<?php

declare(strict_types=1);

namespace App\Request\V1;

use App\Request\Request;

class OrderRequest extends Request
{
    protected $scenes = [
        'privates' => [
            'id',
            'carry_people_info',
        ],
    ];

    public function rules(): array
    {
        return [
            'id' => 'bail|required|string',
            'carry_people_info' => 'bail|sometimes|filled|array:username,tel,gender',
            'carry_people_info.*.username' => [
                'bail',
                'required',
                'string',
                'max:30',
                'regex:/^[\x{4e00}-\x{9fa5}a-zA-Z{\d}{\s}]+$/u',
            ],
            'carry_people_info.*.tel' => [
                'bail',
                'required',
                'size:11',
                'regex:#^1[3456789][0-9]{9}$#',
            ],
            'carry_people_info.*.gender' => 'bail|required|integer|in:1,0',
        ];
    }
}

在OrderController中的定义如下

<?php

declare(strict_types=1);

namespace App\Controller\V1;

use App\Constants\BusCode;
use App\Constants\BusConstant\RouteConstant;
use App\Constants\BusConstant\ServerConstant;
use App\Event\LessonOrderCreatedEvent;
use App\Exception\LessonOrderServiceException;
use App\Middleware\AuthorizationMiddleware;
use App\Middleware\VerifyGuardWasTheStudentMiddleware;
use App\Request\V1\OrderRequest;
use App\Service\Lesson\LessonService;
use App\Service\LessonOrder\LessonOrderService;
use App\Service\LessonScheduleService;
use App\Service\PaymentService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\Middlewares;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Request;
use JetBrains\PhpStorm\ArrayShape;
use Psr\Http\Message\ResponseInterface;
use Yansongda\Supports\Collection;

use function encrypt;
use function decrypt;

#[Controller(server: ServerConstant::API_HTTP_SERVER['name'], prefix: RouteConstant::API_BASE_PREFIX.'orders')]
#[Middlewares(AuthorizationMiddleware::class, VerifyGuardWasTheStudentMiddleware::class)]
class OrderController extends AbstractController
{
    #[Inject]
    protected OrderService $orderService;

    #[Inject]
    protected PaymentService $paymentService;

    #[Inject]
    protected LessonService $lessonService;

    /**
     * 统一下单入口
     *
     * @return ResponseInterface
     */
    #[PostMapping(path: '')]
    public function ofType(): ResponseInterface
    {
        $type = (string)$this->request->query('type');
        !method_exists($this, $type)
        && throw new LessonOrderServiceException(BusCode::SERVICE_LESSON_TYPE_NOT_FOUND);

        $request = di(LessonOrderRequest::class);
        $request->scene($type)->validateResolved();

        return $this->{$type}($request);
    }

    /**
     * 统一订单创建
     */
    #[ArrayShape(['no' => 'string', 'wechat_pay' => Collection::class])]
    protected function create($model, array $inputs): array
    {
        $inputs['user_id'] = self::user()->id;
        $inputs['ip'] = get_client_ip();

        $order = $this->orderService->create($model, $inputs);

        $order = $this->orderService->buyingBeforeCheck($order);

        $result = $this->paymentService->create($order);

        event()->dispatch(new LessonOrderCreatedEvent($order->id));

        return [
            'no' => encrypt($order->no),
            'wechat_pay' => $result->toArray(),
        ];
    }

    /**
     * @param  \Hyperf\HttpServer\Request  $request
     *
     * @return \Psr\Http\Message\ResponseInterface
     */
    protected function privates(Request $request): ResponseInterface
    {
        $inputs = $request->inputs([
            'id',
            'carry_people_info',
        ]);
        isset($inputs['remark']) && $this->orderService->contentIsSecurity($inputs['remark']);
        $skuId = (int)decrypt($inputs['id']);
        $sku = $this->lessonService->checkBeforeBuying($skuId, $inputs);
        $result = $this->create($sku, $inputs);

        return $this->response->success($result);
    }
}

OrderController->ofType接收请求并根ody据场景值type: 默认为privates进行验证.

在请求body定义如下参数

{
    "id": "78f1N0Hk1OKmSnX_CIUaSIc8zx6R9lTo2FsupR7v8A",
    "carry_people_info": [
        {
            "test": "test"
        }
    ]
}

正常通过, 即针对数组中字段的验证array:username,tel,gender没有产生作用.

在请求body定义如下参数

{
    "id": "78f1N0Hk1OKmSnX_CIUaSIc8zx6R9lTo2FsupR7v8A",
    "carry_people_info": [
        {
            "username": "姓名,./,..@"
        }
    ]
}

正常通过, 即针对数组中元素的验证carry_people_info.*.username没有产生作用.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions