Example #1
0
 /**
  * @param  mixed   class, object, callable
  * @param  string  method
  * @return \Closure
  */
 public static function closure($callable, $m = NULL)
 {
     if ($m !== NULL) {
         $callable = array($callable, $m);
     } elseif (is_string($callable) && count($tmp = explode('::', $callable)) === 2) {
         $callable = $tmp;
     } elseif ($callable instanceof \Closure) {
         return $callable;
     } elseif (is_object($callable)) {
         $callable = array($callable, '__invoke');
     }
     if (PHP_VERSION_ID >= 50400) {
         if (is_string($callable) && function_exists($callable)) {
             $r = new \ReflectionFunction($callable);
             return $r->getClosure();
         } elseif (is_array($callable) && method_exists($callable[0], $callable[1])) {
             $r = new \ReflectionMethod($callable[0], $callable[1]);
             return $r->getClosure($callable[0]);
         }
     }
     self::check($callable);
     $_callable_ = $callable;
     return function () use($_callable_) {
         return call_user_func_array($_callable_, func_get_args());
     };
 }
Example #2
0
 /**
  * Execute command
  *
  * @return int|mixed
  * @throws \Exception
  */
 public function exec()
 {
     $args = func_get_args();
     if (!$this->cmd) {
         throw new FWException('no cmd provided', 1);
     }
     $build = new ProcessBuilder();
     $pro = $build->setPrefix($this->cmd)->setArguments($args)->getProcess();
     $pro->setTimeout($this->timeout);
     $rm = new \ReflectionMethod($this, 'output');
     $func = $rm->getClosure($this);
     $re = 0;
     if ($this->async) {
         $pro->start($func);
     } else {
         try {
             $pro->mustRun($func);
             $this->out = $pro->getOutput();
             $re = $this->out;
         } catch (ProcessFailedException $e) {
             getLog()->error($e->getMessage());
             $re = 1;
         }
     }
     return $re;
 }
Example #3
0
 public function __construct(LoggerInterface $logger)
 {
     $build = new \ReflectionMethod($this, 'buildCallback');
     $run = new \ReflectionMethod($this, 'runCallback');
     $this->buildCallback = $build->getClosure($this);
     $this->runCallback = $run->getClosure($this);
     $this->logger = $logger;
 }
Example #4
0
 public function method($controller_root, $method)
 {
     $controller = $this->controller;
     $class = $this->class;
     $controller_model_name = $controller_root . '\\' . $class;
     $func = new \ReflectionMethod($controller_model_name, $method);
     $Closure = $func->getClosure(new $controller_model_name());
     $controller->{$class}()->Methods[$method] = $Closure->bindTo($controller->{$class}(), $controller->{$class}());
     return $controller->{$class}()->Methods[$method];
 }
Example #5
0
function execute($class_name, $method_name, $instance)
{
    try {
        $ref = new ReflectionMethod($class_name, $method_name);
        $method = $ref->getClosure($instance);
        var_dump($method());
    } catch (Exception $e) {
        $c = get_class($e);
        echo "{$c}: {$e->getMessage()}\n";
    }
}
Example #6
0
 public function __construct()
 {
     if (PHP_VERSION_ID >= 50400) {
         if (is_int($code = http_response_code())) {
             $this->code = $code;
         }
     }
     if (PHP_VERSION_ID >= 50401) {
         // PHP bug #61106
         $rm = new \ReflectionMethod('Nette\\Http\\Helpers::removeDuplicateCookies');
         header_register_callback($rm->getClosure());
         // requires closure due PHP bug #66375
     }
 }
