我不知道是否有可能以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';
}
如您所见,一切都发生在包装过程中。
如果您有更多包装器,那么您可以以其他方式准备新的包装类名称(例如与包装器名称相关联)。