コード例 #1
0
 /**
  * Recursively traverses and wraps all Closure objects within the value.
  *
  * NOTE: THIS MAY NOT WORK IN ALL USE CASES, SO USE AT YOUR OWN RISK.
  *
  * @param mixed $data Any variable that contains closures.
  * @param SerializerInterface $serializer The serializer to use.
  */
 public static function wrapClosures(&$data, SerializerInterface $serializer)
 {
     if ($data instanceof \Closure) {
         // Handle and wrap closure objects.
         $reflection = new \ReflectionFunction($data);
         if ($binding = $reflection->getClosureThis()) {
             self::wrapClosures($binding, $serializer);
             $scope = $reflection->getClosureScopeClass();
             $scope = $scope ? $scope->getName() : 'static';
             $data = $data->bindTo($binding, $scope);
         }
         $data = new SerializableClosure($data, $serializer);
     } elseif (is_array($data) || $data instanceof \stdClass || $data instanceof \Traversable) {
         // Handle members of traversable values.
         foreach ($data as &$value) {
             self::wrapClosures($value, $serializer);
         }
     } elseif (is_object($data) && !$data instanceof \Serializable) {
         // Handle objects that are not already explicitly serializable.
         $reflection = new \ReflectionObject($data);
         if (!$reflection->hasMethod('__sleep')) {
             foreach ($reflection->getProperties() as $property) {
                 if ($property->isPrivate() || $property->isProtected()) {
                     $property->setAccessible(true);
                 }
                 $value = $property->getValue($data);
                 self::wrapClosures($value, $serializer);
                 $property->setValue($data, $value);
             }
         }
     }
 }
コード例 #2
0
ファイル: Macroable.php プロジェクト: lunnlew/Norma_Code
 /**
  * Checks if callable is bindable.
  *
  * @param \Closure $callable
  * @return bool
  */
 function isBindable(Closure $callable)
 {
     $bindable = false;
     $reflectionFunction = new \ReflectionFunction($callable);
     if ($reflectionFunction->getClosureScopeClass() === null || $reflectionFunction->getClosureThis() !== null) {
         $bindable = true;
     }
     return $bindable;
 }
コード例 #3
0
 /**
  * Hash anything, return the unique identity.
  *
  * @param $object
  * @return string
  */
 protected function hash($object)
 {
     array_walk_recursive($object, function (&$item) {
         if ($item instanceof \Closure) {
             $reflection = new \ReflectionFunction($item);
             $item = serialize($reflection->getClosureScopeClass()) . $reflection->getNumberOfParameters() . $reflection->getNamespaceName() . $reflection->getStartLine() . $reflection->getEndLine();
         }
     });
     return md5(serialize($object));
 }
コード例 #4
0
ファイル: SmartHasher.php プロジェクト: aaronjan/housekeeper
 /**
  * Hash anything (except PDO connection stuff, for now).
  *
  * @param mixed $object
  * @return string
  */
 public static function hash($object)
 {
     $object = is_array($object) ? $object : [$object];
     array_walk_recursive($object, function ($item) {
         if ($item instanceof \Closure) {
             $reflection = new \ReflectionFunction($item);
             // Unique and fast.
             $item = serialize($reflection->getClosureScopeClass()) . $reflection->getNumberOfParameters() . $reflection->getNamespaceName() . $reflection->getStartLine() . $reflection->getEndLine();
         }
     });
     return md5(serialize($object));
 }
コード例 #5
0
ファイル: ClosureLocation.php プロジェクト: rodrigopbel/ong
 /**
  * Creates a ClosureLocation and seeds it with all the data that can be gleaned from the closure's reflection
  *
  * @param \ReflectionFunction $reflection The reflection of the closure that this ClosureLocation should represent
  *
  * @return ClosureLocation
  */
 public static function fromReflection(\ReflectionFunction $reflection)
 {
     $location = new self();
     $location->directory = dirname($reflection->getFileName());
     $location->file = $reflection->getFileName();
     $location->function = $reflection->getName();
     $location->line = $reflection->getStartLine();
     // @codeCoverageIgnoreStart
     if (version_compare(PHP_VERSION, '5.4', '>=')) {
         $closureScopeClass = $reflection->getClosureScopeClass();
         $location->closureScopeClass = $closureScopeClass ? $closureScopeClass->getName() : null;
     }
     // @codeCoverageIgnoreEnd
     return $location;
 }