Example #7
0
 /**
  * Extracts the named method from the supplied object and attaches
  * it to the skeleton instance
  * 
  * @param object $object
  * @param string $methodName
  * @param string $newMethodName - optional: attach the method under a new name
  * @throws InvalidObjectException When the $object param isn't actually an object
  * @throws InvalidMethodException When the named method is not callable
  * @return \Vanqard\Frankenbuilder\Builder fluent interface
  */
 public function addMethod($object, $methodName, $newMethodName = null)
 {
     if (!is_object($object)) {
         throw new InvalidObjectException('First parameter must be an object instance');
     }
     if (!is_callable(array($object, $methodName))) {
         throw new InvalidMethodException('The named method must be callable on the supplied object');
     }
     $methodInstance = new \ReflectionMethod($object, $methodName);
     $limb = $methodInstance->getClosure($object);
     $limbName = !is_null($newMethodName) ? $newMethodName : $methodName;
     $this->addToSkeleton($limbName, $limb);
     return $this;
 }
 /**
  * Call a action of controller
  * 
  * @access public
  * @param MVC $mvc         MVC Application object
  * @param string $method   Method or Function of the Class Controller
  * @param string $fileView String of the view file
  * @return array           Response array
  * @throws \LogicException
  */
 public final function call(MVC $mvc, $method, $fileView = null)
 {
     if (!method_exists($this, $method)) {
         throw new \LogicException(sprintf('Method "s" don\'t exists.', $method));
     }
     # Replace the view object
     $this->view = $mvc->view();
     # Arguments of method
     $arguments = array();
     # Create a reflection method
     $reflectionMethod = new \ReflectionMethod(get_class($this), $method);
     $reflectionParams = $reflectionMethod->getParameters();
     foreach ($reflectionParams as $param) {
         if ($paramClass = $param->getClass()) {
             $className = $paramClass->name;
             if ($className === 'MVC\\MVC' || $className === '\\MVC\\MVC') {
                 $arguments[] = $mvc;
             } elseif ($className === 'MVC\\Server\\HttpRequest' || $className === '\\MVC\\Server\\HttpRequest') {
                 $arguments[] = $mvc->request();
             }
         } else {
             foreach ($mvc->request()->params as $keyReqParam => $valueReqParam) {
                 if ($param->name === $keyReqParam) {
                     $arguments[] = $valueReqParam;
                     break;
                 }
             }
         }
     }
     $response = call_user_func_array($reflectionMethod->getClosure($this), $arguments);
     if (empty($response)) {
         throw new \LogicException('Response null returned.');
     }
     if (is_string($response)) {
         $this->response['body'] = $response;
     } elseif ($mvc->request()->isAjax()) {
         $this->response['body'] = $this->renderJson($response);
     } elseif (is_array($response)) {
         if (!$fileView) {
             throw new \LogicException('File view is null.');
         }
         $class = explode("\\", get_called_class());
         $classname = end($class);
         // Class without Controller
         $classname = str_replace('Controller', '', $classname);
         $file = $classname . "/{$fileView}";
         $this->response['body'] = $this->renderHtml($file, $response);
     }
     return $this->response;
 }
