2017-01-15 11 views
1

У меня есть 2 класса MyClass и MyClass2. Мне нужно вызвать новый экземпляр MyClass с помощью отражения, передав конструктору экземпляр MyClass2. Это отлично работает, пока я не попытаюсь использовать ссылку в конструкторе MyClass2, $classObject в этом случае будет null.Возвращаемый класс равен null, когда аргумент конструктора является ссылкой при использовании отражения php

Почему эта проблема возникает? Зная, что этого не происходит при тестировании аналогичного вызова функции между двумя функциями внутри одного класса без отражения !!

$className = 'MyClass'; 
$args = array(new MyClass2()); 
$classReflection = new ReflectionClass($className); 
$classObject = $classReflection->newInstanceArgs($args); 

MyClass

public function __construct(&$myClass2) 
+0

'classReflection' не имеет знака доллара в последней строке вашего первого блока кода. Это просто опечатка? –

+0

да @Simon, это опечатка здесь в этом вопросе, а не главная проблема – KAD

+2

Нужно ли это быть ссылкой в ​​первую очередь? Это не нужно делать, если вы передаете объект. Единственная разумная причина беспокоиться об этом, если «MyClass» - это устаревший сторонний код, который вы не можете коснуться ... – deceze

ответ

1

Прямое решение не изменять MyClass «s конструктор, так что больше не требуется ссылка:

public function __construct($myClass2) { } 

Как deceze отмечает в своем комментарии выше, нет вообще никакой необходимости передавать объекты по ссылке ; they are always passed by object identifier, который функционирует как указатель и гарантирует, что все переменные, которым назначен объект, действуют непосредственно на данные этого объекта.

Однако ваш пример иллюстрирует необычное поведение в PHP. Как vuliad says, ваш код, как написано не работает на PHP 7 с этим предупреждением:

PHP Warning: Parameter 1 to MyClass::__construct() expected to be a reference, value given 

Это удивительно, потому что the PHP manual says,

Since PHP 5, new returns a reference automatically...

Так $argsдолжен держать массив, содержащий ссылку, так как Конструктор MyClass ожидает. Но единственный способ, которым я могу получить исходный код для работы является первым назначением нового экземпляра MyClass2 переменной, например:

$newClass2 = new MyClass2(); 
$args = array(&$newClass2); 

$classReflection = new ReflectionClass($className); 
$classObject = $classReflection->newInstanceArgs($args); 

Это решение тоже. Но опять же, передача объектов по ссылке не требуется, поэтому я рекомендую просто изменить конструктор MyClass.

1

Вы можете сделать это с помощью аргументов распаковка:

$classObject = new $className(...$args); 

Это действительно интересный случай, для php7.0 + мы можем увидеть ошибки:

Warning: Parameter 1 to MyClass::__construct() expected to be a reference, value given in /in/Bgjlj on line 15

попробовать здесь https://3v4l.org/Bgjlj