在PHP 5.6中检查类数组常量中元素的存在性

10

我该如何检查常量元素像A\B::X['Y']['Z']是否已设置?

<?php

namespace A;

class B
{
    const X = [
        'Y' => [
            'Z' => 'value'
        ]
    ];
}

var_dump(defined('\A\B::X') && isset(\A\B::X['Y']['Z']));

致命错误:无法对表达式的结果使用isset()(您可以改用“null !== expression”)[...],位于第13行


isset - Federkun
@Rizier123 定义的(A\B::X)返回true,但定义的(A\B::X['Y']['Z'])返回false :( - user5483434
@Federico isset() 触发致命错误。 - user5483434
你能否发布代码,以便我们可以重现错误? - Federkun
@Federico,我刚刚更新了我的问题。 - user5483434
显示剩余5条评论
3个回答

14

isset 仅用于变量。您可以使用以下代码检查 A\B::X['Y']['Z'] 是否存在:

var_dump(
    defined('\A\B::X') &&
    array_key_exists('Y', \A\B::X) &&
    array_key_exists('Z', \A\B::X['Y'])
);

3
如果有人在想:isset 在 PHP 7 中可用于常量数组。似乎没有任何文件记录这一点。 - Ben Guest
很高兴知道,Ben Guest,谢谢。看起来isset在常量数组上不起作用似乎是不合逻辑的,因为它们显然被设置为了某些值。PHP团队最终解决了这个问题。 :) - Pontiac_CZ

5

由于isset仅适用于变量(我的错误),而不适用于任意表达式,因此您可以使用array_key_exists代替。

namespace A;

class B
{
    const X = [
        'Y' => [
            'Z' => 'value'
        ]
    ];
}

var_dump(array_key_exists('Y', \A\B::X) && array_key_exists('Z', \A\B::X['Y']));

1
顺便说一下,头像很不错。 :-) - Charlotte Dunois

0

你也可以简单地使用:

var_dump(@\A\B::X['Y']['Z'] !== NULL);

唯一的注意点是,如果您的const可能被定义为NULL,则无法使用它。
在这种情况下,您可以选择给const一个''(空字符串)值,在PHP中相当等效。

谢谢,但是根据我们公司的编码标准,STFU操作符不是一个选项。就个人而言,我也不喜欢使用它。 - user5483434
@user5483434 我知道这个问题有点像信仰。我同意建议小心使用它,但我坚决反对完全禁止它(在我看来是盲目的)。如果没有帮到你,很抱歉。 - cFreed
1
不要抱歉,兄弟。你的解决方案完全没有出现在我的脑海中,我真的很感谢你教给我这个方法。但根据我们的编码规则,在没有其他适合我们需求的解决方案之前,我们不应该使用那个运算符,但并不是所有情况下都禁止使用它。例如,在PDO构造函数中存在一个错误,唯一修复该错误的方法就是使用此运算符,在这种情况下我们是被允许使用的。实际上,虽然我们并没有完全禁止使用@运算符,但我们已经在我们的许多兆字节的PHP代码中使用了它来修复那个错误。 - user5483434
@user5483434,感谢你的澄清和美言。 - cFreed
目前,@ 错误控制运算符前缀甚至会禁用关键错误的错误报告,这些错误将终止脚本执行。这意味着,如果您使用 @ 来抑制某个函数的错误,并且该函数不可用或输入错误,脚本将在那里立即停止,而没有任何指示原因。 - Francesco Casula
@FrancescoCasula 我同意(显然,因为这只是PHP手册的摘录),但它确实属于我所谓的“有点像宗教”的范畴:在当前OP的情况下,不可能发生关键错误。因此,在这里使用它可以保持相当安全。 - cFreed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接