コード例 #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
ファイル: closure.php プロジェクト: Tacit007/Calenda
 public function parse(&$variable)
 {
     if (!$variable instanceof Closure) {
         return false;
     }
     $this->name = 'Closure';
     $reflection = new ReflectionFunction($variable);
     $ret = array('Parameters' => array());
     if ($val = $reflection->getParameters()) {
         foreach ($val as $parameter) {
             // todo http://php.net/manual/en/class.reflectionparameter.php
             $ret['Parameters'][] = $parameter->name;
         }
     }
     if ($val = $reflection->getStaticVariables()) {
         $ret['Uses'] = $val;
     }
     if ($val = $reflection->getClosureThis()) {
         $ret['Uses']['$this'] = $val;
     }
     if ($val = $reflection->getFileName()) {
         $this->value = Kint::shortenPath($val) . ':' . $reflection->getStartLine();
     }
     return $ret;
 }
コード例 #3
0
ファイル: ClosureAnalyzer.php プロジェクト: focuslife/v0.1
 private function isClosureStatic(\Closure $closure)
 {
     $closure = @$closure->bindTo(new \stdClass());
     if ($closure === null) {
         return true;
     }
     $rebound = new \ReflectionFunction($closure);
     return $rebound->getClosureThis() === null;
 }
コード例 #4
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;
 }
コード例 #5
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();
 }
コード例 #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 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);
         }
     }
 }
コード例 #7
0
 /**
  * Sets the code to execute when running this command.
  *
  * If this method is used, it overrides the code defined
  * in the execute() method.
  *
  * @param callable $code A callable(InputInterface $input, OutputInterface $output)
  *
  * @return Command The current instance
  *
  * @throws \InvalidArgumentException
  *
  * @see execute()
  *
  * @api
  */
 public function setCode($code)
 {
     if (!is_callable($code)) {
         throw new \InvalidArgumentException('Invalid callable provided to Command::setCode.');
     }
     if ($code instanceof \Closure) {
         $r = new \ReflectionFunction($code);
         if (null === $r->getClosureThis()) {
             $code = \Closure::bind($code, $this);
         }
     }
     $this->code = $code;
     return $this;
 }
コード例 #8
0
ファイル: Command.php プロジェクト: blazarecki/symfony
 /**
  * Sets the code to execute when running this command.
  *
  * If this method is used, it overrides the code defined
  * in the execute() method.
  *
  * @param callable $code A callable(InputInterface $input, OutputInterface $output)
  *
  * @return Command The current instance
  *
  * @throws InvalidArgumentException
  *
  * @see execute()
  */
 public function setCode(callable $code)
 {
     if ($code instanceof \Closure) {
         $r = new \ReflectionFunction($code);
         if (null === $r->getClosureThis()) {
             $code = \Closure::bind($code, $this);
         }
     }
     $this->code = $code;
     return $this;
 }
コード例 #9
0
ファイル: Multiget.php プロジェクト: kijtra/multiget
 private function isBinded($closure)
 {
     $reflection = new \ReflectionFunction($closure);
     $bind = $reflection->getClosureThis();
     if (is_object($bind)) {
         return $bind;
     }
     return false;
 }
コード例 #10
0
<?php

class StaticExample
{
    static function foo()
    {
        var_dump("Static Example class, Hello World!");
    }
}
class Example
{
    public $bar = 42;
    public function foo()
    {
        var_dump("Example class, bar: " . $this->bar);
    }
}
// Initialize classes
$class = new ReflectionClass('Example');
$staticclass = new ReflectionClass('StaticExample');
$object = new Example();
$method = $staticclass->getMethod('foo');
$closure = $method->getClosure();
$rf = new ReflectionFunction($closure);
var_dump($rf->getClosureThis());
$method = $class->getMethod('foo');
$closure = $method->getClosure($object);
$rf = new ReflectionFunction($closure);
var_dump($rf->getClosureThis());
echo "Done!\n";
コード例 #11
0
ファイル: Command.php プロジェクト: symfony/symfony
 /**
  * Sets the code to execute when running this command.
  *
  * If this method is used, it overrides the code defined
  * in the execute() method.
  *
  * @param callable $code A callable(InputInterface $input, OutputInterface $output)
  *
  * @return Command The current instance
  *
  * @throws InvalidArgumentException
  *
  * @see execute()
  */
 public function setCode(callable $code)
 {
     if ($code instanceof \Closure) {
         $r = new \ReflectionFunction($code);
         if (null === $r->getClosureThis()) {
             if (PHP_VERSION_ID < 70000) {
                 // Bug in PHP5: https://bugs.php.net/bug.php?id=64761
                 // This means that we cannot bind static closures and therefore we must
                 // ignore any errors here.  There is no way to test if the closure is
                 // bindable.
                 $code = @\Closure::bind($code, $this);
             } else {
                 $code = \Closure::bind($code, $this);
             }
         }
     }
     $this->code = $code;
     return $this;
 }