简体   繁体   English

PHP参考归还澄清

[英]PHP Return by Reference Clarification

I have an example script here with a return by reference magic __get: 我在这里有一个示例脚本,其中包含引用魔术__get的返回:

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);

The idea of returning by reference from my __get here is so I can do stuff like: 从我的__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(),
    );

Since I cannot normally due to PHP using a copy of the original array. 因为我通常不能由于PHP使用原始数组的副本。 However When I pull say "username" into a new variable ($u) I do not want it to pass a reference of its original parent. 但是,当我说“用户名”到新变量($ u)中时,我不希望它传递其原始父项的引用。

The script above prints out: 上面的脚本输出:

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

Which is awesome becasue it is not passing $username as reference back to $u and it works like I want it to. 这很棒,因为它没有将$ username作为参考传递回$ u,并且它的工作方式就像我想要的那样。

Now time for the question: Is this a good approach? 现在该问问题了:这是一个好方法吗? Is it expected behaviour in PHP to do this? 这是PHP的预期行为吗?

I have been reading the page for referencing but it's a bit patchy, however it does mention that to tell PHP that $u should be a reference I must also use the reference symbol when pulling out the variable (as can be seen here: http://php.net/manual/en/language.references.return.php ). 我一直在阅读该页面以进行引用,但是有点不完整,但是它确实提到要告诉PHP $ u应该是一个引用,在取出变量时也必须使用引用符号(如此处所示: http: //php.net/manual/en/language.references.return.php )。

So is this expected behaviour and can I rely on it in PHP or is there something terrible I'm not seeing? 那么,这是预期的行为吗?我可以在PHP中依靠它吗?还是我没有看到可怕的东西?

Thanks 谢谢

Now time for the question: Is this a good approach? 现在该问问题了:这是一个好方法吗? Is it expected behaviour in PHP to do this? 这是PHP的预期行为吗?

This is a bad (odd) approach. 这是一种不好的方法。 Simply manipulate the object, this is more common practice. 简单地操纵对象,这是更常见的做法。 The way you have it is tricky and can mislead you during development. 拥有它的方式很棘手,在开发过程中可能会误导您。

If you decide to continue with your reference approach, you need to make sure you received the value by reference. 如果决定继续使用参考方法,则需要确保已通过参考获得了该值。 See sample below: 请参阅以下示例:

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

Instead of returning an array by reference, just return an ArrayObject . 而不是通过引用返回数组,只需返回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);

Output: 输出:

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

Unfortunately PHP ArrayObject s cannot be used directly with PHP array functions, but I would prefer the above over always returning __get by reference. 不幸的是,PHP ArrayObject不能直接与PHP数组函数一起使用,但是我宁愿上面的方法而不是总是通过引用返回__get

You can do something similar for scalars if you box them in an object that implements __toString() . 如果将标量装在实现__toString()的对象中,则可以对标量执行类似的操作。 And yes, there are flaws with this as well, but I would always discourage using __get by reference. 是的,这样做也有缺陷,但是我总是不鼓励使用__get引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM