Validator – 永夜 https://www.shuijingwanwq.com 没有不值得去解决的问题,也没有不值得去学习的技术! Thu, 28 May 2026 12:21:50 +0000 zh-Hans hourly 1 https://wordpress.org/?v=7.0 在 Lavavel 9 中 验证 符合 MySQL 字段类型 decimal(8,2) 的字段 https://www.shuijingwanwq.com/2024/07/05/8699/ https://www.shuijingwanwq.com/2024/07/05/8699/#respond Fri, 05 Jul 2024 07:55:56 +0000 https://www.shuijingwanwq.com/?p=8699 浏览量: 60 1、在 Lavavel 9 中 验证 符合 MySQL 字段类型 decimal(8,2) 的字段。如图1
在 Lavavel 9 中 验证 符合 MySQL 字段类型 decimal(8,2) 的字段

图1



`return_package_length` decimal(8,2) NOT NULL DEFAULT '0.00' COMMENT '退货包裹长度(厘米)'


2、最终实现如下


        $validator = Validator::make(
            $params,
            [
                'return_package_length' => [
                    'numeric',
                    'min:0.00',
                    'max:999999.99',
                    'regex:/^\d{0,6}(\.\d{1,2})?$/'
                ],
            ],
            [

            ]
        );
        if ($validator->stopOnFirstFailure()->fails()) {
            throw new BusinessException(BusinessException::MODULE_ORDER, $validator->getMessageBag()->first());
        }



3、分别尝试:-4(失败)、0(成功)、5(成功)、999999.99(成功)、999999.990(成功)、999999.991(失败)、9999990.99(失败)、0.09(成功)、0.009(失败)、0.0000001(失败),符合预期。如图2
分别尝试:-4(失败)、0(成功)、5(成功)、999999.99(成功)、999999.990(成功)、999999.991(失败)、9999990.99(失败)、0.09(成功)、0.009(失败)、0.0000001(失败),符合预期

图2

]]>
https://www.shuijingwanwq.com/2024/07/05/8699/feed/ 0
在 Laravel 9 ,当有 2 组时间字段时,每一组为 2 个,一为开始,一为结束,验证必须存在一组时间字段的实现 https://www.shuijingwanwq.com/2024/06/07/8628/ https://www.shuijingwanwq.com/2024/06/07/8628/#respond Fri, 07 Jun 2024 09:08:28 +0000 https://www.shuijingwanwq.com/?p=8628 浏览量: 81 1、在一个列表页面,有 2 组时间字段时,每一组为 2 个,一为开始,一为结束,需要验证必须存在一组时间字段。如图1
在一个列表页面,有 2 组时间字段时,每一组为 2 个,一为开始,一为结束,需要验证必须存在一组时间字段

图1

2、总计 4 个字段,分别是:shipping_at_gmt_start、shipping_at_gmt_end、operated_at_gmt_start、operated_at_gmt_end。必须存在一组时间字段,既必须存在 shipping_at_gmt_start、shipping_at_gmt_end 。或者必须存在 operated_at_gmt_start、operated_at_gmt_end 3、最终验证规则实现如下,依赖于 required_without 实现。当 shipping_at_gmt_start、shipping_at_gmt_end 其中一个不存在时,那么 operated_at_gmt_start 必填。符合预期。如图2
最终验证规则实现如下,依赖于 required_without 实现。当 shipping_at_gmt_start、shipping_at_gmt_end 其中一个不存在时,那么 operated_at_gmt_start 必填。符合预期

图2



    public function validateIndex(array $params): ValidationValidator
    {
        $validator = Validator::make(
            $params,
            [
                'filter.shipping_at_gmt_start' => 'required_without:filter.operated_at_gmt_start,filter.operated_at_gmt_end|date',
                'filter.shipping_at_gmt_end' => [
                    'date',
                    'after_or_equal:filter.shipping_at_gmt_start',
                    function ($attribute, $value, $fail) use ($params) {
                        $startDate = Carbon::parse($params['filter']['shipping_at_gmt_start'])->addMonths(3);
                        $endDate = Carbon::parse($value);
                        if ($endDate->isAfter($startDate)) {
                            $fail('交运时间结束与交运时间开始的跨度不可超过3个月');
                        }
                    },
                ],
                'filter.operated_at_gmt_start' => 'required_without:filter.shipping_at_gmt_start,filter.shipping_at_gmt_end|date',
                'filter.operated_at_gmt_end' => [
                    'date',
                    'after_or_equal:filter.operated_at_gmt_start',
                    function ($attribute, $value, $fail) use ($params) {
                        $startDate = Carbon::parse($params['filter']['operated_at_gmt_start'])->addMonths(3);
                        $endDate = Carbon::parse($value);
                        if ($endDate->isAfter($startDate)) {
                            $fail('操作时间结束与操作时间开始的跨度不可超过3个月');
                        }
                    },
                ],
            ],
            [
                'filter.shipping_at_gmt_start.required_without' => '时间筛选必填',
                'filter.shipping_at_gmt_start.date' => '交运时间开始必须是日期',
                'filter.shipping_at_gmt_end.date' => '交运时间结束必须是日期',
                'filter.shipping_at_gmt_end.after_or_equal' => '交运时间结束必须晚于或等于交运时间开始',
                'filter.operated_at_gmt_start.required_without' => '时间筛选必填',
                'filter.operated_at_gmt_start.date' => '操作时间开始必须是日期',
                'filter.operated_at_gmt_end.date' => '操作时间结束必须是日期',
                'filter.operated_at_gmt_end.after_or_equal' => '操作时间结束必须晚于或等于操作时间开始'
            ]
        );
        if ($validator->stopOnFirstFailure()->fails()) {
            throw new BusinessException(BusinessException::MODULE_ORDER, $validator->getMessageBag()->first());
        }

        return $validator;
    }


