我不知道是否有可能以欺骗方式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 2011-03-25 13:01:10