Я топал вокруг механизма кастования PHP и столкнулся с нечетным случаем при создании массива как объекта
$o = (object) array('1'=>'/foo/bar'); $o = new stdClass(); var_dump($o);
Насколько я понимаю, свойства PHP должны быть объявлены с теми же правилами, что и переменные PHP. Это допустимое имя переменной начинается с буквы или подчеркивания, за которой следует любое количество букв, цифр или символов подчеркивания . Однако приведенный выше код дает следующий результат
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, или просто заблокирован для остальной части жизненного цикла запроса? (практическое использование этого – ноль, мне просто любопытно)
Да, они просто заперты, если они не вернутся к массиву. В PHP есть несколько небольших «Gotchas», например, в более старых версиях вы можете определить константу как массив, но затем никогда не обращаться к ее элементам. Даже сейчас вы можете определить константу как ресурс (например, define('MYSQL',mysql_connect());
) хотя это приводит к довольно непредсказуемому поведению и, опять же, следует избегать.
Как правило, лучше избегать приведения массива к объекту, если это вообще возможно. Если вам действительно нужно это сделать, подумайте о создании нового экземпляра stdClass
а затем вручную переименуйте все переменные, например, в _0
, _1
и т. Д.
$a = array('cat','dog','pheasant'); $o = new stdClass; foreach ($a as $k => $v) { if (is_numeric($k)) { $k = "_{$k}"; } $o->$k = $v; }
EDIT: Просто сделал еще один быстрый тест по этой гипотезе, и да, они официально «не существуют» в объектном контексте; данные сохраняются, но доступ к ним невозможно, и поэтому он является конечным частным пользователем. Вот тест:
$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];
Да, они просто заперты, если они не вернутся к массиву.
Возможно, свойства все еще существуют и доступны, а не напрямую. Тем не менее, я не уверен, как 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 )
Я думаю, вы получаете сообщение об ошибке, потому что приведение целочисленного ключа в массив к объекту / подобъекту приведет к нарушению соглашений об именах переменных var var.
Советы:
OBJECT
или ARRAY