希望する方法でオペレーターをだますことができるかどうかはわかりませんがinstanceof
(そうでない場合はクラスをサブクラスとして認識します)、ニーズに合った解決策を見つけたと思います。私があなたの問題を正しく理解していれば、コード全体に最小限の変更を加えて、任意のクラスにいくつかのメソッドを挿入したいだけです。
この場合の解決策を準備する最善の方法は、特性を使用することだと思います (ここで説明します)。特性を使用すると、直接継承せずに任意のクラスにメソッドを追加でき、基本クラスからメソッドを上書きできます。メソッドを特性で上書きするには、もちろんサブクラスが必要ですが、それらは動的に作成できます。ラッピングプロセスについては何も知りませんが、私のソリューションでは特別なクラスを使用しました。私の解決策を見てみましょう:
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';
}
ご覧のとおり、すべてがラッピング プロセス中に行われます。
より多くのラッパーがある場合は、新しいラップされたクラス名を別の方法で準備できます (たとえば、ラッパー名と関連付けるなど)。