Example #9
0
 public static function loadTable($name, $db_name = db_name)
 {
     if (isset(self::$tables[$db_name][$name])) {
         return self::$tables[$db_name][$name];
     }
     $blackList = array("index", "foreign", "unique");
     $sName = "\\database\\{$db_name}\\{$name}";
     if (class_exists($sName)) {
         $table_load = new $sName();
         foreach ($table_load as $key => $value) {
             if (!preg_grep("/^{$key}\$/", $blackList)) {
                 $keys = array_keys($value);
                 $values = array_values($value);
                 $array = array();
                 foreach ($keys as $k => $v) {
                     if (is_int($v)) {
                         $keys[$k] = $values[$k];
                         $values[$k] = true;
                     }
                 }
                 if (method_exists($table_load, $key)) {
                     $options = new \lib\sql\options();
                     $func = new \ReflectionMethod($sName, $key);
                     $Closure = $func->getClosure($table_load);
                     $options->{$key} = \Closure::bind($Closure, $options);
                     $options->table = $table_load;
                     $options->tableName = $table_load;
                     $options->fieldName = $key;
                     $values[] = $options;
                     $keys[] = 'closure';
                 }
                 $array = array_combine($keys, $values);
                 $table_load->{$key} = (object) $array;
             }
         }
         foreach ($table_load as $key => $value) {
             if (method_exists($table_load, $key)) {
                 if (isset($table_load->{$key}->closure)) {
                     $closure = $table_load->{$key}->closure;
                     call_user_func($closure->{$key});
                 }
             }
         }
         self::$tables[$db_name][$name] = $table_load;
         return $table_load;
     }
     return null;
 }
 public function testExpandClasses()
 {
     $r = new \ReflectionClass(AddClassesToCachePass::class);
     $pass = $r->newInstanceWithoutConstructor();
     $r = new \ReflectionMethod(AddClassesToCachePass::class, 'expandClasses');
     $expand = $r->getClosure($pass);
     $this->assertSame('Foo', $expand(array('Foo'), array())[0]);
     $this->assertSame('Foo', $expand(array('\\Foo'), array())[0]);
     $this->assertSame('Foo', $expand(array('Foo'), array('\\Foo'))[0]);
     $this->assertSame('Foo', $expand(array('Foo'), array('Foo'))[0]);
     $this->assertSame('Foo', $expand(array('\\Foo'), array('\\Foo\\Bar'))[0]);
     $this->assertSame('Foo', $expand(array('Foo'), array('\\Foo\\Bar'))[0]);
     $this->assertSame('Foo', $expand(array('\\Foo'), array('\\Foo\\Bar\\Acme'))[0]);
     $this->assertSame('Foo\\Bar', $expand(array('Foo\\'), array('\\Foo\\Bar'))[0]);
     $this->assertSame('Foo\\Bar\\Acme', $expand(array('Foo\\'), array('\\Foo\\Bar\\Acme'))[0]);
     $this->assertEmpty($expand(array('Foo\\'), array('\\Foo')));
     $this->assertSame('Acme\\Foo\\Bar', $expand(array('**\\Foo\\'), array('\\Acme\\Foo\\Bar'))[0]);
     $this->assertEmpty($expand(array('**\\Foo\\'), array('\\Foo\\Bar')));
     $this->assertEmpty($expand(array('**\\Foo\\'), array('\\Acme\\Foo')));
     $this->assertEmpty($expand(array('**\\Foo\\'), array('\\Foo')));
     $this->assertSame('Acme\\Foo', $expand(array('**\\Foo'), array('\\Acme\\Foo'))[0]);
     $this->assertEmpty($expand(array('**\\Foo'), array('\\Acme\\Foo\\AcmeBundle')));
     $this->assertEmpty($expand(array('**\\Foo'), array('\\Acme\\FooBar\\AcmeBundle')));
     $this->assertSame('Foo\\Acme\\Bar', $expand(array('Foo\\*\\Bar'), array('\\Foo\\Acme\\Bar'))[0]);
     $this->assertEmpty($expand(array('Foo\\*\\Bar'), array('\\Foo\\Acme\\Bundle\\Bar')));
     $this->assertSame('Foo\\Acme\\Bar', $expand(array('Foo\\**\\Bar'), array('\\Foo\\Acme\\Bar'))[0]);
     $this->assertSame('Foo\\Acme\\Bundle\\Bar', $expand(array('Foo\\**\\Bar'), array('\\Foo\\Acme\\Bundle\\Bar'))[0]);
     $this->assertSame('Acme\\Bar', $expand(array('*\\Bar'), array('\\Acme\\Bar'))[0]);
     $this->assertEmpty($expand(array('*\\Bar'), array('\\Bar')));
     $this->assertEmpty($expand(array('*\\Bar'), array('\\Foo\\Acme\\Bar')));
     $this->assertSame('Foo\\Acme\\Bar', $expand(array('**\\Bar'), array('\\Foo\\Acme\\Bar'))[0]);
     $this->assertSame('Foo\\Acme\\Bundle\\Bar', $expand(array('**\\Bar'), array('\\Foo\\Acme\\Bundle\\Bar'))[0]);
     $this->assertEmpty($expand(array('**\\Bar'), array('\\Bar')));
     $this->assertSame('Foo\\Bar', $expand(array('Foo\\*'), array('\\Foo\\Bar'))[0]);
     $this->assertEmpty($expand(array('Foo\\*'), array('\\Foo\\Acme\\Bar')));
     $this->assertSame('Foo\\Bar', $expand(array('Foo\\**'), array('\\Foo\\Bar'))[0]);
     $this->assertSame('Foo\\Acme\\Bar', $expand(array('Foo\\**'), array('\\Foo\\Acme\\Bar'))[0]);
     $this->assertSame(array('Foo\\Bar'), $expand(array('Foo\\*'), array('Foo\\Bar', 'Foo\\BarTest')));
     $this->assertSame(array('Foo\\Bar', 'Foo\\BarTest'), $expand(array('Foo\\*', 'Foo\\*Test'), array('Foo\\Bar', 'Foo\\BarTest')));
     $this->assertSame('Acme\\FooBundle\\Controller\\DefaultController', $expand(array('**Bundle\\Controller\\'), array('\\Acme\\FooBundle\\Controller\\DefaultController'))[0]);
     $this->assertSame('FooBundle\\Controller\\DefaultController', $expand(array('**Bundle\\Controller\\'), array('\\FooBundle\\Controller\\DefaultController'))[0]);
     $this->assertSame('Acme\\FooBundle\\Controller\\Bar\\DefaultController', $expand(array('**Bundle\\Controller\\'), array('\\Acme\\FooBundle\\Controller\\Bar\\DefaultController'))[0]);
     $this->assertSame('Bundle\\Controller\\Bar\\DefaultController', $expand(array('**Bundle\\Controller\\'), array('\\Bundle\\Controller\\Bar\\DefaultController'))[0]);
     $this->assertSame('Acme\\Bundle\\Controller\\Bar\\DefaultController', $expand(array('**Bundle\\Controller\\'), array('\\Acme\\Bundle\\Controller\\Bar\\DefaultController'))[0]);
     $this->assertSame('Foo\\Bar', $expand(array('Foo\\Bar'), array())[0]);
     $this->assertSame('Foo\\Acme\\Bar', $expand(array('Foo\\**'), array('\\Foo\\Acme\\Bar'))[0]);
 }