4、当 shipping_at_gmt_start、shipping_at_gmt_end 皆不存在时,那么 operated_at_gmt_start 必填。符合预期。如图3
当 shipping_at_gmt_start、shipping_at_gmt_end 皆不存在时,那么 operated_at_gmt_start 必填。符合预期

图3

5、反之,另一组字段,也符合第 3、4 步骤的验证结果。]]>
https://www.shuijingwanwq.com/2024/06/07/8628/feed/ 0
在 Laravel 6、Lighthouse 5 中,验证输入值的组合是否存在的实现 https://www.shuijingwanwq.com/2023/03/20/7503/ https://www.shuijingwanwq.com/2023/03/20/7503/#respond Mon, 20 Mar 2023 01:41:33 +0000 https://www.shuijingwanwq.com/?p=7503 浏览量: 71 1、在 GraphQL Schema 文件中定义如下


extend type Mutation {
    "取消发布主题(role 从 DEVELOPMENT 切换到 UNPUBLISHED)"
    onlineStoreThemeUnpublish(
        "待取消发布的主题ID"
        id: ID!
    ): ThemeUnpublishPayload @validator(class: "Modules\\OnlineStoreThemeGraphQl\\Validators\\UnpublishThemeValidator") @field(resolver: "Modules\\OnlineStoreThemeGraphQl\\Resolver\\Theme\\UnpublishThemeResolver") @guard
}


2、在自定义的验证器类 Validator Classes Modules\\OnlineStoreThemeGraphQl\\Validators\\UnpublishThemeValidator 中,代码实现如下
<pre class="wp-block-syntaxhighlighter-code">

<?php

namespace Modules\OnlineStoreThemeGraphQl\Validators;

use Nuwave\Lighthouse\Validation\Validator;
use Illuminate\Validation\Rule;
use Modules\ThemeStoreDb\Models\ThemeInstallation;

class UnpublishThemeValidator extends Validator
{
    /**
     * Return the validation rules.
     *
     * @return array<string, array<mixed>>
     */
    public function rules(): array
    {
        return [
            'id' => [
                Rule::exists('theme_installation', 'theme_id')->where(function ($query) {
                    $query->where('role', ThemeInstallation::ROLE_DEVELOPMENT);
                }),
            ],
        ];
    }
}


</pre>
3、请求验证失败,符合预期。如图1
请求验证失败,符合预期

图1



