使用数字键作为对象来投射数组

我正在围绕着PHP的投射机制,当把一个数组作为一个对象时,遇到了一个奇怪的情况

$o = (object) array('1'=>'/foo/bar'); $o = new stdClass(); var_dump($o); 

据我了解,PHP属性需要用与PHPvariables相同的规则来声明。 这是一个有效的variables名称,以字母或下划线开头,后面跟着任意数量的字母,数字或下划线 。 但是,上面的代码产生以下输出

 object(stdClass)#1 (1) { [1]=> string(8) "/foo/bar" } 

当你尝试访问对象中的信息的时候,它变得非常奇怪。

 var_dump($o->1); // parse error var_dump($o->{'1'}); // NULL var_dump(get_object_vars($o)); //array(0) { } 

无论如何,要获取var_dump报告在对象中的信息,还是仅仅locking了请求生命周期的其余部分? (实际使用这个是零,我只是好奇)

是的,他们只是locking,除非重新回到arrays。 PHP中有一些小问题,比如在老版本中,你可以定义一个常量作为数组,但是不能访问它的元素。 即使现在你可以定义一个常量作为一个资源(例如, define('MYSQL',mysql_connect()); ),尽pipe这导致相当不可预知的行为,并且应该避免。

一般来说,最好尽可能避免数组到对象的转换。 如果您确实需要这样做,请考虑创build一个stdClass的新实例,然后手动重命名所有variables,例如_0_1等。

 $a = array('cat','dog','pheasant'); $o = new stdClass; foreach ($a as $k => $v) { if (is_numeric($k)) { $k = "_{$k}"; } $o->$k = $v; } 

编辑:只是做了一个更快速的testing这个假设,是的,他们正式“不存在”的对象上下文; 数据被存储,但不可能访问,因此是最终的私人成员。 这是testing:

 $a = array('one','two','three'); $o = (object)$a; var_dump(property_exists($o, 1), property_exists($o, '1')); 

输出是:

 bool(false) bool(false) 

再次编辑:有趣的一面,下面的操作返回false:

 $a = array('one','two','three','banana' => 'lime'); $b = array('one','two','banana' => 'lime'); $y = (object)$a; $z = (object)$b; var_dump($y == $z); 

看来ArrayObject类可以访问属性

 $a = new ArrayObject($obj); echo $a[0]; 

是的,他们只是locking,除非重新回到arrays。

也许,属性仍然存在,可以访问,只是不直接。 但是,我不确定foreach是如何在内部工作的(它可能会将对象转换为数组),因为我没有在源代码中进行调用。

例:

 $array = array('one', 'two', 'three', 'four'); $obj = (object) $array; foreach ($obj as $key => &$val) { print "$key -> $val<br>"; $val = 'Nhaca'; var_dump($obj); } print_r($obj); print_r($array); 

输出:

 0 -> one object(stdClass)[1] &string 'Nhaca' (length=5) string 'two' (length=3) string 'three' (length=5) string 'four' (length=4) 1 -> two object(stdClass)[1] string 'Nhaca' (length=5) &string 'Nhaca' (length=5) string 'three' (length=5) string 'four' (length=4) 2 -> three object(stdClass)[1] string 'Nhaca' (length=5) string 'Nhaca' (length=5) &string 'Nhaca' (length=5) string 'four' (length=4) 3 -> four object(stdClass)[1] string 'Nhaca' (length=5) string 'Nhaca' (length=5) string 'Nhaca' (length=5) &string 'Nhaca' (length=5) stdClass Object ( [0] => Nhaca [1] => Nhaca [2] => Nhaca [3] => Nhaca ) Array ( [0] => one [1] => two [2] => three [3] => four ) 

我想你会得到一个错误,因为将数组的整数键转换为对象/子对象将会破坏PHPvariables的命名约定。

提示:

  • 决定是否要有OBJECTARRAY
  • 注意types转换(例如(object)数组(1 =>'string')不要做这样的事情)
  • 使用铸件validation,而不是转换的东西
  • 避免使用对象作为“假”数组