php 7 - PHP7. Reflection doesn't work from old versions php -


i have php script written on php 5.6.19, works on 5.3 version to, installed addons.

i decide try execute on php7.

the special of script initializing class parameter reference via creating new instance reflection::class. , there warning waited variable reference value received.

definition of class' constructor method tried create instance from:

public function __construct($user, idatabase &$repository, $errors = null); 

sample of code constructor used:

// define manager type create (all managers has same constructor) $manager = $managersnamespace . ucfirst($this->_manager) . "manager"; // trying create manager // !!!and here warning occurs $reflect = new \reflectionclass($manager); $manager = $reflect->newinstance($user, $database, $errors); 

after these invoking method need, , here fatal error stopped script:

$method = "show" . ucfirst($this->_page) . "page"; $reflect->getmethod($method)->invoke($manager); 

i didn't see changes in documentation. had same issue?

first , foremost, why passing object reference !?

objects have pass-by-reference semantics, forcibly trying pass objects reference has not made sense since php 4.

just remove & ...

let's ignore that, , pretend there still problem, can try understand going on.

to break down problem, first need understand distinction between variable , expression:

mine(1 + 2); 

the argument mine has no name, it's represented temporary variable in engine: it's expression.

mine(1); 

the argument mine has no name, it's not expression, literal constant, represented compiler variable in engine. it's similar temporary variable, kind of constant expression.

mine($a); 

the argument mine has name, can use refer it's value. it's normal variable.

only variables can passed reference because cannot refer expressions or literal constants

next need understand why pass-by-reference:

function mine(int $thing) {     $thing++; }  $a = 1;  mine($a);  var_dump($a); // int(1) 

in code, $a passed mine() value, changes mine() make $thing visible inside scope of mine. $a unchanged after call mine() returns because $a , $thing distinct, having been passed-by-value, means it's value copied on call stack invocation of mine().

function mine(int &$thing) {     $thing++; }  $a = 1;  mine($a);  var_dump($a); // int(2) 

in code above, $a passed mine() reference, means $a , $thing no longer distinct. changes mine() make $thing visible after call mine() returns.

the last piece in puzzle reflection:

function mine(int &$thing) {     $thing++; }  $a = 1;  $reflector = new reflectionfunction("mine"); $reflector->invoke($a); 

the code above raise:

warning: parameter 1 mine() expected reference, value given in /usr/src/php-src/refs.php on line 9 

this because reflectionfunction::invoke , similar reflection functions (reflectionclass::newinstance) accept parameters value , pass them onto invoked function value.

but ...

there still difference between pass-by-reference semantics, , passing reference, dangerous one:

class foo {     public function qux() {} }  class bar {}  function mine(foo &$foo) {   $foo = new bar();         }  $foo = new foo;  mine($foo);  $foo->qux(); 

will yield:

php fatal error:  uncaught error: call undefined method bar::qux() in /usr/src/php-src/refs.php:16 stack trace: #0 {main}   thrown in /usr/src/php-src/refs.php on line 16 

the declaration of mine() tells lies type safety of it's parameter. type safety guaranteed upon entry function, function body free break type safety, doesn't affect caller when relying on engines pass reference semantics objects.

this extremely scary kind of api, should avoided.


Comments

Popular posts from this blog

sql server - Cannot query correctly (MSSQL - PHP - JSON) -

php - trouble displaying mysqli database results in correct order -

C++ Linked List -