{
  "errors": [
    {
      "message": "Validation failed for the field [onlineStoreThemeUnpublish].",
      "extensions": {
        "validation": {
          "id": [
            "The selected id is invalid."
          ]
        },
        "category": "validation"
      },
      "locations": [
        {
          "line": 2,
          "column": 5
        }
      ],
      "path": [
        "onlineStoreThemeUnpublish"
      ],
      "trace": [
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Directives\\ArgTraversalDirective.php",
          "line": 27,
          "call": "Nuwave\\Lighthouse\\Validation\\ValidateDirective::Nuwave\\Lighthouse\\Validation\\{closure}(null, array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Directives\\ConvertEmptyStringsToNullDirective.php",
          "line": 48,
          "call": "Nuwave\\Lighthouse\\Schema\\Directives\\ArgTraversalDirective::Nuwave\\Lighthouse\\Schema\\Directives\\{closure}(null, array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Directives\\TrimDirective.php",
          "line": 54,
          "call": "Nuwave\\Lighthouse\\Schema\\Directives\\ConvertEmptyStringsToNullDirective::Nuwave\\Lighthouse\\Schema\\Directives\\{closure}(null, array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Factories\\FieldFactory.php",
          "line": 97,
          "call": "Nuwave\\Lighthouse\\Schema\\Directives\\TrimDirective::Nuwave\\Lighthouse\\Schema\\Directives\\{closure}(null, array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 623,
          "call": "Nuwave\\Lighthouse\\Schema\\Factories\\FieldFactory::Nuwave\\Lighthouse\\Schema\\Factories\\{closure}(null, array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 550,
          "call": "GraphQL\\Executor\\ReferenceExecutor::resolveFieldValueOrError(instance of GraphQL\\Type\\Definition\\FieldDefinition, instance of GraphQL\\Language\\AST\\FieldNode, instance of Closure, null, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 474,
          "call": "GraphQL\\Executor\\ReferenceExecutor::resolveField(GraphQLType: Mutation, null, instance of ArrayObject(1), array(1))"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 857,
          "call": "GraphQL\\Executor\\ReferenceExecutor::GraphQL\\Executor\\{closure}(array(0), 'onlineStoreThemeUnpublish')"
        },
        {
          "call": "GraphQL\\Executor\\ReferenceExecutor::GraphQL\\Executor\\{closure}(array(0), 'onlineStoreThemeUnpublish')"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 859,
          "function": "array_reduce(array(1), instance of Closure, array(0))"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 490,
          "call": "GraphQL\\Executor\\ReferenceExecutor::promiseReduce(array(1), instance of Closure, array(0))"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 263,
          "call": "GraphQL\\Executor\\ReferenceExecutor::executeFieldsSerially(GraphQLType: Mutation, null, array(0), instance of ArrayObject(1))"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 215,
          "call": "GraphQL\\Executor\\ReferenceExecutor::executeOperation(instance of GraphQL\\Language\\AST\\OperationDefinitionNode, null)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\Executor.php",
          "line": 156,
          "call": "GraphQL\\Executor\\ReferenceExecutor::doExecute()"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\GraphQL.php",
          "line": 162,
          "call": "GraphQL\\Executor\\Executor::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, instance of Nuwave\\Lighthouse\\Schema\\Context, array(1), 'UnpublishTheme', null)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\GraphQL.php",
          "line": 94,
          "call": "GraphQL\\GraphQL::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, instance of Nuwave\\Lighthouse\\Schema\\Context, array(1), 'UnpublishTheme', null, array(30))"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
          "line": 268,
          "call": "GraphQL\\GraphQL::executeQuery(instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, instance of Nuwave\\Lighthouse\\Schema\\Context, array(1), 'UnpublishTheme', null, array(30))"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
          "line": 203,
          "call": "Nuwave\\Lighthouse\\GraphQL::executeParsedQuery(instance of GraphQL\\Language\\AST\\DocumentNode, instance of Nuwave\\Lighthouse\\Schema\\Context, array(1), null, 'UnpublishTheme')"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
          "line": 162,
          "call": "Nuwave\\Lighthouse\\GraphQL::parseAndExecuteQuery('            mutation UnpublishTheme($id: ID!) {\n    onlineStoreThemeUnpublish(id: $id) {\n        theme {\n            id\n            name\n            role\n            createdAt\n        }\n    }\n}', instance of Nuwave\\Lighthouse\\Schema\\Context, array(1), null, 'UnpublishTheme')"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
          "line": 121,
          "call": "Nuwave\\Lighthouse\\GraphQL::executeOperation(instance of GraphQL\\Server\\OperationParams, instance of Nuwave\\Lighthouse\\Schema\\Context)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Utils.php",
          "line": 99,
          "call": "Nuwave\\Lighthouse\\GraphQL::Nuwave\\Lighthouse\\{closure}(instance of GraphQL\\Server\\OperationParams)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
          "line": 120,
          "call": "Nuwave\\Lighthouse\\Support\\Utils::mapEach(instance of Closure, instance of GraphQL\\Server\\OperationParams)"
        },
        {
          "file": "E:\\wwwroot\\object\\Modules\\OnlineStoreThemeGraphQl\\Controllers\\GraphQLController.php",
          "line": 39,
          "call": "Nuwave\\Lighthouse\\GraphQL::executeOperationOrOperations(instance of GraphQL\\Server\\OperationParams, instance of Nuwave\\Lighthouse\\Schema\\Context)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\ControllerDispatcher.php",
          "line": 48,
          "call": "Modules\\OnlineStoreThemeGraphQl\\Controllers\\GraphQLController::__invoke(instance of Illuminate\\Http\\Request, instance of Nuwave\\Lighthouse\\GraphQL, instance of Illuminate\\Events\\Dispatcher, instance of Laragraph\\Utils\\RequestParser, instance of Nuwave\\Lighthouse\\Execution\\SingleResponse, instance of Nuwave\\Lighthouse\\Execution\\ContextFactory)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php",
          "line": 219,
          "call": "Illuminate\\Routing\\ControllerDispatcher::dispatch(instance of Illuminate\\Routing\\Route, instance of Modules\\OnlineStoreThemeGraphQl\\Controllers\\GraphQLController, '__invoke')"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php",
          "line": 176,
          "call": "Illuminate\\Routing\\Route::runController()"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
          "line": 681,
          "call": "Illuminate\\Routing\\Route::run()"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 130,
          "call": "Illuminate\\Routing\\Router::Illuminate\\Routing\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\Modules\\OnlineStoreThemeGraphQl\\Middleware\\InjectStoreOptionsToConfigMiddleware.php",
          "line": 24,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Modules\\OnlineStoreThemeGraphQl\\Middleware\\InjectStoreOptionsToConfigMiddleware::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Http\\Middleware\\AttemptAuthentication.php",
          "line": 34,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Nuwave\\Lighthouse\\Support\\Http\\Middleware\\AttemptAuthentication::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Middleware\\ThrottleRequests.php",
          "line": 59,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Illuminate\\Routing\\Middleware\\ThrottleRequests::handle(instance of Illuminate\\Http\\Request, instance of Closure, 300, '1')"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Middleware\\SubstituteBindings.php",
          "line": 41,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Illuminate\\Routing\\Middleware\\SubstituteBindings::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Middleware\\ThrottleRequests.php",
          "line": 59,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Illuminate\\Routing\\Middleware\\ThrottleRequests::handle(instance of Illuminate\\Http\\Request, instance of Closure, 60, '1')"
        },
        {
          "file": "E:\\wwwroot\\object\\app\\Http\\Middleware\\ApiHeader.php",
          "line": 23,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "App\\Http\\Middleware\\ApiHeader::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Session\\Middleware\\StartSession.php",
          "line": 56,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Illuminate\\Session\\Middleware\\StartSession::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Cookie\\Middleware\\EncryptCookies.php",
          "line": 67,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\app\\Http\\Middleware\\EncryptCookies.php",
          "line": 30,
          "call": "Illuminate\\Cookie\\Middleware\\EncryptCookies::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "App\\Http\\Middleware\\EncryptCookies::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 105,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
          "line": 683,
          "call": "Illuminate\\Pipeline\\Pipeline::then(instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
          "line": 658,
          "call": "Illuminate\\Routing\\Router::runRouteWithinStack(instance of Illuminate\\Routing\\Route, instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
          "line": 624,
          "call": "Illuminate\\Routing\\Router::runRoute(instance of Illuminate\\Http\\Request, instance of Illuminate\\Routing\\Route)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
          "line": 613,
          "call": "Illuminate\\Routing\\Router::dispatchToRoute(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
          "line": 170,
          "call": "Illuminate\\Routing\\Router::dispatch(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 130,
          "call": "Illuminate\\Foundation\\Http\\Kernel::Illuminate\\Foundation\\Http\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\barryvdh\\laravel-debugbar\\src\\Middleware\\InjectDebugbar.php",
          "line": 67,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Barryvdh\\Debugbar\\Middleware\\InjectDebugbar::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\app\\Http\\Middleware\\ChangeAppUrlMiddleware.php",
          "line": 23,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "App\\Http\\Middleware\\ChangeAppUrlMiddleware::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
          "line": 21,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
          "line": 21,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize.php",
          "line": 27,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode.php",
          "line": 63,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\fideloper\\proxy\\src\\TrustProxies.php",
          "line": 57,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Fideloper\\Proxy\\TrustProxies::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\dingo\\api\\src\\Http\\Middleware\\Request.php",
          "line": 111,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Dingo\\Api\\Http\\Middleware\\Request::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 105,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
          "line": 145,
          "call": "Illuminate\\Pipeline\\Pipeline::then(instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
          "line": 110,
          "call": "Illuminate\\Foundation\\Http\\Kernel::sendRequestThroughRouter(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\public\\index.php",
          "line": 57,
          "call": "Illuminate\\Foundation\\Http\\Kernel::handle(instance of Illuminate\\Http\\Request)"
        }
      ]
    }
  ],
  "data": {
    "onlineStoreThemeUnpublish": null
  }
}