コード例 #6
0
 public function afterTraverse(array $nodes)
 {
     if ($this->location['class']) {
         $this->location['class'] = $this->location['namespace'] . '\\' . $this->location['class'];
         $this->location['method'] = "{$this->location['class']}::{$this->location['function']}";
     } elseif ($this->location['trait']) {
         $this->location['trait'] = $this->location['namespace'] . '\\' . $this->location['trait'];
         $this->location['method'] = "{$this->location['trait']}::{$this->location['function']}";
     }
     if (!$this->location['class']) {
         /** @var \ReflectionClass $closureScopeClass */
         $closureScopeClass = $this->reflection->getClosureScopeClass();
         $this->location['class'] = $closureScopeClass ? $closureScopeClass->getName() : null;
     }
 }
コード例 #7
0
ファイル: CallbackUtils.php プロジェクト: edde-framework/edde
 public static function unwrap(\Closure $closure)
 {
     $reflectionFunction = new \ReflectionFunction($closure);
     if (substr($reflectionFunction->getName(), -1) === '}') {
         $vars = $reflectionFunction->getStaticVariables();
         return isset($vars['_callable_']) ? $vars['_callable_'] : $closure;
     } else {
         if ($obj = $reflectionFunction->getClosureThis()) {
             return [$obj, $reflectionFunction->getName()];
         } else {
             if ($class = $reflectionFunction->getClosureScopeClass()) {
                 return [$class->getName(), $reflectionFunction->getName()];
             }
         }
     }
     return $reflectionFunction->getName();
 }
コード例 #8
0
 public function afterTraverse(array $nodes)
 {
     if ($this->location['class']) {
         $this->location['class'] = $this->location['namespace'] . '\\' . $this->location['class'];
         $this->location['method'] = "{$this->location['class']}::{$this->location['function']}";
     } elseif ($this->location['trait']) {
         $this->location['trait'] = $this->location['namespace'] . '\\' . $this->location['trait'];
         $this->location['method'] = "{$this->location['trait']}::{$this->location['function']}";
         // If the closure was declared in a trait, then we will do a best
         // effort guess on the name of the class that used the trait. It's
         // actually impossible at this point to know for sure what it is.
         if ($closureScope = $this->reflection->getClosureScopeClass()) {
             $this->location['class'] = $closureScope ? $closureScope->getName() : null;
         } elseif ($closureThis = $this->reflection->getClosureThis()) {
             $this->location['class'] = get_class($closureThis);
         }
     }
 }
コード例 #9
0
ファイル: Module.php プロジェクト: cawaphp/module-clockwork
 /**
  * @param callable $listener
  *
  * @return string
  */
 private function getControllerName($listener) : string
 {
     if (is_array($listener)) {
         if (is_string($listener[0])) {
             return $listener[0] . '::' . $listener[1];
         } else {
             return get_class($listener[0]) . '::' . $listener[1];
         }
     } elseif (is_string($listener)) {
         return $listener;
     } else {
         $reflection = new \ReflectionFunction($listener);
         return $reflection->getClosureScopeClass()->getName() . '::' . 'closure[' . $reflection->getStartLine() . ':' . $reflection->getEndLine() . ']';
     }
 }
コード例 #10
0
ファイル: closure_042.php プロジェクト: badlamer/hhvm
<?php

$c = function () {
    var_dump($this);
};
$d = $c->bindTo(new stdClass());
$d();
$rm = new ReflectionFunction($d);
var_dump($rm->getClosureScopeClass()->name);
//dummy sope is Closure
//should have the same effect
$d = $c->bindTo(new stdClass(), NULL);
$d();
$rm = new ReflectionFunction($d);
var_dump($rm->getClosureScopeClass()->name);
//dummy sope is Closure
echo "Done.\n";
コード例 #11
0
<?php

$closure = function ($param) {
    return "this is a closure";
};
$rf = new ReflectionFunction($closure);
var_dump($rf->getClosureScopeClass());
class A
{
    public static function getClosure()
    {
        return function ($param) {
            return "this is a closure";
        };
    }
}
$closure = A::getClosure();
$rf = new ReflectionFunction($closure);
var_dump($rf->getClosureScopeClass());
echo "Done!\n";