我在使用PHP对象属性名时遇到了一些麻烦,类似于数组键。
我的理解是数组键可以是任何字符串或整数,例如
$arr = array("crash-me" => "value");
是有效的键/值对。
现在,如果我将其“转换”为对象:
$obj = (object) $arr;
我做了一些非法的事情,因为钥匙串中有破折号吗?
一个简单的例子显示了我的困境:
<?php
error_reporting(-1);
$obj = new stdClass;
$prop = "crash-me";
$arr = array();
$obj->$prop = "no crash";
$obj->$prop = $arr; // bp here and $obj->$prop is correct
print_r($obj); // bp here, inspect $obj->$prop and... xdebug/php will crash.
exit;
当你在print_r()之前检查$ obj的值时,这将使用xdebug崩溃eclipse-pdt。
但是,如果没有bp,则会在退出时从print_r()正确打印内容。
stdClass Object ( [crash-me] => Array ( ) )
请注意,如果我在将属性分配给属性时将其填充到数组中,那么事情就可以了:
$obj = new stdClass;
$prop = "crash-me";
$arr = array("works_ok");
$obj->$prop = "no crash";
$obj->$prop = $arr;
print_r($obj);
exit;
从底线开始,我想使用带有破折号的属性名称以及可能与数组键类似的其他标点符号。可能吗?或者我通过分配一个空数组来做非法的事情,在这种情况下不会发现错误?
非常感谢您的善意考虑!
在编辑时,我忘记了另一部分拼图 - 下面的代码不会崩溃。在这种情况下,属性名称没有破折号,但是,数组键是空的!
$obj = new stdClass;
$prop = "crash_me"; // note underscore
$arr = array();
$obj->$prop = "no crash";
$obj->$prop = $arr; // bp here and $obj->$prop is correct
print_r($obj); // bp here, inspect $obj->$prop and... no crash!
exit;
抱歉这个混乱!这可能是我想念的东西。
第二次编辑 -
为了澄清,我希望从json_decode()中读取属性名称,只需使用对象而无需转换为数组。这是一个使用json数据文件中的键生成动态代码的实验。根据下面的讨论,看起来如果我想继续使用PHP,我需要$ arr ['key1'] ['key2'] ...语法并让解码器使用“array”标志。
感谢您的回复!
答案 0 :(得分:4)
我不确定xdebug是否存在非标准属性名称的任何问题,但您肯定不会希望有意使用这些属性名称。这没有意义。
如果您打算将对象用于OO目的,那么您将正式声明其属性。在这种情况下,使用“奇怪的”属性名称是不可能的,没有什么可说的了。
如果您不打算为OO使用对象,那么您最终会得到一个数组,您可以将$like->this
而不是$like['this']
编入索引。虽然第一种形式更短,我自己更喜欢它,但在使用属性$with->{'strange-names'}
时变得更加丑陋 - 实际上比数组访问更糟糕。再说一次,这样做没有任何好处。
在某些非常特殊的情况下,可能存在类似属性名称的情况 - 例如,如果对象使用其属性的名称作为数据库表中的列名。但即使在这种情况下,在PHP属性名称和数据库列名称之间添加转换层通常要方便得多,而不是在每一步都与语法作斗争。
奖金论点:如果看一眼this question不足以改变主意,那么什么都不会。这只是一个特定的角落案例,但我们正在谈论PHP。角落案件应该......避免。