4、再次确认验证规则生成的 SQL,生成如下。如图2
再次确认验证规则生成的 SQL,生成如下

图2



select
  count(*) as aggregate
from
  `table`
where
  `theme_id` = '986c9d3e-206c-43c7-8e77-f166731a5df5'
  and (`role` = 'development')


]]>
https://www.shuijingwanwq.com/2023/03/20/7503/feed/ 0
在 Lighthouse 5 中,报错:Failed to find class Modules\\ThemeStore\\Validators\\ThemeAsset\\CreateThemeAssetInputValidator in namespaces [App\\GraphQL\\Validators] for directive @validator. https://www.shuijingwanwq.com/2022/06/28/6703/ https://www.shuijingwanwq.com/2022/06/28/6703/#respond Tue, 28 Jun 2022 01:17:22 +0000 https://www.shuijingwanwq.com/?p=6703 浏览量: 115 1、在 Lighthouse 5 中,报错:Failed to find class Modules\\ThemeStore\\Validators\\ThemeAsset\\CreateThemeAssetInputValidator in namespaces [App\\GraphQL\\Validators] for directive @validator.。如图1
在 Lighthouse 5 中,报错:Failed to find class Modules\\ThemeStore\\Validators\\ThemeAsset\\CreateThemeAssetInputValidator in namespaces [App\\GraphQL\\Validators] for directive @validator.

图1



PS E:\wwwroot\object> php artisan lighthouse:ide-helper
Wrote schema directive definitions to E:\wwwroot\object/schema-directives.graphql.

   Nuwave\Lighthouse\Exceptions\DefinitionException  : Failed to find class Modules\ThemeStore\Validators\ThemeAsset\CreateThemeAssetInputValidator in namespaces [App\GraphQL\Validators] for directive @validator.

  at E:\wwwroot\object\vendor\nuwave\lighthouse\src\Schema\Directives\BaseDirective.php:200
    196|         );
    197|
    198|         if (! $className) {
    199|             $consideredNamespaces = implode(', ', $namespacesToTry);
  > 200|             throw new DefinitionException(
    201|                 "Failed to find class {$classCandidate} in namespaces [{$consideredNamespaces}] for directive @{$this->name()}."
    202|             );
    203|         }
    204|

  Exception trace:

  1   Nuwave\Lighthouse\Schema\Directives\BaseDirective::namespaceClassName("Modules\ThemeStore\Validators\ThemeAsset\CreateThemeAssetInputValidator", Object(Closure))
      E:\wwwroot\object\vendor\nuwave\lighthouse\src\Validation\ValidatorDirective.php:151

  2   Nuwave\Lighthouse\Validation\ValidatorDirective::namespaceValidatorClass("Modules\ThemeStore\Validators\ThemeAsset\CreateThemeAssetInputValidator")
      E:\wwwroot\object\vendor\nuwave\lighthouse\src\Validation\ValidatorDirective.php:124

  Please use the argument -v to see more details.


2、确认类 Modules\\ThemeStore\\Validators\\ThemeAsset\\CreateThemeAssetInputValidator 已经迁移至 Modules\\ThemeStoreGraphQl\\Validators\\ThemeAsset\\CreateThemeAssetInputValidator 。如图2
确认类 Modules\\ThemeStore\\Validators\\ThemeAsset\\CreateThemeAssetInputValidator 已经迁移至 Modules\\ThemeStoreGraphQl\\Validators\\ThemeAsset\\CreateThemeAssetInputValidator

图2

3、在指令 @validator 中的类文件路径调整为:Modules\\ThemeStoreGraphQl\\Validators\\ThemeAsset\\CreateThemeAssetInputValidator 后,不再报错。


input ThemeAssetCreateInput @validator(class: "Modules\\ThemeStore\\Validators\\ThemeAsset\\CreateThemeAssetInputValidator") {
    "主题ID"
    themeId: String!,
    "内容"
    content: String!,
    "路径,相对于主题的路径,如 pages/index.blade.php"
    key: String!,
}


]]>
https://www.shuijingwanwq.com/2022/06/28/6703/feed/ 0
在 Laravel 6、Module、Lighthouse 中实现 安全 验证 的流程(使用验证器类来支持复杂的验证规则) https://www.shuijingwanwq.com/2022/03/25/6196/ https://www.shuijingwanwq.com/2022/03/25/6196/#respond Fri, 25 Mar 2022 01:16:13 +0000 https://www.shuijingwanwq.com/?p=6196 浏览量: 171

1、当请求响应成功时的结构。如图1

当请求响应成功时的结构。

图1



mutation {
  onlineStoreThemeAssetCreate(
    input: { themeId: "vogue", content: "string", key: "string" }
  ) {
    themeAsset {
      id
      themeId
      content
      key
      mimeType
      category
      schema
      createdAt
      updatedAt
      deletable
      renameable
      updatable
    }
  }
}