Example #11
0
 /**
  * Add routes to an App from this class by inferring details from PHPDoc @url and @method properties
  * @param App $app
  */
 public function load(App $app)
 {
     $class = get_called_class();
     $methods = get_class_methods($class);
     foreach ($methods as $class_method) {
         $method_props = [];
         $rm = new \ReflectionMethod($this, $class_method);
         $phpdoc = preg_split('/\\r\\n|\\n|\\r/', preg_replace('%^\\s*/?\\*+((?<=\\*)/|[ \\t]*)%m', '', $rm->getDocComment()));
         foreach ($phpdoc as $docline) {
             if (preg_match('#^@(url|method)\\s+(\\S+)$#', $docline, $matches)) {
                 $method_props[$matches[1]] = $matches[2];
             }
         }
         if (isset($method_props['url'])) {
             $route = $app->route($class . '::' . $class_method, $method_props['url'], $rm->getClosure($this));
             if (isset($method_props['method'])) {
                 $route->via($method_props['method']);
             }
         }
     }
 }
Example #12
0
 /**
  * Casts the given callable to Closure
  * @param callable $callable
  * @return \Closure
  * @throws \InvalidArgumentException
  */
 protected function castToClosure($callable)
 {
     if (!is_callable($callable)) {
         throw new \InvalidArgumentException('Argument 1 must be callable, ' . gettype($callable) . ' given.');
     }
     $result = null;
     if (is_object($callable)) {
         if ($callable instanceof \Closure) {
             $result = $callable;
         } else {
             if (method_exists($callable, '__invoke')) {
                 $r = new \ReflectionObject($callable);
                 $result = $r->getMethod('__invoke')->getClosure($callable);
             }
         }
     } else {
         try {
             $r = new \ReflectionMethod($callable);
             $result = $r->getClosure();
         } catch (\Exception $e) {
             try {
                 $r = new \ReflectionFunction($callable);
                 $result = $r->getClosure();
             } catch (\Exception $e) {
                 if (is_array($callable)) {
                     $r = new \ReflectionObject($callable[0]);
                     $result = $r->getMethod($callable[1])->getClosure($callable[0]);
                 }
             }
         }
     }
     if ($result === null) {
         throw new \InvalidArgumentException('Unsupported callable given.');
     }
     return $result;
 }
 /**
  * Returns the function/method as closure.
  *
  * @param object $object Object
  *
  * @return \Closure
  */
 public function getClosure($object)
 {
     if (PHP_VERSION >= 50400) {
         return parent::getClosure();
     } else {
         $that = $this;
         return function () use($object, $that) {
             return $that->invokeArgs($object, func_get_args());
         };
     }
 }
Example #14
0
 /**
  * @return	Closure
  */
 public function getClosure()
 {
     if ($this->closure instanceof \Closure) {
         return $this->closure;
     }
     $reflect = new \ReflectionMethod($this->closure);
     return $reflect->getClosure();
 }
