Share Pastebin
Guest
Public paste!

andrewm

By: a guest | Aug 9th, 2008 | Syntax: PHP | Size: 3.28 KB | Hits: 118 | Expires: Never
Copy text to clipboard
  1. <?php
  2.  
  3. class Goose
  4. {
  5.         public static function cast($class, $object)
  6.         {
  7.                 if ($object instanceof $class)
  8.                 {
  9.                         return $object;
  10.                 }
  11.  
  12.                 $name = 'duck_'.md5(microtime());
  13.  
  14.                 $c = new ReflectionClass($class);
  15.  
  16.                 // generate an object....
  17.                 $code = 'class '.$name
  18.                         .($c->isInterface() ? ' implements ' : ' extends ').$c->getName().' {'
  19.                         .' protected $__obj;'
  20.                         .' public function __construct($object) { $this->__obj = $object; }';
  21.  
  22.                 foreach ($c->getMethods() as $m)
  23.                 {
  24.                         /* @var $m ReflectionMethod */
  25.                         if (!$m->isConstructor()
  26.                                 && !$m->isDestructor())
  27.                         {
  28.                                 $code .= self::buildMethod($m);
  29.                         }
  30.                 }
  31.                 $code .= '}';
  32.  
  33.                 eval($code);
  34.                 return new $name($object);
  35.         }
  36.  
  37.         public static function isA($interface, $object)
  38.         {
  39.                 if ($interface instanceof $object)
  40.                 {
  41.                         return TRUE;
  42.                 }
  43.  
  44.                 $c1 = new ReflectionClass($interface);
  45.                 $c2 = new ReflectionClass($object);
  46.  
  47.                 // include the constructor if we're not an object,
  48.                 // because we'll probably want to construct it
  49.                 $construct = !is_object($object);
  50.  
  51.                 return self::implementsInterface($c1, $c2, $construct);
  52.         }
  53.  
  54.         protected static function buildMethod(ReflectionMethod $m)
  55.         {
  56.                 $mod = ($m->getModifiers() & ~ReflectionMethod::IS_ABSTRACT);
  57.  
  58.                 return implode(' ', Reflection::getModifierNames($mod))
  59.                         . ' function '.$m->getName() .' () {'
  60.                         . ' $a = func_get_args();'
  61.                         . ' call_user_func_array(array($this->__obj, "'.$m->getName().'"), $a);'
  62.                         . '}';
  63.         }
  64.  
  65.         protected static function implementsInterface(ReflectionClass $interface, ReflectionClass $class, $include_constructor)
  66.         {
  67.                 foreach ($interface->getMethods() as $m1)
  68.                 {
  69.                         /* @type $m1 ReflectionMethod */
  70.                         if (($m1->isConstructor() === $include_constructor)
  71.                                 && !$m1->isDestructor()
  72.                                 && (($m2 = self::hasMethod($class, $m1)) === FALSE
  73.                                         || !self::checkModifiers($m1, $m2)
  74.                                         || !self::checkParameters($m1, $m2)))
  75.                         {
  76.                                 return FALSE;
  77.                         }
  78.                 }
  79.                 return TRUE;
  80.         }
  81.  
  82.         protected static function hasMethod(ReflectionClass $c, ReflectionMethod $m)
  83.         {
  84.                 $name = $m->getName();
  85.  
  86.                 if ($c->hasMethod($name))
  87.                 {
  88.                         return $c->getMethod($name);
  89.                 }
  90.                 return FALSE;
  91.         }
  92.  
  93.         protected static function checkModifiers(ReflectionMethod $m1, ReflectionMethod $m2)
  94.         {
  95.                 $mask = $m1->getModifiers();
  96.  
  97.                 switch (TRUE)
  98.                 {
  99.                         case ($mask & ReflectionMethod::IS_PUBLIC):
  100.                                 $mask |= ReflectionMethod::IS_PROTECTED;
  101.                         case ($mask & ReflectionMethod::IS_PROTECTED):
  102.                                 $mask |= ReflectionMethod::IS_PRIVATE;
  103.                 }
  104.  
  105.                 return ($m1->getModifiers() & $mask);
  106.         }
  107.  
  108.         protected static function checkParameters(ReflectionMethod $m1, ReflectionMethod $m2)
  109.         {
  110.                 if ($m2->getNumberOfRequiredParameters() < $m1->getNumberOfRequiredParameters())
  111.                 {
  112.                         return FALSE;
  113.                 }
  114.  
  115.                 $params1 = $m1->getParameters();
  116.                 $params2 = $m2->getParameters();
  117.                 $c = count($params1);
  118.  
  119.                 for ($i = 0; $i < $c; $i++)
  120.                 {
  121.                         $p1 = $params1[$i];
  122.                         $p2 = $params2[$i];
  123.  
  124.                         /* @var $p1 ReflectionParameter */
  125.                         /* @var $p2 ReflectionParameter */
  126.                         if ($p1->isOptional() !== $p2->isOptional()
  127.                                 || $p1->allowsNull() !== $p2->allowsNull()
  128.                                 || $p1->isArray() !== $p2->isArray()
  129.                                 /*|| $p1->getClass() !== $p2->getClass()*/
  130.                                 || $p1->isPassedByReference() !== $p2->isPassedByReference())
  131.                         {
  132.                                 return FALSE;
  133.                         }
  134.                 }
  135.  
  136.                 return TRUE;
  137.         }
  138. }
  139. ?>