Преобразование объекта в массив и обратно

php_coder

Новичок
Привет всем.
У меня вопросик по преобразованию объекта в массив и обратно: почему из массива, созданного "вручную", нельзя создать private-член класса в объекте?

PHP:
<?php
  class cls
  {
    public prop1 = 'a';
    private prop2 = 'b';
  }

  $obj = new cls();
  $objArr = (array)$obj;
  $obj2 = (object)$objArr;

//дамп. Здесь всё отлично. Объект правильно восстанавливается из массива.
  echo '<pre>';
  print_r($obj2);
  echo '</pre>';


  $arr = array('prop1'=>'a', 'prop2:cls:private'=>'b');
  $obj3 = (object)$arr;

//дамп. А вот тут валится ошибка. Не может Private-член создать. Почему?
  echo '<pre>';
  print_r($obj3);
  echo '</pre>';
?>
 

php_coder

Новичок
2 AmdY, спасибо за ответы. Я хочу массив преобразовать в объект с private-членами/методами, а не работать с объектом как с массивом.
 

php_coder

Новичок
PHP:
<?php
$arr = array('prop1'=>'a', 'prop2:cls:private'=>'b');
  $obj3 = (object)$arr;

//дамп.
  echo '<pre>';
  print_r($obj3);
  echo '</pre>';
  
  /** выводит:
	stdClass Object
	(
	[prop1] => a
	[prop2:private] => b
	)
*/
  
  echo $obj3->prop1;//выводит: a
  echo '<br />';
  echo $obj3->prop2;//выводит: Notice: Undefined property: stdClass::$prop2 in F:\web\oop\02_objectsAndClasses\noname1.php on line 37 
?>
 

Baton

Новичок
В вашем исходнике есть синтаксические ошибки, но это не так важно.

Вы бы лучше проверили тип `восстановленных` объектов.

PHP:
<?php
  class cls
  {
    public $prop1 = 'a';
    private $prop2 = 'b';
  }

  $obj = new cls();
  
  if( $obj instanceof cls ){ 
     echo '$obj instanceof cls<br>';
  }
  
  $objArr = (array)$obj;
  $obj2 = (object)$objArr;
  
  //false
  if( $obj2 instanceof cls ){ 
     echo '$obj2 instanceof cls<br>';
  }
  
  //true
  if( $obj2 instanceof stdClass ){ 
     echo '$obj2 instanceof stdClass<br>';
  }
  
  //stdClass
  echo get_class( $obj2 );

  //cls Object
  echo '<pre>';
  print_r($obj);
  echo '</pre>';  
  
  //stdClass Object
  echo '<pre>';
  print_r($obj2);
  echo '</pre>';  
  
?>
Так что насчет правильного восстановления Вы погорячились.
 

Baton

Новичок
А если вот так попробовать, ни на какие мысли не наводит? :)

PHP:
<?php
  class cls
  {
    public $prop1 = 'a';
    private $prop2 = 'b';
  }

  $obj = new cls();
  
  echo $obj->$prop2;
?>
 

php_coder

Новичок
2 Baton. Спасибо за ответ. На счёт "вы погорячились" - не понял.
После преобразования из массива объект является экземпляром стандартного класса (stdClass).
Меня интересует почему Public-члены "восстанавливаются", а private - нет?

PHP:
<?php
class cls
  {
	public $prop1 = 'a';
	private $prop2 = 'b';
  }

  $obj = new cls();
  $objArr = (array)$obj;
  $obj2 = (object)$objArr;
  echo $obj2->prop1;  //выводит: a
  echo $obj2->prop2;  //выводит:Notice: Undefined property: stdClass::$prop2 in F:\web\oop\02_objectsAndClasses\noname1.php on line 12
?>
 

php_coder

Новичок
При обращении к private-члену будет такая ошибка: "Fatal error: Cannot access private property", а не "Undefined property".
 

Baton

Новичок
Потому, что свойство cls::$prop2 объявлено как закрытый. Доступ к нему возможен только внутри любого метода класса cls.
 

Baton

Новичок
Наверняка в преобразуемом Вами классе был геттер к $prop2, но после преобразования он исчез :)

PHP:
<?php
class cls
  {
    public $prop1 = 'a';
    private $prop2 = 'b';
    public function getProp2(){
       return $this->prop2;
    }
  }

  $obj = new cls();
  //b
  echo $obj->getProp2();
  $objArr = (array)$obj;  
  $obj2 = (object)$objArr;  
  echo $obj2->prop1;  
  // Fatal error: Call to undefined method stdClass::getProp2() in W:\WWW\test\public\test2.php on line 16
  echo $obj2->getProp2();
?>
 

php_coder

Новичок
Можно ли сделать так, чтобы при "восстановлении" объекта из массива, восстанавливался и спецификатор "private" члена объекта?
 

Baton

Новичок
Так он и восстанавливается, только получить доступ к нему можно только из любого метода класса, а Вы пытаетесь получить доступ из глобального контекста.

ЗЫ: все я больше в дискуссии не участвую.
 

php_coder

Новичок
То есть по этому признаку ты определяешь имеется свойство или нет?
Да, именно так. Сообщения интерпретатора об обшибках - это понятные человеку сообщения.
А по-человечески не пробовал?
"По человечески" - это как?
 

С.

Продвинутый новичок
Да, именно так. Сообщения интерпретатора об обшибках - это понятные человеку сообщения.
А-а-а... То-то ты за разъясниями сюда обратился.
"По человечески" - это как?
Так, как положено обращаться к приватному свойству.
 
Сверху