Opis\Closure\ReflectionClosure::getCode PHP Method

getCode() public method

public getCode ( ) : string
return string
    public function getCode()
    {
        if ($this->code !== null) {
            return $this->code;
        }
        $fileName = $this->getFileName();
        $line = $this->getStartLine() - 1;
        $match = ClosureStream::STREAM_PROTO . '://';
        if ($line === 1 && substr($fileName, 0, strlen($match)) === $match) {
            return $this->code = substr($fileName, strlen($match));
        }
        $className = null;
        if (SerializableClosure::supportBinding()) {
            if (null !== ($className = $this->getClosureScopeClass())) {
                $className = '\\' . trim($className->getName(), '\\');
            }
        }
        $ns = $this->getNamespaceName();
        $nsf = $ns == '' ? '' : ($ns[0] == '\\' ? $ns : '\\' . $ns);
        $_file = var_export($fileName, true);
        $_dir = var_export(dirname($fileName), true);
        $_namespace = var_export($ns, true);
        $_class = var_export(trim($className, '\\'), true);
        $_function = $ns . ($ns == '' ? '' : '\\') . '{closure}';
        $_method = ($className == '' ? '' : trim($className, '\\') . '::') . $_function;
        $_function = var_export($_function, true);
        $_method = var_export($_method, true);
        $_trait = null;
        $hasTraitSupport = defined('T_TRAIT_C');
        $tokens = $this->getTokens();
        $state = 'start';
        $open = 0;
        $code = '';
        $buffer = $name = '';
        $new_key_word = false;
        $classes = $functions = $constants = null;
        $use = array();
        $lineAdd = 0;
        $isUsingScope = false;
        $isUsingThisObject = false;
        foreach ($tokens as $token) {
            $is_array = is_array($token);
            switch ($state) {
                case 'start':
                    if ($is_array && ($token[0] === T_FUNCTION || $token[0] === T_STATIC)) {
                        $code .= $token[1];
                        $state = $token[0] === T_FUNCTION ? 'function' : 'static';
                    }
                    break;
                case 'static':
                    if ($is_array && ($token[0] === T_WHITESPACE || $token[0] === T_COMMENT || $token[0] === T_FUNCTION)) {
                        $code .= $token[1];
                        if ($token[0] === T_FUNCTION) {
                            $state = 'function';
                        }
                    } else {
                        $code = '';
                        $state = 'start';
                    }
                    break;
                case 'function':
                    if ($is_array) {
                        $code .= $token[1];
                        if ($token[0] === T_STRING) {
                            $state = 'named_function';
                            $code = '';
                        }
                    } else {
                        $code .= $token;
                        if ($token === '(') {
                            $state = 'closure';
                        }
                    }
                    break;
                case 'named_function':
                    if (!$is_array) {
                        if ($token === '{') {
                            $open++;
                        } elseif ($token === '}') {
                            if (--$open === 0) {
                                $state = 'start';
                            }
                        }
                    }
                    break;
                case 'closure':
                    if ($is_array) {
                        switch ($token[0]) {
                            case T_LINE:
                                $token[1] = $token[2] - $line + $lineAdd;
                                break;
                            case T_FILE:
                                $token[1] = $_file;
                                break;
                            case T_DIR:
                                $token[1] = $_dir;
                                break;
                            case T_NS_C:
                                $token[1] = $_namespace;
                                break;
                            case T_CLASS_C:
                                $token[1] = $_class;
                                break;
                            case T_FUNC_C:
                                $token[1] = $_function;
                                break;
                            case T_METHOD_C:
                                $token[1] = $_method;
                                break;
                            case T_COMMENT:
                                if (substr($token[1], 0, 8) === '#trackme') {
                                    $timestamp = time();
                                    $token[1] = '/**' . PHP_EOL;
                                    $token[1] .= '* Date      : ' . date(DATE_W3C, $timestamp) . PHP_EOL;
                                    $token[1] .= '* Timestamp : ' . $timestamp . PHP_EOL;
                                    $token[1] .= '* Line      : ' . ($line + 1) . PHP_EOL;
                                    $token[1] .= '* File      : ' . $_file . PHP_EOL . '*/' . PHP_EOL;
                                    $lineAdd += 5;
                                }
                                break;
                            case T_VARIABLE:
                                if ($token[1] == '$this') {
                                    $isUsingThisObject = true;
                                }
                                break;
                            case T_USE:
                                $state = 'use';
                                break;
                            case T_CURLY_OPEN:
                            case T_DOLLAR_OPEN_CURLY_BRACES:
                                $open++;
                                break;
                            case T_NS_SEPARATOR:
                            case T_STRING:
                                $buffer = $name = $token[1];
                                $new_key_word = false;
                                $state = 'name';
                                break 2;
                            case T_STATIC:
                                $isUsingScope = true;
                                break;
                            case T_NEW:
                                $buffer = $token[1];
                                $new_key_word = true;
                                $state = 'new';
                                break 2;
                            default:
                                if ($hasTraitSupport && $token[0] == T_TRAIT_C) {
                                    if ($_trait === null) {
                                        $startLine = $this->getStartLine();
                                        $endLine = $this->getEndLine();
                                        $structures = $this->getStructures();
                                        $_trait = '';
                                        foreach ($structures as &$struct) {
                                            if ($struct['type'] === 'trait' && $struct['start'] <= $startLine && $struct['end'] >= $endLine) {
                                                $_trait = ($ns == '' ? '' : $ns . '\\') . $struct['name'];
                                                break;
                                            }
                                        }
                                        $_trait = var_export($_trait, true);
                                    }
                                    $token[1] = $_trait;
                                }
                        }
                        $code .= $token[1];
                    } else {
                        $code .= $token;
                        if ($token === '{') {
                            $open++;
                        } elseif ($token === '}') {
                            if (--$open === 0) {
                                break 2;
                            }
                        }
                    }
                    break;
                case 'use':
                    if ($is_array) {
                        if ($token[0] === T_VARIABLE) {
                            $use[] = substr($token[1], 1);
                        }
                        $code .= $token[1];
                    } else {
                        if ($token == ')') {
                            $state = 'closure';
                        }
                        $code .= $token;
                    }
                    break;
                case 'name':
                    if ($is_array) {
                        switch ($token[0]) {
                            case T_NS_SEPARATOR:
                            case T_STRING:
                                $name .= $token[1];
                                $buffer .= $token[1];
                                break 2;
                            case T_WHITESPACE:
                                $buffer .= $token[1];
                                break 2;
                        }
                    }
                    if ($name[0] == '\\' || ($selfOrStatic = $name == 'static' || $name == 'self')) {
                        $code .= $buffer . ($is_array ? $token[1] : $token);
                        if ($selfOrStatic) {
                            $isUsingScope = true;
                        }
                    } elseif ($new_key_word || $is_array && ($token[0] == T_VARIABLE || $token[0] == T_DOUBLE_COLON)) {
                        $suffix = substr($buffer, strlen(rtrim($buffer)));
                        if ($classes === null) {
                            $classes = $this->getClasses();
                        }
                        if (isset($classes[$name])) {
                            $name = $classes[$name];
                        } else {
                            $name = $nsf . '\\' . $name;
                        }
                        $code .= $name . $suffix . ($is_array ? $token[1] : $token);
                    } elseif (!$is_array && $token === '(') {
                        $suffix = substr($buffer, strlen(rtrim($buffer)));
                        if ($functions === null) {
                            $functions = $this->getFunctions();
                        }
                        if (isset($functions[$name])) {
                            $name = $functions[$name];
                        }
                        $code .= $name . $suffix . ($is_array ? $token[1] : $token);
                    } else {
                        if ($constants === null) {
                            $constants = $this->getConstants();
                        }
                        if (isset($constants[$name])) {
                            $suffix = substr($buffer, strlen(rtrim($buffer)));
                            $name = $constants[$name];
                            $code .= $name . $suffix . ($is_array ? $token[1] : $token);
                        } else {
                            $code .= $buffer . ($is_array ? $token[1] : $token);
                        }
                    }
                    $state = 'closure';
                    break;
                case 'new':
                    if ($is_array) {
                        switch ($token[0]) {
                            case T_WHITESPACE:
                                $buffer .= $token[1];
                                break;
                            case T_NS_SEPARATOR:
                            case T_STRING:
                                $code .= $buffer;
                                $buffer = $name = $token[1];
                                $state = 'name';
                                break 2;
                            default:
                                $code .= $buffer . $token[1];
                                $state = 'closure';
                                break;
                        }
                    } else {
                        $code .= $buffer . $token;
                        $state = 'closure';
                    }
                    break;
            }
        }
        $this->isBindingRequired = $isUsingThisObject;
        $this->isScopeRequired = $isUsingScope;
        $this->code = $code;
        $this->useVariables = empty($use) ? $use : array_intersect_key($this->getStaticVariables(), array_flip($use));
        return $this->code;
    }

Usage Example

Ejemplo n.º 1
0
 /**
  * Analyzer a given closure.
  *
  * @param Closure $closure
  *
  * @return array
  */
 public function analyze(Closure $closure)
 {
     $reflection = new ReflectionClosure($closure);
     $scope = $reflection->getClosureScopeClass();
     $data = ['reflection' => $reflection, 'code' => $reflection->getCode(), 'hasThis' => $reflection->isBindingRequired(), 'context' => $reflection->getUseVariables(), 'hasRefs' => false, 'binding' => $reflection->getClosureThis(), 'scope' => $scope ? $scope->getName() : null, 'isStatic' => $reflection->isStatic()];
     return $data;
 }