2016-11-10 27 views
0

私はPHP 5.6.19で書かれたPHPスクリプトを5.3バージョンで動作し、いくつかのインストールされたアドオンで動作します。PHP7。リフレクションは古いバージョンからは機能しませんPHP

私はphp7で実行しようと決めました。

Reflection::classで新しいインスタンスを作成して、パラメータを参照してクラスを初期化するスクリプトの特別な機能です。そして、そこでは警告が参照によって変数を待っていたが、受け取った価値があった。私は私が必要なメソッドを呼び出していますこれらの後

// define manager type to create (all managers has the same constructor) 
$manager = $managersNamespace . ucfirst($this->_manager) . "Manager"; 
// trying to create the manager 
// !!!And here a Warning occurs 
$reflect = new \ReflectionClass($manager); 
$manager = $reflect->newInstance($user, $database, $errors); 

:このコンストラクタが使用されているコードの

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

サンプル:クラスの

定義コンストラクタメソッドからインスタンスを作成しようとしましたここで致命的なエラーがスクリプトを停止しました:

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

私は見たことがありませんドキュメントの変更。誰もが同じ問題を抱えていた?

+2

何かエラーがありますか? – bishop

+0

カプラを抜いたコードスニペットの代わりに、正確な問題と、問題のみを示すSSCCEを与えることができますか? –

+0

これはSSCCEが何であるかを推測しようとしました - http://sandbox.onlinephpfunctions.com/code/9a32f440e3939f845a9b1c26bc2f06408abbf5cd - 5.6と7.0の両方でA-OKを実行しました。あなたはそのコードを取ってあなたの実際の状況を反映してそれを修正し、それをあなたの質問の例として掲示できますか?ありがとう。 –

答えて

6

まず第一に、オブジェクトを参照する理由は何ですか?

オブジェクトは参照渡しのセマンティクスを持っており、オブジェクトを参照渡ししようと強制的に試行したのはPHP 4であるため意味がありません。

ちょうどあなたが何が起こっているか理解しようとすることができるように、のは、それを無視してみましょう、との問題が依然として存在しているふりを& ...

を削除します。

あなたは、変数や表現の違いを理解する必要がある最初の、問題を打破するには、次の鉱山へ

mine(1 + 2); 

引数には名前がありません、それはエンジンに一時変数で表されます:それはです表現。鉱山へ

mine(1); 

引数に名前がない、それはエンジン内のコンパイラの変数によって表される表現が、リテラル定数、ではありません。これは一時変数のようなもので、一種の定数式です。

mine($a); 

mineの引数は値を参照するために使用できる名前です。これは通常の変数です。このコードで

function mine(int $thing) { 
    $thing++; 
} 

$a = 1; 

mine($a); 

var_dump($a); // int(1) 

、:あなたは私たちが参照渡し理由を理解する必要がありますが、式やリテラル定数

次を参照することはできませんので、変数のみが参照渡しすることができ

$amine()に値で渡されるため、mine()$thingに変更されるのはmineの範囲内にのみ表示されます。$a$thingは異なる値で渡されたため、mine()の呼び出しの呼び出しスタックにコピーされたことを意味するので、mine()の呼び出し後には$aは変更されません。上記のコードで

function mine(int &$thing) { 
    $thing++; 
} 

$a = 1; 

mine($a); 

var_dump($a); // int(2) 

$aが参照によりmine()に渡され、これは$a$thingがもはや明確であることを意味しません。 mine()の呼び出し後にmine()の変更が$thingに変更されました。

function mine(int &$thing) { 
    $thing++; 
} 

$a = 1; 

$reflector = new ReflectionFunction("mine"); 
$reflector->invoke($a); 

は、上記のコードが発生します:

Warning: Parameter 1 to mine() expected to be a reference, value given in /usr/src/php-src/refs.php on line 9 

これはReflectionFunction::invokeと同様の反射関数(ReflectionClass::newInstanceaccept their parameters by valuepass them onto the invoked function by valueため

パズルの最後のピースが反射されます。

しかし...

あり参照渡しセマンティクスとの差はまだある、と参照渡し、危険1:

class Foo { 
    public function qux() {} 
} 

class Bar {} 

function mine(Foo &$foo) { 
    $foo = new Bar();   
} 

$foo = new Foo; 

mine($foo); 

$foo->qux(); 

ウィル明らか収量:

PHP Fatal error: Uncaught Error: Call to 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 

mine()の宣言は、そのパラメータの型安全性について嘘をつきます。型安全性は関数への入力時にのみ保証され、関数本体は型安全性を自由に破ることができますが、エンジンに依存するときには呼び出し側には影響しません。

これは非常に恐ろしい種類のAPIなので、避けてください。

+0

ありがとう。あなたが正しいです –

関連する問題