Example #15
0
function yolisp($swag, array &$env = [])
{
    static $OP_CACHE = [];
    // HAH! Take that Zend!
    if (!$swag instanceof cons) {
        // implicitly quote non-strings
        if (!is_string($swag)) {
            return $swag;
        }
        // lookup in environment
        if (array_key_exists($swag, $env)) {
            return $env[$swag];
        } else {
            if (isset($OP_CACHE[$swag])) {
                return $OP_CACHE[$swag];
            } else {
                if (array_key_exists($swag, DEFAULT_ENV)) {
                    $callable = DEFAULT_ENV[$swag];
                    if (is_array($callable)) {
                        return $OP_CACHE[$swag] = (new \ReflectionMethod(...$callable))->getClosure();
                    } else {
                        if (is_string($callable)) {
                            return $OP_CACHE[$swag] = (new \ReflectionFunction($callable))->getClosure();
                        } else {
                            return $callable;
                        }
                    }
                } else {
                    if (function_exists($swag)) {
                        return $OP_CACHE[$swag] = (new \ReflectionFunction($swag))->getClosure();
                        // we do class lookup after function lookup because everyone knows functional programming is superior
                        // what did you expect? this is yolisp, not yojava
                    } else {
                        if (class_exists($swag)) {
                            return $swag;
                        } else {
                            if (array_key_exists($swag, OPS)) {
                                $format = OPS[$swag];
                                $ops = substr_count($format, '$');
                                $ops += $optional_ops = substr_count($format, '?');
                                if ($ops === 0) {
                                    throw new \Exception("Invalid operator format string: \"{$format}\"");
                                }
                                $param_names = [];
                                for ($i = 0; $i < $ops; $i++) {
                                    $param_names[] = '$op' . $i;
                                }
                                $param_list = '';
                                for ($i = 0; $i < $ops; $i++) {
                                    if ($i !== 0) {
                                        $param_list .= ', ';
                                    }
                                    $param_list .= $param_names[$i];
                                    if ($i >= $ops - $optional_ops) {
                                        $param_list .= ' = NULL';
                                    }
                                }
                                $parts = explode(' ', $format);
                                if ($optional_ops) {
                                    $optionless_expr = '';
                                    $i = 0;
                                    foreach ($parts as $part) {
                                        if ($part === '?') {
                                            $optionless_expr .= ' ';
                                        } else {
                                            if ($part === '$') {
                                                $optionless_expr .= ' ' . $param_names[$i];
                                                $i++;
                                            } else {
                                                $optionless_expr .= ' ' . $part;
                                            }
                                        }
                                    }
                                }
                                $expr = '';
                                $i = 0;
                                foreach ($parts as $part) {
                                    if ($part === '?' || $part === '$') {
                                        $expr .= ' ' . $param_names[$i];
                                        $i++;
                                    } else {
                                        $expr .= ' ' . $part;
                                    }
                                }
                                if ($optional_ops) {
                                    $body = "if (func_num_args() < {$ops}) { return {$optionless_expr}; } else { return {$expr}; }";
                                } else {
                                    $body = "return {$expr};";
                                }
                                // And people said eval() and create_function() were evil!
                                return $OP_CACHE[$swag] = create_function($param_list, $body);
                            } else {
                                throw new \Exception("Could not find {$swag} in environment");
                            }
                        }
                    }
                }
            }
        }
    }
    $eval = function ($swag) use(&$env) {
        return yolisp($swag, $env);
    };
    $command = cons::car($swag);
    $args = cons::cdr($swag);
    switch ($command) {
        case 'quote':
            return cons::car($args);
        case 'lambda':
            $arg_names = x(cons::car($args));
            $body = cons::car(cons::cdr($args));
            return function (...$args) use($arg_names, $body, &$env) {
                $new_env = $env;
                // copies rather than references
                foreach ($arg_names as $i => $arg_name) {
                    $new_env[$arg_name] = $args[$i];
                }
                return yolisp($body, $new_env);
            };
        case 'let':
            $pairs = cons::car($args);
            $body = cons::car(cons::cdr($args));
            $new_env = $env;
            // copies rather than references
            while (!is_null($pairs)) {
                $pair = cons::car($pairs);
                // (name value) 2-element list
                $new_env[cons::car($pair)] = yolisp(cons::car(cons::cdr($pair)), $new_env);
                $pairs = cons::cdr($pairs);
            }
            return yolisp($body, $new_env);
        case 'if':
            $expr = cons::car($args);
            $results = cons::cdr($args);
            $on_true = cons::car($results);
            $on_false = cons::car(cons::cdr($results));
            if ($eval($expr)) {
                return $eval($on_true);
            } else {
                return $eval($on_false);
            }
            break;
            // -> and :: aren't normal ops as property name is implicitly quoted
        // -> and :: aren't normal ops as property name is implicitly quoted
        case '->':
        case '::':
            $obj = $eval(cons::car($args));
            $prop = cons::car(cons::cdr($args));
            if (property_exists($obj, $prop)) {
                if ($command === '->') {
                    return $obj->{$prop};
                } else {
                    // this is really ugly syntax for a variable static property access
                    // luckily yolo users don't need to deal with it
                    return $obj::${$prop};
                }
                // PHP has separate symbol tables for methods and properties
                // NOT IN YOLISP!
            } else {
                if (method_exists($obj, $prop)) {
                    $method = new \ReflectionMethod($obj, $prop);
                    if ($command === '->') {
                        return $method->getClosure($obj);
                    } else {
                        return $method->getClosure();
                    }
                } else {
                    throw new \Exception("No property/method {$command}{$prop} in {$obj}");
                }
            }
            break;
        case 'new':
            $class = cons::car($args);
            $constructor_args = cons::cdr($args);
            $class_name = $eval($class);
            $evaluated_args = array_map($eval, x($constructor_args));
            return new $class_name(...$evaluated_args);
        default:
            $func = $eval($command);
            $evaluated_args = array_map($eval, x($args));
            return $func(...$evaluated_args);
    }
}
Example #16
0
 public function getClosure($object = NULL)
 {
     return PHP_VERSION_ID < 50400 ? Nette\Utils\Callback::closure($object ?: parent::getDeclaringClass()->getName(), $this->getName()) : parent::getClosure($object);
 }
