使用反射

时间:2017-01-09 01:19:25

标签: php reflection pass-by-reference

This article有以下方法:

/**
 * Call protected/private method of a class.
 *
 * @param object &$object    Instantiated object that we will run method on.
 * @param string $methodName Method name to call
 * @param array  $parameters Array of parameters to pass into method.
 *
 * @return mixed Method return.
 */
public function invokeMethod(&$object, $methodName, array $parameters = array())
{
    $reflection = new \ReflectionClass(get_class($object));
    $method = $reflection->getMethod($methodName);
    $method->setAccessible(true);

    return $method->invokeArgs($object, $parameters);
}

我的问题是......为什么$object在函数声明中有&符号之前有特殊原因?通常情况下,这意味着你是通过引用传递的,但是默认情况下,PHP会通过引用传递对象吗?

2 个答案:

答案 0 :(得分:2)

  

我的问题是...... $ object有一个特殊的原因   在函数声明中它之前的&符号?

在这段代码中,$object仅用于此函数内的值。使用它的唯一两个地方是传递给get_class()(它通过值获取其参数),并传递给ReflectionMethod::invokeArgs()(它也通过值获取其参数)。

因此,没有必要参考$object

答案 1 :(得分:1)

正如您在PHP文档的Function arguments部分所见:

  

PHP支持按值传递参数(默认值),传递引用和默认参数值。还支持可变长度参数列表。

默认情况下,参数按值传递。

至于对象,似乎它们是通过引用传递的,但这并非完全正确。请参阅Objects and references说明:

  

PHP引用是一个别名,它允许两个不同的变量写入相同的值。从PHP 5开始,对象变量不再包含对象本身作为值。它只包含一个对象标识符,它允许对象访问者查找实际对象。当一个对象通过参数发送,返回或分配给另一个变量时,不同的变量不是别名:它们包含标识符的副本,它指向同一个对象。

因此,为了避免混淆,我总是假设参数不是通过值传递的,即使是对象也是如此。如果您希望通过引用传递它,请添加&以确保您确实通过引用传递它。

以下是对象的示例:

<?php

// Passed by value... won't be affected
function byValue($arg) { 
  $arg = null;
} 

// Passed by reference... will be affected
function byReference(&$arg) { 
  $arg = null;
} 

$obj = new StdClass;
var_dump($obj);  // Untouched object created

byValue($obj);
var_dump($obj);  // After 'trying' to set it to null

byReference($obj);
var_dump($obj);  // After setting it to null for real

Run demo