最も近い祖先のコンストラクタを呼び出す場合は、祖先をclass_parentsでループし、コンストラクタがある場合はmethod_existsでチェックできます。その場合は、コンストラクタを呼び出します。そうでなければ、次の最も近い祖先で検索を続行します。だけでなく、親のコンストラクタをオーバーライド予防するだけでなく、他の先祖のこと(場合には親がコンストラクタを持っていない)でください:
コードの再利用のために
class Queue extends SplQueue {
public function __construct() {
echo 'before';
// loops through all ancestors
foreach(class_parents($this) as $ancestor) {
// check if constructor has been defined
if(method_exists($ancestor, "__construct")) {
// execute constructor of ancestor
eval($ancestor."::__construct();");
// exit loop if constructor is defined
// this avoids calling the same constructor twice
// e.g. when the parent's constructor already
// calls the grandparent's constructor
break;
}
}
echo 'I have made it after the parent constructor call';
}
}
、あなたはまた、機能として、このコードを書くことができていますeval
EDになるようにPHPコードを返します。
// define function to be used within various classes
function get_parent_construct($obj) {
// loop through all ancestors
foreach(class_parents($obj) as $ancestor) {
// check if constructor has been defined
if(method_exists($ancestor, "__construct")) {
// return PHP code (call of ancestor's constructor)
// this will automatically break the loop
return $ancestor."::__construct();";
}
}
}
class Queue extends SplQueue {
public function __construct() {
echo 'before';
// execute the string returned by the function
// eval doesn't throw errors if nothing is returned
eval(get_parent_construct($this));
echo 'I have made it after the parent constructor call';
}
}
// another class to show code reuse
class AnotherChildClass extends AnotherParentClass {
public function __construct() {
eval(get_parent_construct($this));
}
}
ただ、好奇心から、なぜあなたはキュークラスを拡張していますか?あなたは飾り付けをするために何をする必要がありますか? – ircmaxell