2012-02-24 2 views
0

Я думаю, что это довольно простой вопрос, но не уверен.PHP __set переменная while __get проходит по ссылке

У меня есть класс:

<?PHP 
class PropertyTest { 
    private $data = array(); 

    public function __set($name, $value) { 
     $this->data[$name] = $value; 
    } 

    public function __get($name) { 
     if (array_key_exists($name, $this->data)) { 
      return $this->data[$name]; 
     } 

     $trace = debug_backtrace(); 
     trigger_error(
      'Undefined property via __get(): ' . $name . 
       ' in ' . $trace[0]['file'] . 
       ' on line ' . $trace[0]['line'], 
      E_USER_NOTICE); 
     return null; 
    } 

    public function __isset($name) { 
     echo "Is '$name' set?\n"; 
     return isset($this->data[$name]); 
    } 

    public function __unset($name) { 
     echo "Unsetting '$name'\n"; 
     unset($this->data[$name]); 
    } 

    public function getHidden() { 
     return $this->hidden; 
    } 
} 
?> 

Не знаю почему, но блок «код» раздражает, как ад, так или иначе.

Просто базовая магическая установка действительно установлена. Но когда я изменяю __get пройти по ссылке, я не могу больше этого делать:

$object->$variableName = $variableValue; 

Я не знаю, почему, хотя я предполагаю, потому что он проверяет, если он существует, но так как она должна вернуть то, что по ссылке это не получится для этого, если этого не существует для начала. Функция set не будет называться, вероятно, и даже если я верну свое поддельное значение, она никогда не вызовет функцию set, потому что она уже существует/имеет значение.

Я правильно понимаю это? Если да, есть ли работа? Если нет, то как это работает и есть ли обходной путь?

+0

Можете ли вы показать нам, в какой части вы пытаетесь перейти на передачу по ссылке? Я становлюсь фатальным при настройке аргумента на такой ** PHP Fatal error: Method PropertyTest :: __ get() не может принимать аргументы по ссылке ** – quickshiftin

+0

public function & __ get ($ name) { – John

ответ

0

Если я что-то он работает нормально для меня

<?php 
class PropertyTest 
{ 

    private $data = array(); 

    public function __set($name, $value) 
    { 
     $this->data[$name] = $value; 
    } 

    public function &__get($name) 
    { 
     if(array_key_exists($name, $this->data)) 
      return $this->data[$name]; 
     return null; 
    } 

    public function __isset($name) 
    { 
     return isset($this->data[$name]); 
    } 

    public function __unset($name) 
    { 
     unset($this->data[$name]); 
    } 

    public function getHidden() 
    { 
     return $this->hidden; 
    } 
} 

$oPropTest = new PropertyTest(); 
$sField = 'my-field'; 

$oPropTest->$sField = 5; 

var_dump($oPropTest); 

выходов отсутствует:

bash-3.2$ php test-get-set.php 
object(PropertyTest)#1 (1) { 
    ["data":"PropertyTest":private]=> 
    array(1) { 
    ["my-field"]=> 
    int(5) 
    } 
} 

Один твик я хотел бы предложить для __get реализации является использование метода __isset скорее чем повторная реализация проверки (делает это 2 разных способа, как вы)

public function __get($name) 
{ 
    if($this->__isset($name)) 
     return $this->data[$name]; 
    return null; 
} 

Что касается идеи возврата по ссылке от __get; он будет работать, но будет бесполезен ни на чем, кроме публичных атрибутов, поскольку частные и защищенные атрибуты не будут устанавливаться непосредственно через ссылку вне области класса.

$oPropTest = new PropertyTest(); 
$sField = 'my-field'; 

$oPropTest->$sField = 5;  // sets $oPropTest->my-field to 5 (effectively) 
$iRef = $oPropTest->$sField; // $iRef is a reference to $oPropTest->my-field 
$iRef = 6;     // this will not set $oPropTest->my-field since it's private 
Смежные вопросы