【发布时间】:2013-08-24 01:42:17
【问题描述】:
这有点哲学,但我想很多人都遇到过这个问题。目标是访问 PHP 中的各种(动态声明的)属性,并在未设置通知时摆脱通知。
为什么不__get?
如果您可以声明自己的类,这是一个不错的选择,但不适用于stdClass、SimpleXML 或类似的情况。扩展它们不是一个选项,因为您通常不直接实例化这些类,它们是作为 JSON/XML 解析的结果返回的。
示例:
$data = '{"name": "Pavel", "job": "programmer"}';
$object = json_decode($data);
我们有简单的stdClass 对象。问题很明显:
$b = $data->birthday;
该属性未定义,因此发出通知:
PHP Notice: Undefined property: stdClass::$birthday
如果您认为您是通过解析某些 JSON 获得该对象,这种情况可能会经常发生。天真的解决方案很明显:
$b = isset($data->birthday) ? $data->birthday : null;
但是,将每个访问器都包装到其中时,很快就会感到疲倦。特别是在链接对象时,例如$data->people[0]->birthday->year。检查是否设置了people。检查是否设置了第一个元素。检查是否设置了birthday。检查是否设置了year。感觉有点过头了……
问题:
最后,我的问题来了。
解决这个问题的最佳方法是什么?使通知静音似乎不是最好的主意。并且检查每个属性是困难的。我见过一些解决方案,例如Symfony property access,但我认为它仍然是太多样板文件。有没有更简单的方法?第三方库、PHP 设置、C 扩展,我不在乎它的工作原理……还有哪些可能的陷阱?
【问题讨论】:
-
“但是,当将每个访问器都包装到其中时,人们很快就会感到疲倦。尤其是在链接对象时,例如 $data->people[0]->birthday->year。” 我不明白。即使
$data为空,您也可以安全地执行isset($data->people[0]->birthday->year),而不会产生任何副作用。 -
这是一个很好的观点,我没有意识到这一点。谢谢! (而且,还有更短的
$y = isset($x) ? $x : null; -
没有。如果您查看其他语言,PHP 实际上具有最短的形式。在 C 每个示例中,您必须手动检查每个子元素是否为 null。在 Python 中,您必须用
try..except块包围它。如果你真的想要更短,你总是可以写一个小的包装函数。 -
好吧,换行试试..except 会有所帮助。问题不是编写单个 isset() 而是一遍又一遍地重复它,在我/你的代码中重复 1000 倍。
-
你有没有考虑过Reflection class?,我的意思是你可以定义一个类作为模板,然后使用“反射”来检查你的对象。
标签: php properties isset boilerplate