Example #17
0
<?php

$closure = function () {
    echo "Invoked!\n";
};
$method = new ReflectionFunction($closure);
$closure2 = $method->getClosure();
$closure2();
$closure2->__invoke();
unset($closure);
$closure2();
$closure2->__invoke();
$closure = function () {
    echo "Invoked!\n";
};
$method = new ReflectionMethod($closure, '__invoke');
$closure2 = $method->getClosure($closure);
$closure2();
$closure2->__invoke();
unset($closure);
$closure2();
$closure2->__invoke();
?>
===DONE===
 /**
  * __get() implementation.
  * @param  object
  * @param  string  property name
  * @return mixed   property value
  * @throws MemberAccessException if the property is not defined.
  */
 public static function &get($_this, $name)
 {
     $class = get_class($_this);
     $uname = ucfirst($name);
     $methods =& self::getMethods($class);
     if ($name === '') {
         throw new MemberAccessException("Cannot read a class '{$class}' property without name.");
     } elseif (isset($methods[$m = 'get' . $uname]) || isset($methods[$m = 'is' . $uname])) {
         // property getter
         if ($methods[$m] === 0) {
             $rm = new \ReflectionMethod($class, $m);
             $methods[$m] = $rm->returnsReference();
         }
         if ($methods[$m] === TRUE) {
             return $_this->{$m}();
         } else {
             $val = $_this->{$m}();
             return $val;
         }
     } elseif (isset($methods[$name])) {
         // public method as closure getter
         if (PHP_VERSION_ID >= 50400) {
             $rm = new \ReflectionMethod($class, $name);
             $val = $rm->getClosure($_this);
         } else {
             $val = Nette\Utils\Callback::closure($_this, $name);
         }
         return $val;
     } else {
         // strict class
         $type = isset($methods['set' . $uname]) ? 'a write-only' : 'an undeclared';
         throw new MemberAccessException("Cannot read {$type} property {$class}::\${$name}.");
     }
 }
 /**
  * Возвращает замыкания на метод
  * @param $name имя метода, для которого надо получить замыкание
  * @return callable
  */
 protected function getMethod($name)
 {
     $method = new \ReflectionMethod(get_class($this), $name);
     return $method->getClosure($this);
 }
Example #20
0
function foo($a)
{
    return $a + 2;
}
$foo = function ($a) {
    return $a + 3;
};
$bar = new Bar(10);
// Dynamic methods
$rf = new ReflectionMethod($bar, 'baz');
var_dump($rf->getClosure() === NULL);
var_dump(call_user_func($rf->getClosure($bar), 1));
$rf = new ReflectionMethod('Bar', 'baz');
var_dump($rf->getClosure() === NULL);
var_dump(call_user_func($rf->getClosure($bar), 1));
$rf = new ReflectionMethod('Bar::baz');
var_dump($rf->getClosure() === NULL);
var_dump(call_user_func($rf->getClosure($bar), 1));
// Static methods
$rf = new ReflectionMethod($bar, 'foo');
var_dump(call_user_func($rf->getClosure(), 1));
$rf = new ReflectionMethod('Bar', 'foo');
var_dump(call_user_func($rf->getClosure(), 1));
$rf = new ReflectionMethod('Bar::foo');
var_dump(call_user_func($rf->getClosure(), 1));
// Function
$rf = new ReflectionFunction('foo');
var_dump(call_user_func($rf->getClosure(), 1));
// Closure
$rf = new ReflectionFunction($foo);
var_dump(call_user_func($rf->getClosure(), 1));
 /**
  * {@inheritDoc}
  */
 public function getClosure($object)
 {
     $this->initializeInternalReflection();
     return parent::getClosure($object);
 }