{
  "data": {
    "onlineStoreThemeAssetCreate": {
      "themeAsset": {
        "id": "653",
        "themeId": "vogue",
        "content": "string",
        "key": "string",
        "mimeType": "text/x-php",
        "category": "unknown",
        "schema": null,
        "createdAt": "2022-02-25 01:49:53",
        "updatedAt": "2022-02-25 01:49:53",
        "deletable": false,
        "renameable": false,
        "updatable": false
      }
    }
  }
}


2、但是,现阶段并未针对请求参数进行安全验证。参考:https://lighthouse-php.com/master/security/validation.html#single-arguments 。Lighthouse 允许您在查询和变更中使用 Laravel 的验证。如图2

但是,现阶段并未针对请求参数进行安全验证。参考:https://lighthouse-php.com/master/security/validation.html#single-arguments 。Lighthouse 允许您在查询和变更中使用 Laravel 的验证。

图2

3、此 GraphQL API 的变更虽然在输入对象中仅有 3 个参数,但是验证规则比较复杂。包含如下规则:
(1)验证表中是否存在 themeId: “vogue” 的记录,如果不存在,验证失败;


SELECT * FROM `object_store`.`theme_asset` WHERE `theme_id` = 'vogue' LIMIT 0,1


(2)验证 key: “string” 的格式,其必须为一个有效的相对路径,例:assets/iconfont/iconfont.css。其值等于 string ,验证失败;
(3)验证 key: “string” 的格式,其为一个有效的相对路径后,其文件后缀名必须属于一个预先定义的数组中,例:[‘json’, ‘css’, ‘js’];
(4)验证表中 themeId: “vogue”, key: “string” 记录的唯一性,如果已存在,验证失败;


SELECT * FROM `object_store`.`theme_asset` WHERE `theme_id` = 'vogue' AND `asset_key` = 'string' LIMIT 0,1


(5)验证 content: “string” 的格式,例:当 key 的值的文件后缀名为 .json 时,需要验证 content 的值格式为 json 格式;
(6)mime_type 的值需要基于 key 的值转换得出;
(7)category 的值需要基于 key 的值转换得出;

4、使用验证器类来支持复杂的验证规则。Lighthouse 对验证器类使用简单的命名约定,只需使用输入类型的名称并附加 Validator 。最终生成文件:/app/GraphQL/Validators/CreateOnlineStoreThemeAssetInputValidator.php


PS E:\wwwroot\lighthouse-tutorial> php artisan lighthouse:validator CreateOnlineStoreThemeAssetInputValidator
Validator created successfully.


5、由于现在需要在 Module ThemeStore 中使用此验证器类,将文件:/app/GraphQL/Validators/CreateOnlineStoreThemeAssetInputValidator.php 剪切至:/Modules/ThemeStore/Validators/CreateOnlineStoreThemeAssetInputValidator.php

<?php
 
namespace Modules\ThemeStore\Validators;
 
use Nuwave\Lighthouse\Validation\Validator;
 
class CreateOnlineStoreThemeAssetInputValidator extends Validator
{
    /**
     * Return the validation rules.
     *
     * @return array<string, array<mixed>>
     */
    public function rules(): array
    {
        return [
            'themeId' => [
                'exists:theme_asset,theme_id'
            ],
        ];
    }
}

6、编辑文件:/Modules/ThemeStore/Resources/graphql/theme_asset.graphql,修改输入对象,使用 @validator 指令,以指定验证器类


input OnlineStoreThemeAssetCreateInput @validator(class: "Modules\\ThemeStore\\Validators\\CreateOnlineStoreThemeAssetInputValidator") {
    "主题ID"
    themeId: String!,
    "内容"
    content: String!,
    "路径,相对于主题的路径,如 pages/index.blade.php"
    key: String!,
}


7、测试验证规则是否有效,确定有效。如图3

测试验证规则是否有效,确定有效。

图3



mutation {
  onlineStoreThemeAssetCreate(
    input: { themeId: "vogue1", content: "string", key: "string" }
  ) {
    themeAsset {
      id
      themeId
      content
      key
      mimeType
      category
      schema
      createdAt
      updatedAt
      deletable
      renameable
      updatable
    }
  }
}




