2012-04-16 3 views
0

У меня есть пример сценария здесь с возвращением по эталонным волшебной __get:PHP Возврат по ссылке Разъяснение

class a{ 

    public $_attributes = array(); 

    function &__get($k){ 
     if(isset($this->_attributes[$k])){ 
      return $this->_attributes[$k]; 
     }else{ 
      return null; 
     } 
    } 

    function __set($k, $v){ 
     $this->_attributes[$k] = $v; 
    } 
} 


$a = new a(); 
$a->username = "sam"; 
var_dump($a->username); 
$u = $a->username; 
$u = $u.'dddd'; 
var_dump($a->username); 
var_dump($u); 

Идея возвращения по ссылке из моего __get здесь, так что я могу делать такие вещи, как:

$this->user->ins[session_id()] = array(
     "key"=>$_SESSION['server_key'], 
     "ip"=>$_SERVER['REMOTE_ADDR'], 
     "agent"=>$_SERVER['HTTP_USER_AGENT'], 
     "last_request"=>$_SERVER['REQUEST_URI'], 
     "last_active"=>new MongoDate(), 
    ); 

Поскольку я не могу нормально из-за PHP использовать копию исходного массива. Однако, когда я пытаюсь сказать «имя пользователя» в новую переменную ($ u), я не хочу, чтобы она передавала ссылку на ее исходный родитель.

Сценарий выше печатает:

string(3) "sam" string(3) "sam" string(7) "samdddd" 

который является удивительным это еще потому не проходит $ имя пользователя в качестве ссылки обратно $ и и она работает, как я хочу его.

Сейчас на этот вопрос: Это хороший подход? Ожидается ли поведение PHP в этом?

Я читал страницу для ссылок, но это немного неоднородно, однако упоминает, что для того, чтобы сказать PHP, что $ u должно быть ссылкой, я также должен использовать ссылочный символ при вытаскивании переменной (как можно видеть здесь: http://php.net/manual/en/language.references.return.php).

Итак, это ожидаемое поведение, и я могу полагаться на него на PHP или есть что-то ужасное, чего я не вижу?

Благодаря

ответ

1

Теперь время для вопроса: Является ли это хороший подход? Ожидается ли поведение в PHP?

Это плохой (нечетный) подход. Просто манипулируйте объектом, это более распространенная практика. То, как вы это делаете, сложно и может ввести вас в заблуждение во время разработки.

Если вы решите продолжить использование ссылочного подхода, вам необходимо убедиться, что вы получили значение по ссылке. Смотрите пример ниже:

$a = new a(); 
// returning by reference is not enough, you need to receive by ref as well 
$u =& $a->username; 
+0

regr спасибо за информацию :) – Sammaye

0

Вместо того, чтобы возвратить массив по ссылке, просто возвращает ArrayObject.

class Foo 
{ 
    private $data; 

    public function __construct() 
    { 
    $this->data = new ArrayObject(); 
    } 

    public function __get($key) 
    { 
    return $this->data; 
    } 
} 

$foo = new Foo(); 
$foo->data['bar'] = 42; 
var_dump($foo->data); 

Выход:

object(ArrayObject)#2 (1) { 
    ["storage":"ArrayObject":private]=> 
    array(1) { 
    ["bar"]=> 
    int(42) 
    } 
} 

К сожалению PHP ArrayObject s не может быть использован непосредственно с функциями массива PHP, но я предпочел бы выше над всегда возвращается __get по ссылке.

Вы можете сделать что-то подобное для скаляров, если вы помещаете их в объект, который реализует __toString(). И да, есть и недостатки в этом, но я всегда отказываюсь использовать __get по ссылке.

+0

Это будет работать в большинстве случаев без контекста, в котором я его использовал, и теперь, когда я смотрю на первый ответ, я думаю, что должен добавить контекст.Представьте, что вы создаете активную модель записи, поэтому вам нужны все функции активной записи, но ваше здание для NoSQL, что означает динамическую shcema, поэтому вы считаете, что вам нужен атрибут $ data, поскольку вы не можете просто сказать «получить поля», как в SQL. Отсюда и возник вопрос. Передача по ссылке в __get позволила мне манипулировать динамической схемой, подобной фактическому объекту, но также иметь все свои функции. – Sammaye

+0

Я имею в виду, что в качестве альтернативы вы можете разместить массив $ _fields, который содержит ключ => имя всех полей в динамическом объекте, и это является лучшим способом, поскольку вы можете манипулировать самим объектом при констатации динамического набора схемы, записанного имя переменной witin в массиве $ _fields. – Sammaye

Смежные вопросы