<?php

class MyClass
{
    public function method()
    {
    }
}
$object = new MyClass();
$reflector = new \ReflectionMethod($object, 'method');
$closure = $reflector->getClosure($object);
$closureReflector = new \ReflectionFunction($closure);
var_dump($closureReflector->isClosure());
/**
 * Converts any valid PHP callable into a Closure. Requires PHP 5.4.0+.
 *
 * The ramifications of this are many, but basically it means that any function
 * or method can be converted into a Closure, bound to another scope, and
 * executed easily. Works properly even with private methods.
 *
 * - On success, returns a Closure corresponding to the provided callable.
 * - If the parameter is not callable, issues an E_USER_WARNING and returns a
 *   Closure which only returns null.
 * - In the event of a strange or unrecoverable situation (e.g. providing a
 *   non-static method without an object), an UnexpectedValueException is
 *   thrown.
 *
 * @author Matthew Lanigan <*****@*****.**>
 * @copyright (c) 2012, Matthew Lanigan
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
 * @link https://gist.github.com/2773168 Official closurize() gist
 * @param callable $callable
 * @return \Closure
 * @throws \UnexpectedValueException
 */
function closurize($callable)
{
    if ($callable instanceof \Closure) {
        return $callable;
    }
    $is_callable = function ($callable) {
        return \is_callable($callable);
    };
    $error = function () {
        $debug = \debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
        $fmt = 'Parameter 1 for closurize() must be callable ' . 'in %s on line %d (issued at %s on line %d)';
        $error = \sprintf($fmt, $debug[1]['file'], $debug[1]['line'], $debug[0]['file'], $debug[0]['line']);
        \trigger_error($error, \E_USER_WARNING);
        return function () {
            return null;
        };
    };
    $object = null;
    $class = null;
    $debug = \debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
    if (isset($debug[1]['object']) && \is_object($debug[1]['object'])) {
        $object = $debug[1]['object'];
        $class = $debug[1]['class'];
        $is_callable = $is_callable->bindTo($object, $object);
    }
    if (!$is_callable($callable)) {
        if (isset($callable[0]) && is_object($callable[0])) {
            $is_callable = $is_callable->bindTo($callable[0], $callable[0]);
        } else {
            if (isset($callable[0]) && \class_exists($callable[0])) {
                $is_callable = $is_callable->bindTo(null, $callable[0]);
            }
        }
        if (!$is_callable($callable)) {
            return $error();
        }
    }
    if (\is_string($callable) && \strpos($callable, '::') === false) {
        $ref = new \ReflectionFunction($callable);
        return $ref->getClosure();
    } else {
        if (\is_string($callable)) {
            $callable = \explode('::', $callable);
        }
    }
    if (!\is_array($callable)) {
        throw new \UnexpectedValueException('Callable is not string, array, ' . 'or Closure');
    }
    if (\is_object($callable[0])) {
        $ref = new \ReflectionMethod($callable[0], $callable[1]);
        return $ref->getClosure($callable[0]);
    }
    if (!\is_string($callable[0])) {
        throw new \UnexpectedValueException('Callable class is not string ' . 'or object');
    }
    switch ($callable[0]) {
        case 'self':
            if (!\is_object($object) && \is_null($class)) {
                return $error();
            }
            $self = function () {
                return \get_class();
            };
            $self = $self->bindTo($object, $class);
            $ref = new \ReflectionMethod($self(), $callable[1]);
            $callable[0] = $object;
            break;
        case 'static':
            if (!\is_object($object)) {
                return $error();
            }
            $static = function () {
                return \get_called_class();
            };
            $static = $static->bindTo($object, $class);
            $ref = new \ReflectionMethod($static(), $callable[1]);
            $callable[0] = $object;
            break;
        case 'parent':
            if (!\is_object($object)) {
                return $error();
            }
            $parent = function () {
                return \get_parent_class();
            };
            $parent = $parent->bindTo($object, $class);
            $ref = new \ReflectionMethod($parent(), $callable[1]);
            $callable[0] = $object;
            break;
        default:
            $ref = new \ReflectionMethod($callable[0], $callable[1]);
            break;
    }
    if (!$ref->isStatic() && \is_object($callable[0])) {
        return $ref->getClosure($callable[0]);
    } else {
        if (!$ref->isStatic()) {
            throw new \UnexpectedValueException('Callable method is not static, ' . 'but no calling object available');
        }
    }
    return $ref->getClosure();
}
Example #24
0
/**
 * Invokes a method of an object/class, optionally on the context of another class.
 *
 * @param callable $ref     A callable reference; either [className,methodName] or [classInstance,methodName].
 * @param null     $self    [optional] The object on which context the call will be performed (this will set $this in
 *                          the method).
 * @param mixed    ...$args Extra arguments to be prepended to `$fn` on each call.
 * @return mixed The method's return value.
 */
