が、それはあなたが望む方法でinstanceof
オペレータをだますことが可能である(そうでない場合は、サブクラスとしてクラスを認識)が、私は、私はあなたのニーズに合わせて解決策を見つけたと思います参照してください。 。あなたが問題を正しく理解しているならば、コード全体の変更を最小限に抑えて、どのクラスにもいくつかのメソッドを注入したいだけです。
このケースでは、解決策を準備する最良の方法は、形質を使用することです(hereを参照)。特性を使用すると、直接継承なしで任意のクラスにメソッドを追加することができ、基本クラスのメソッドを上書きすることができます。もちろん、特性を使ってメソッドを上書きするには、サブクラスが必要ですが、動的に作成することができます。私はラッピングプロセスについて何も知らないが、私のソリューションでは特別なクラスを使用した。私の解決策を見てみましょう:
namespace someNameSpace;
//this is one of your class that you want to wrap - it can be declare under some other namespace if you need
class yourBaseClass { }
//your wrapper class as a trait
trait yourWrapper { }
//class for wrapping any object
class ObjectWrapperClass
{
//method for change object class (described on http://stackoverflow.com/a/3243949/4662836)
protected static function objectToObject($instance, $className)
{
return unserialize(sprintf('O:%d:"%s"%s', strlen($className), $className, strstr(strstr(serialize($instance), '"'), ':')));
}
//wrapping method
//$object is a object to be wrapped
//$wrapper is a full name of the wrapper trait
public static function wrap($object, $wrapper)
{
//take some information about the object to be wrapped
$reflection = new \ReflectionClass($object);
$baseClass = $reflection->getShortName();
$namespace = $reflection->getNamespaceName();
//perpare the name of the new wrapped class
$newClassName = "{$baseClass}Wrapped";
//if new wrapped class has not been declared before we need to do it now
if (!class_exists($newClassName)) {
//prepare a code of the wrapping class that inject trait
$newClassCode = "namespace {$namespace} { class {$newClassName} extends {$baseClass} { use {$wrapper}; } }";
//run the prepared code
eval($newClassCode);
}
//change the object class and return it
return self::objectToObject($object, $namespace . '\\' . $newClassName);
}
}
//lets test this solution
$originalObject = new yourBaseClass();
$wrappedObject = ObjectWrapperClass::wrap($originalObject, 'yourWrapper');
if ($wrappedObject instanceof yourBaseClass) {
echo 'It is working';
}
あなたが見ることができるようにすべてのラッピングプロセス中に発生します。
さらにラッパーがある場合は、新しいラップされたクラス名を別の方法で準備することができます(たとえば、ラッパー名をコアにするなど)。
これは私が取り組もうとしている問題とまったく同じです。あなたは何とかこれを働かせることができましたか?もしそうなら、私はあなたのやり方に非常に興味があります。 – mrjames