{
  "errors": [
    {
      "message": "Validation failed for the field [onlineStoreThemeAssetCreate].",
      "extensions": {
        "validation": {
          "input.themeId": [
            "The selected input.theme id is invalid."
          ]
        },
        "category": "validation"
      },
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "onlineStoreThemeAssetCreate"
      ],
      "trace": [
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Directives\\ArgTraversalDirective.php",
          "line": 29,
          "call": "Nuwave\\Lighthouse\\Validation\\ValidateDirective::Nuwave\\Lighthouse\\Validation\\{closure}(null, array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Directives\\TrimDirective.php",
          "line": 56,
          "call": "Nuwave\\Lighthouse\\Schema\\Directives\\ArgTraversalDirective::Nuwave\\Lighthouse\\Schema\\Directives\\{closure}(null, array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Schema\\Factories\\FieldFactory.php",
          "line": 99,
          "call": "Nuwave\\Lighthouse\\Schema\\Directives\\TrimDirective::Nuwave\\Lighthouse\\Schema\\Directives\\{closure}(null, array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 623,
          "call": "Nuwave\\Lighthouse\\Schema\\Factories\\FieldFactory::Nuwave\\Lighthouse\\Schema\\Factories\\{closure}(null, array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 550,
          "call": "GraphQL\\Executor\\ReferenceExecutor::resolveFieldValueOrError(instance of GraphQL\\Type\\Definition\\FieldDefinition, instance of GraphQL\\Language\\AST\\FieldNode, instance of Closure, null, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 474,
          "call": "GraphQL\\Executor\\ReferenceExecutor::resolveField(GraphQLType: Mutation, null, instance of ArrayObject(1), array(1))"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 857,
          "call": "GraphQL\\Executor\\ReferenceExecutor::GraphQL\\Executor\\{closure}(array(0), 'onlineStoreThemeAssetCreate')"
        },
        {
          "call": "GraphQL\\Executor\\ReferenceExecutor::GraphQL\\Executor\\{closure}(array(0), 'onlineStoreThemeAssetCreate')"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 859,
          "function": "array_reduce(array(1), instance of Closure, array(0))"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 490,
          "call": "GraphQL\\Executor\\ReferenceExecutor::promiseReduce(array(1), instance of Closure, array(0))"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 263,
          "call": "GraphQL\\Executor\\ReferenceExecutor::executeFieldsSerially(GraphQLType: Mutation, null, array(0), instance of ArrayObject(1))"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\ReferenceExecutor.php",
          "line": 215,
          "call": "GraphQL\\Executor\\ReferenceExecutor::executeOperation(instance of GraphQL\\Language\\AST\\OperationDefinitionNode, null)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\Executor\\Executor.php",
          "line": 156,
          "call": "GraphQL\\Executor\\ReferenceExecutor::doExecute()"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\GraphQL.php",
          "line": 162,
          "call": "GraphQL\\Executor\\Executor::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\webonyx\\graphql-php\\src\\GraphQL.php",
          "line": 94,
          "call": "GraphQL\\GraphQL::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null, array(29))"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
          "line": 268,
          "call": "GraphQL\\GraphQL::executeQuery(instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null, array(29))"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
          "line": 203,
          "call": "Nuwave\\Lighthouse\\GraphQL::executeParsedQuery(instance of GraphQL\\Language\\AST\\DocumentNode, instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
          "line": 162,
          "call": "Nuwave\\Lighthouse\\GraphQL::parseAndExecuteQuery('mutation {\n  onlineStoreThemeAssetCreate(\n    input: { themeId: \"vogue1\", content: \"string\", key: \"string\" }\n  ) {\n    themeAsset {\n      id\n      themeId\n      content\n      key\n      mimeType\n      category\n      schema\n      createdAt\n      updatedAt\n      deletable\n      renameable\n      updatable\n    }\n  }\n}', instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
          "line": 121,
          "call": "Nuwave\\Lighthouse\\GraphQL::executeOperation(instance of GraphQL\\Server\\OperationParams, instance of Nuwave\\Lighthouse\\Schema\\Context)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Utils.php",
          "line": 99,
          "call": "Nuwave\\Lighthouse\\GraphQL::Nuwave\\Lighthouse\\{closure}(instance of GraphQL\\Server\\OperationParams)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\GraphQL.php",
          "line": 120,
          "call": "Nuwave\\Lighthouse\\Support\\Utils::applyEach(instance of Closure, instance of GraphQL\\Server\\OperationParams)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Http\\Controllers\\GraphQLController.php",
          "line": 32,
          "call": "Nuwave\\Lighthouse\\GraphQL::executeOperationOrOperations(instance of GraphQL\\Server\\OperationParams, instance of Nuwave\\Lighthouse\\Schema\\Context)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\ControllerDispatcher.php",
          "line": 48,
          "call": "Nuwave\\Lighthouse\\Support\\Http\\Controllers\\GraphQLController::__invoke(instance of Illuminate\\Http\\Request, instance of Nuwave\\Lighthouse\\GraphQL, instance of Illuminate\\Events\\Dispatcher, instance of Laragraph\\Utils\\RequestParser, instance of Nuwave\\Lighthouse\\Execution\\SingleResponse, instance of Nuwave\\Lighthouse\\Execution\\ContextFactory)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php",
          "line": 219,
          "call": "Illuminate\\Routing\\ControllerDispatcher::dispatch(instance of Illuminate\\Routing\\Route, instance of Nuwave\\Lighthouse\\Support\\Http\\Controllers\\GraphQLController, '__invoke')"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php",
          "line": 176,
          "call": "Illuminate\\Routing\\Route::runController()"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
          "line": 681,
          "call": "Illuminate\\Routing\\Route::run()"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 130,
          "call": "Illuminate\\Routing\\Router::Illuminate\\Routing\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Http\\Middleware\\AttemptAuthentication.php",
          "line": 34,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Nuwave\\Lighthouse\\Support\\Http\\Middleware\\AttemptAuthentication::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\nuwave\\lighthouse\\src\\Support\\Http\\Middleware\\AcceptJson.php",
          "line": 27,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Nuwave\\Lighthouse\\Support\\Http\\Middleware\\AcceptJson::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 105,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
          "line": 683,
          "call": "Illuminate\\Pipeline\\Pipeline::then(instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
          "line": 658,
          "call": "Illuminate\\Routing\\Router::runRouteWithinStack(instance of Illuminate\\Routing\\Route, instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
          "line": 624,
          "call": "Illuminate\\Routing\\Router::runRoute(instance of Illuminate\\Http\\Request, instance of Illuminate\\Routing\\Route)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
          "line": 613,
          "call": "Illuminate\\Routing\\Router::dispatchToRoute(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
          "line": 170,
          "call": "Illuminate\\Routing\\Router::dispatch(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 130,
          "call": "Illuminate\\Foundation\\Http\\Kernel::Illuminate\\Foundation\\Http\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\barryvdh\\laravel-debugbar\\src\\Middleware\\InjectDebugbar.php",
          "line": 67,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Barryvdh\\Debugbar\\Middleware\\InjectDebugbar::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\app\\Http\\Middleware\\ChangeAppUrlMiddleware.php",
          "line": 23,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "App\\Http\\Middleware\\ChangeAppUrlMiddleware::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
          "line": 21,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
          "line": 21,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize.php",
          "line": 27,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode.php",
          "line": 63,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\fideloper\\proxy\\src\\TrustProxies.php",
          "line": 57,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Fideloper\\Proxy\\TrustProxies::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\dingo\\api\\src\\Http\\Middleware\\Request.php",
          "line": 111,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 171,
          "call": "Dingo\\Api\\Http\\Middleware\\Request::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
          "line": 105,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
          "line": 145,
          "call": "Illuminate\\Pipeline\\Pipeline::then(instance of Closure)"
        },
        {
          "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
          "line": 110,
          "call": "Illuminate\\Foundation\\Http\\Kernel::sendRequestThroughRouter(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "E:\\wwwroot\\object\\public\\index.php",
          "line": 57,
          "call": "Illuminate\\Foundation\\Http\\Kernel::handle(instance of Illuminate\\Http\\Request)"
        }
      ]
    }
  ],
  "data": {
    "onlineStoreThemeAssetCreate": null
  }
}