function call_method($ref, $self = null)
{
    if (!is_array($ref) || count($ref) != 2) {
        throw new InvalidArgumentException("Argument must be an array with 2 elements");
    }
    $args = array_slice(func_get_args(), 2);
    $m = new \ReflectionMethod($ref[0], $ref[1]);
    if ($m->isStatic()) {
        return call_user_func_array($ref, $args);
    }
    $f = $m->getClosure($ref[0]);
    if ($self) {
        $f = $f->bindTo($self, $self);
    }
    return call_user_func_array($f, $args);
}
Example #25
0
 /**
  * Returns the method as a closure
  *
  * @return  callable
  * @since   0.1.0
  */
 public function getClosure()
 {
     return parent::getClosure($this->instance);
 }
Example #26
0
 /**
  * Run the aplication
  * 
  * @access public
  * @return void
  */
 public function run(HttpRequest $request = null)
 {
     if (!$this->container->getSetting('debug')) {
         error_reporting(0);
     } else {
         error_reporting(E_ALL);
     }
     if (!$request) {
         $request = $this->container->getRequest();
     }
     try {
         $parsed = $this->container->getRouter()->parse($request, $this->container->getRoutes());
         if ($parsed['found'] || $this->container->hasRoute('notFound')) {
             if (is_string($parsed['action'])) {
                 # Extract class controller and method
                 list($controller, $method) = explode('::', $parsed['action']);
                 # initialize arguments
                 $arguments = array();
                 # Create a reflection method
                 $reflectionMethod = new \ReflectionMethod($controller, $method);
                 $reflectionParams = $reflectionMethod->getParameters();
                 # Create arguments
                 foreach ($reflectionParams as $param) {
                     if ($paramClass = $param->getClass()) {
                         $className = $paramClass->name;
                         if ($className === 'MVC\\MVC' || $className === '\\MVC\\MVC') {
                             $arguments[] = $this;
                         } elseif ($className === 'MVC\\Server\\HttpRequest' || $className === '\\MVC\\Server\\HttpRequest') {
                             $arguments[] = $request;
                         }
                     } else {
                         foreach ($parsed['params'] as $keyRouteParam => $valueRouteParam) {
                             if ($param->name === $keyRouteParam) {
                                 $arguments[] = $valueRouteParam;
                                 break;
                             }
                         }
                     }
                 }
                 $response = call_user_func_array($reflectionMethod->getClosure(new $controller()), $arguments);
                 if (is_array($response) && !isset($response['body'])) {
                     throw new \LogicException("Invalid response array. Array response haven't body. Expected array('body' => 'string')");
                 } elseif (is_string($response)) {
                     $response = array('body' => $response);
                 }
             } elseif (is_callable($parsed['action'])) {
                 $this->container->getRequest()->params = $parsed['params'];
                 $response = call_user_func_array($parsed['action'], array_values($parsed['params']));
             } else {
                 throw new \LogicException('Route haven\'t action.');
             }
             if ($this->container->hasProvider('monolog')) {
                 $this->container->providers['monolog']->addInfo($response, $parsed);
             }
             $this->container->getResponse()->render($response);
         } else {
             if ($this->container->getSetting('debug')) {
                 throw new \LogicException(sprintf('Route or Resource "%s" not found.', $request->url));
             }
             $this->defaultNotFound();
         }
     } catch (\Exception $e) {
         Error::run($e);
     }
 }