代码之家  ›  专栏  ›  技术社区  ›  Jan Richter

如何在PHP中以类型安全的方式处理用户输入

  •  0
  • Jan Richter  · 技术社区  · 5 年前

    我试图实现处理用户输入(源于JSON格式的HTTP请求),并使用PHP中的类将其分配到类型化属性中。

    假设我有一个JSON有效载荷,如下所示:

    {
      "foo": "bar",
      "baz": "qux"
    }
    

    但是 foo 可以为null,因此有效的有效载荷也是这样的:

    {
      "foo": null,
      "baz": "qux"
    }
    

    我们实际上是在处理HTTP PATCH 请求,这样的部分有效载荷也是有效的:

    {
      "baz": "qux"
    }
    

    因此,价值 foo 可以是: string , null 否则它将不存在。

    现在,当谈到为这个结构创建一个类时:

    class FooRequest
    {
        public ?string $foo;
        public string $bar;
    }
    

    这需要翻译成另一个 DTO 结构:

    class FooDTO
    {
        public ?string $foo;
    }
    

    因此,当我处理实际代码时,我使用 symfony/http-foundation 处理请求和响应。

    $request = Request::createFromGlobals();
    
    $fooPayload = new FooRequest();
    foreach ($request->toArray() as $propertyName => $value) {
        $fooPayload->$propertyName = $value;
    }
    

    所以 FooRequest 已正确分配所有数据。但当涉及到决定房产是否 无效的 ,值为 一串 或根本不提供,由财产决定 initialized , 无效的 一串 .

    Code example

    当我想采取下一步并将值分配给 DTO 类,我在PHP中看到的唯一合适的方法是使用 Reflection (我以前试过 property_exists isset ):

    $fooDTO = new FooDTO();
    $p = new ReflectionProperty(FooRequest::class, 'foo');
    if ($p->isInitialized($fooPayload)) {
        $fooDTO->foo = $fooPayload->foo;
    }
    

    所以基本上,我试图处理这3种可能的情况 foo PHP中的值使用类型安全的方式。我认为这不是最好(或最有效)的方法,因为每当我需要确定用户输入的这3种状态之一时,我都需要使用反射。

    你知道有什么更好的方法来处理这个问题吗?

    谢谢

    0 回复  |  直到 5 年前