首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP7.4类型属性迭代

PHP7.4类型属性迭代
EN

Stack Overflow用户
提问于 2020-03-29 12:47:25
回答 4查看 5.5K关注 0票数 9

我刚刚在PHP7.4中发现了一些“有点奇怪”的地方,我不确定是我遗漏了什么,还是可能是一个实际的bug。主要是我对你的意见/确认感兴趣。

因此,在PHP中,您可以迭代对象属性如下:

代码语言:javascript
复制
class DragonBallClass 
{
    public $goku;
    public $bulma = 'Bulma';
    public $vegeta = 'Vegeta';
}

$dragonBall = new DragonBallClass();

foreach ($dragonBall as $character) {
  var_dump($character);

}

RESULT

NULL
string(5) "Bulma"
string(6) "Vegeta"

现在,如果我们开始使用这样的强类型属性:

代码语言:javascript
复制
class DragonBallClass 
{
    public string $goku;
    public string $bulma = 'Bulma';
    public string $vegeta = 'Vegeta';
}

$dragonBall = new DragonBallClass();

foreach ($dragonBall as $character) {
  var_dump($character);

}

我们会得到一个不同的结果:

代码语言:javascript
复制
string(5) "Bulma"
string(6) "Vegeta"

现在不同的是:

当您不为强类型属性分配默认值时,它将是Uninitialized类型的。这当然有道理。但问题是,如果它们以这种方式结束,您就不能简单地循环它们--没有错误,也没有您在第二个示例中看到的任何东西。所以我就失去了接近他们的机会。

这很有意义,但是想象一下,您有一个自定义的请求/数据类,如下所示:

代码语言:javascript
复制
namespace App\Request\Request\Post;

use App\Request\Request\Request;

class GetPostsRequest extends Request
{
    public string $title = '';
}

你看到那个难看的字符串作业了吗?如果我想使类上的属性可迭代,那么我必须这样做:

  • 跌落类型
  • 赋值

我可能希望有一个具有类型化属性的对象,其中没有任何值,如果有意义的话,可以对它们进行循环并填充它们。

有什么更好的方法吗?是否有任何选项可以保持类型并保持它们的可迭代性,而不必执行这个虚拟值可憎的操作?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-03-29 12:56:24

如果希望允许类型化属性为空,只需在类型之前添加一个?,并将NULL作为默认值,如下所示:

代码语言:javascript
复制
class DragonBallClass 
{
    public ?string $goku = NULL;
    public string $bulma = 'Bulma';
    public string $vegeta = 'Vegeta';
}

在这种情况下,NULL是一个完全合法的值(而不是虚拟值)。

演示

此外,如果不使用?,则始终可以将类属性与对象属性列表合并:

代码语言:javascript
复制
class DragonBallClass 
{
    public string $goku;
    public string $bulma = 'Bulma';
    public string $vegeta = 'Vegeta';
}

$dragonBall = new DragonBallClass();

$classProperties = get_class_vars(get_class($dragonBall));
$objectProperties = get_object_vars($dragonBall);

var_dump(array_merge($classProperties, $objectProperties));

// array(3) {
//  ["goku"]=>
//  NULL
//  ["bulma"]=>
//  string(5) "Bulma"
//  ["vegeta"]=>
//  string(6) "Vegeta"
// }
票数 10
EN

Stack Overflow用户

发布于 2020-03-29 14:25:04

在我们开始之前,我认为我接受并由Casimir提供的答案比我想出的更好、更正确(这也适用于评论)。

我只是想分享一下我的想法,因为这在某种程度上是一个可行的解决方案,至少我们可以称之为答案。

这是我为我的特殊需要而想出来的,只是为了好玩。我很好奇我能做些什么,使它更符合我想要的方式,所以不要被它吓坏了;P我认为这是一个相当干净的解决方法--我知道这并不完美。

代码语言:javascript
复制
class MyRequest
{
    public function __construct()
    {    
        $reflectedProperties = (new \ReflectionClass($this))->getProperties();
        foreach ($reflectedProperties as $property) {
            !$property->isInitialized($this) ??
            $property->getType()->allowsNull() ? $property->setValue($this, null) : null;
        }
    }

}


class PostRequest extends MyRequest 
{
    public ?string $title;

}

$postRequest = new PostRequest();

// works fine - I have access here!
foreach($postRequest as $property) {
    var_dump($property);
}

此解决方案的缺点是,您必须始终使类型在类中为空。,然而,对于我和我的具体需要,,这是完全可以的。我不介意,不管怎么说,他们最终都会变成空档,如果有人赶时间的话,这可能是一个很好的解决短期期限问题的办法。

当类型不可为空时,它仍然保留原始PHP未初始化的错误。我觉得现在还挺酷的。您可以保留所有的东西:瘦类、PHP错误,表明问题的真正本质,如果您同意让类型化属性保持为空,就有可能对它们进行循环。所有这些都由本机PHP 7可空运算符管理。

当然,如果这有任何意义的话,这可以更改或扩展到更特定的类型。

票数 2
EN

Stack Overflow用户

发布于 2020-07-02 10:12:56

更新:这个答案可能过时了,但是注释包含了一个有趣的讨论。

@Robert的解决办法是有缺陷的;在这部分:

代码语言:javascript
复制
        foreach ($reflectedProperties as $property) {
            !$property->isInitialized($this) ??
            $property->getType()->allowsNull() ? $property->setValue($this, null) : null;
        }

必须将??更正为&&

此外,这是对三元条件的误用;只需使用经典的if

代码语言:javascript
复制
        foreach ($reflectedProperties as $property) {
            if (!$property->isInitialized($this)
                && $property->getType()->allowsNull()
            ) {
                $property->setValue($this, null);
            }
        }

或者:

代码语言:javascript
复制
        foreach ($reflectedProperties as $property) {
            if (!$property->isInitialized($this) && $property->getType()->allowsNull()) {
                $property->setValue($this, null);
            }
        }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60914497

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档