8、查看 Laravel Telescope 中请求中的 SQL 语句。如图4

查看 Laravel Telescope 中请求中的 SQL 语句。

图4


select count(*) as aggregate from `theme_asset` where `theme_id` = 'vogue1'


]]>
https://www.shuijingwanwq.com/2022/03/25/6196/feed/ 0
Laravel 5.4 的表单验证,错误提示中的属性名调整为中文的实现 https://www.shuijingwanwq.com/2021/10/28/5417/ https://www.shuijingwanwq.com/2021/10/28/5417/#respond Thu, 28 Oct 2021 05:33:31 +0000 https://www.shuijingwanwq.com/?p=5417 浏览量: 94 1、Laravel 的表单验证,错误提示中存在英文,主要为验证的属性名:winning limit。如图1
Laravel 的表单验证,错误提示中存在英文,主要为验证的属性名:winning limit

图1



{
  "code": 10000,
  "message": "winning limit 必须是整数。",
  "data": []
}


2、查看 验证 代码如下


        $input = $request->json()->all();
        Arr::set($input, 'activity_id', $activityId);
        $factory = Container::getInstance()->make('validator');
        $validator = $factory->make($input, [
            'activity_id' => 'required|uuid|exists:activities,id',
            'prize_id' => 'required|uuid|exists:prizes,id',
            'winning_limit' => 'integer',
            'stock_limit' => 'numeric',
            'winning_probability' => 'numeric|between:0,1',
        ]);


3、参考网址:https://learnku.com/docs/laravel/5.4/validation/1234#42c1ed 。在语言文件中自定义属性。如果希望将验证消息的:attribute 部分替换为自定义属性名称,则可以在 resources/lang/xx/validation.php 语言文件的 attributes 数组中指定自定义名称。编辑:resources/lang/zh-CN/validation.php


    'attributes'           => [
		'winning_limit'         => '中奖限制',
    ],


4、Laravel 的表单验证,错误提示中的属性名:winning limit 已经被替换为:中奖限制。符合预期。如图2
Laravel 的表单验证,错误提示中的属性名:winning limit 已经被替换为:中奖限制。符合预期。

图2



{
  "code": 10000,
  "message": "中奖限制 必须是整数。",
  "data": []
}


 ]]>
https://www.shuijingwanwq.com/2021/10/28/5417/feed/ 0
在 Yii 2 中,当输入数据是通过网址时,为了避免执行冗余的更新SQL,给输入值应用一个过滤器(intval),进而导致衍生出的验证规则失效的分析解决 https://www.shuijingwanwq.com/2018/12/29/3082/ https://www.shuijingwanwq.com/2018/12/29/3082/#respond Sat, 29 Dec 2018 10:38:33 +0000 http://www.shuijingwanwq.com/?p=3082 浏览量: 111 1、在浏览器中打开网址:http://www.channel-pub-api-localhost.chinamcloud.com/weibo-oauth2/authorize-update?group_id=spider&channel_app_source_uuid=269f68bc098011e9b1c354ee75d2ebc1&user_name=华栖云1658397962&permission=4&status=1&redirect_uri=aHR0cDovL3d3dy56bXQuY29tLw%3D%3D ,此时验证规则生效,如图1
在浏览器中打开网址:http://www.channel-pub-api-localhost.chinamcloud.com/weibo-oauth2/authorize-update?group_id=spider&channel_app_source_uuid=269f68bc098011e9b1c354ee75d2ebc1&user_name=华栖云1658397962&permission=4&status=1&redirect_uri=aHR0cDovL3d3dy56bXQuY29tLw%3D%3D ,此时验证规则生效

图1

2、验证规则为:permission:可选,权限,1:同步;2:发布;3:同步与发布


            /* 更新微博的微连接的网页应用的用户 */
            [['permission'], 'in', 'range' => [self::PERMISSION_SYNC, self::PERMISSION_PUB, self::PERMISSION_SYNC_PUB], 'on' => self::SCENARIO_UPDATE],


3、此时数据库中 permission 的值为 2,updated_at 的值为 1545961613 ,如图2
此时数据库中 permission 的值为 2,updated_at 的值为 1545961613

图2

4、在浏览器中打开网址:http://www.channel-pub-api-localhost.chinamcloud.com/weibo-oauth2/authorize-update?group_id=spider&channel_app_source_uuid=269f68bc098011e9b1c354ee75d2ebc1&user_name=华栖云1658397962&permission=2&status=1&redirect_uri=aHR0cDovL3d3dy56bXQuY29tLw%3D%3D ,permission 的值为 2,由于 permission 字段为 SMALLINT(6) 类型,status 字段为 SMALLINT(6) 类型,而通过网址传递的参数为字符串类型,因此,即使 permission 与 status 的值未发生变化,仍然执行了更新 SQL,执行 SQL 语句如下:


