2017-01-09 4 views
2

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 имеет амперсанд перед ним в объявлении функции? Обычно это означало бы, что вы проходили по ссылке, но не по умолчанию передавали объекты по ссылке?

ответ

1

Как вы можете видеть в Function arguments разделе документации PHP:

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

+0

http://pastebin.com/9M5nEheS похоже, что он передается со ссылкой на меня. – neubert

+0

Я отредактировал свой ответ, чтобы освещать «ссылку на объекты». :-) – Maxime

+0

Из любопытства, как вы думаете, вы могли бы придумать пример, где invokeMethod будет вести себя по-другому, когда амперсанд присутствует, а не когда нет? Это действительно помогло бы мне визуализировать это. Благодаря! – neubert

1

Мой вопрос ... есть конкретная причина, почему $ объект имеет амперсанд перед ним в объявление функции?

В этом фрагменте кода нет. $object используется только для его значения внутри этой функции. Только два места, где он используется, должны быть переданы в get_class() (который принимает свой аргумент по значению) и передается в ReflectionMethod::invokeArgs() (который также принимает свои аргументы по значению).

Следовательно, не было смысла принимать $object по ссылке.