UPDATE `cpa_weibo_weibo_connect_web_app_user` SET `permission`=2, `status`=1, `updated_at`=1546066986 WHERE `id`=17


5、调整验证规则,给输入值应用一个过滤器(intval)


            /* 更新微博的微连接的网页应用的用户 */
            [['permission'], 'in', 'range' => [self::PERMISSION_SYNC, self::PERMISSION_PUB, self::PERMISSION_SYNC_PUB], 'on' => self::SCENARIO_UPDATE],
			[['permission', 'status'], 'filter', 'filter' => 'intval', 'on' => self::SCENARIO_UPDATE],


6、在浏览器中打开网址:http://www.channel-pub-api-localhost.chinamcloud.com/weibo-oauth2/authorize-update?group_id=spider&channel_app_source_uuid=269f68bc098011e9b1c354ee75d2ebc1&user_name=华栖云1658397962&permission=&status=1&redirect_uri=aHR0cDovL3d3dy56bXQuY29tLw%3D%3D ,permission 的值为 空字符串,此时验证规则失效,permission 的值更新为 0,执行 SQL 语句如下:


UPDATE `cpa_weibo_weibo_connect_web_app_user` SET `permission`=0, `updated_at`=1546067544 WHERE `id`=17


7、调整验证规则,将过滤器(intval)置于最前


            /* 更新微博的微连接的网页应用的用户 */
			[['permission', 'status'], 'filter', 'filter' => 'intval', 'on' => self::SCENARIO_UPDATE],
            [['permission'], 'in', 'range' => [self::PERMISSION_SYNC, self::PERMISSION_PUB, self::PERMISSION_SYNC_PUB], 'on' => self::SCENARIO_UPDATE],


8、在浏览器中打开网址:http://www.channel-pub-api-localhost.chinamcloud.com/weibo-oauth2/authorize-update?group_id=spider&channel_app_source_uuid=269f68bc098011e9b1c354ee75d2ebc1&user_name=华栖云1658397962&permission=&status=1&redirect_uri=aHR0cDovL3d3dy56bXQuY29tLw%3D%3D ,permission 的值为 空字符串,此时验证规则生效,但是其值已经从字符串变化为 0,期望的是,当其值非“空值”时,才转换整数值,如图3
在浏览器中打开网址:http://www.channel-pub-api-localhost.chinamcloud.com/weibo-oauth2/authorize-update?group_id=spider&channel_app_source_uuid=269f68bc098011e9b1c354ee75d2ebc1&user_name=华栖云1658397962&permission=&status=1&redirect_uri=aHR0cDovL3d3dy56bXQuY29tLw%3D%3D ,permission 的值为 空字符串,此时验证规则生效,但是其值已经从字符串变化为 0,期望的是,当其值非“空值”时,才转换整数值

图3

9、默认情况下,当输入项为空字符串,空数组,或 null 时,会被视为“空值”。在 核心验证器 之中,filter(滤镜)验证器默认会处理空输入。调整 filter(滤镜)验证器,其 yii\base\Validator::skipOnEmpty 属性为 false,调整为 true


            /* 更新微博的微连接的网页应用的用户 */
			[['permission', 'status'], 'filter', 'filter' => 'intval', 'skipOnEmpty' => true, 'on' => self::SCENARIO_UPDATE],
            [['permission'], 'in', 'range' => [self::PERMISSION_SYNC, self::PERMISSION_PUB, self::PERMISSION_SYNC_PUB], 'on' => self::SCENARIO_UPDATE],


10、在浏览器中打开网址:http://www.channel-pub-api-localhost.chinamcloud.com/weibo-oauth2/authorize-update?group_id=spider&channel_app_source_uuid=269f68bc098011e9b1c354ee75d2ebc1&user_name=华栖云1658397962&permission=&status=1&redirect_uri=aHR0cDovL3d3dy56bXQuY29tLw%3D%3D ,permission 的值为 空字符串,此时验证规则生效,数据验证失败:权限不能为空。如图4
在浏览器中打开网址:http://www.channel-pub-api-localhost.chinamcloud.com/weibo-oauth2/authorize-update?group_id=spider&channel_app_source_uuid=269f68bc098011e9b1c354ee75d2ebc1&user_name=华栖云1658397962&permission=&status=1&redirect_uri=aHR0cDovL3d3dy56bXQuY29tLw%3D%3D ,permission 的值为 空字符串,此时验证规则生效,数据验证失败:权限不能为空。

图4

11、此时,2 条规则的顺序可以随意调整了,因为 2 条规则皆是在其值非“空值”时,才会执行验证,推荐置于最后,表示当验证通过后,才转为整数值


            /* 更新微博的微连接的网页应用的用户 */
            [['permission'], 'in', 'range' => [self::PERMISSION_SYNC, self::PERMISSION_PUB, self::PERMISSION_SYNC_PUB], 'on' => self::SCENARIO_UPDATE],
			[['permission', 'status'], 'filter', 'filter' => 'intval', 'skipOnEmpty' => true, 'on' => self::SCENARIO_UPDATE],


12、在浏览器中打开网址:http://www.channel-pub-api-localhost.chinamcloud.com/weibo-oauth2/authorize-update?group_id=spider&channel_app_source_uuid=269f68bc098011e9b1c354ee75d2ebc1&user_name=华栖云1658397962&permission=&status=1&redirect_uri=aHR0cDovL3d3dy56bXQuY29tLw%3D%3D ,permission 的值为 空字符串,此时验证规则生效,数据验证失败:权限不能为空。与步骤 10 的异常响应一致,符合预期  ]]>
https://www.shuijingwanwq.com/2018/12/29/3082/feed/ 0