[ Index ]

PHP Cross Reference of phpBB-3.3.2-deutsch

title

Body

[close]

/vendor/zendframework/zend-code/src/Reflection/ -> FunctionReflection.php (source)

   1  <?php
   2  /**
   3   * Zend Framework (http://framework.zend.com/)
   4   *
   5   * @link      http://github.com/zendframework/zf2 for the canonical source repository
   6   * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
   7   * @license   http://framework.zend.com/license/new-bsd New BSD License
   8   */
   9  
  10  namespace Zend\Code\Reflection;
  11  
  12  use ReflectionFunction;
  13  
  14  use function array_shift;
  15  use function array_slice;
  16  use function count;
  17  use function file;
  18  use function implode;
  19  use function preg_match;
  20  use function preg_quote;
  21  use function preg_replace;
  22  use function sprintf;
  23  use function strlen;
  24  use function strrpos;
  25  use function substr;
  26  use function var_export;
  27  
  28  class FunctionReflection extends ReflectionFunction implements ReflectionInterface
  29  {
  30      /**
  31       * Constant use in @MethodReflection to display prototype as an array
  32       */
  33      const PROTOTYPE_AS_ARRAY = 'prototype_as_array';
  34  
  35      /**
  36       * Constant use in @MethodReflection to display prototype as a string
  37       */
  38      const PROTOTYPE_AS_STRING = 'prototype_as_string';
  39  
  40      /**
  41       * Get function DocBlock
  42       *
  43       * @throws Exception\InvalidArgumentException
  44       * @return DocBlockReflection
  45       */
  46      public function getDocBlock()
  47      {
  48          if ('' == ($comment = $this->getDocComment())) {
  49              throw new Exception\InvalidArgumentException(sprintf(
  50                  '%s does not have a DocBlock',
  51                  $this->getName()
  52              ));
  53          }
  54  
  55          $instance = new DocBlockReflection($comment);
  56  
  57          return $instance;
  58      }
  59  
  60      /**
  61       * Get start line (position) of function
  62       *
  63       * @param  bool $includeDocComment
  64       * @return int
  65       */
  66      public function getStartLine($includeDocComment = false)
  67      {
  68          if ($includeDocComment) {
  69              if ($this->getDocComment() != '') {
  70                  return $this->getDocBlock()->getStartLine();
  71              }
  72          }
  73  
  74          return parent::getStartLine();
  75      }
  76  
  77      /**
  78       * Get contents of function
  79       *
  80       * @param  bool   $includeDocBlock
  81       * @return string
  82       */
  83      public function getContents($includeDocBlock = true)
  84      {
  85          $fileName = $this->getFileName();
  86          if (false === $fileName) {
  87              return '';
  88          }
  89  
  90          $startLine = $this->getStartLine();
  91          $endLine = $this->getEndLine();
  92  
  93          // eval'd protect
  94          if (preg_match('#\((\d+)\) : eval\(\)\'d code$#', $fileName, $matches)) {
  95              $fileName = preg_replace('#\(\d+\) : eval\(\)\'d code$#', '', $fileName);
  96              $startLine = $endLine = $matches[1];
  97          }
  98  
  99          $lines = array_slice(
 100              file($fileName, FILE_IGNORE_NEW_LINES),
 101              $startLine - 1,
 102              $endLine - ($startLine - 1),
 103              true
 104          );
 105  
 106          $functionLine = implode("\n", $lines);
 107  
 108          $content = '';
 109          if ($this->isClosure()) {
 110              preg_match('#function\s*\([^\)]*\)\s*(use\s*\([^\)]+\))?\s*\{(.*\;)?\s*\}#s', $functionLine, $matches);
 111              if (isset($matches[0])) {
 112                  $content = $matches[0];
 113              }
 114          } else {
 115              $name = substr($this->getName(), strrpos($this->getName(), '\\') + 1);
 116              preg_match(
 117                  '#function\s+' . preg_quote($name) . '\s*\([^\)]*\)\s*{([^{}]+({[^}]+})*[^}]+)?}#',
 118                  $functionLine,
 119                  $matches
 120              );
 121              if (isset($matches[0])) {
 122                  $content = $matches[0];
 123              }
 124          }
 125  
 126          $docComment = $this->getDocComment();
 127  
 128          return $includeDocBlock && $docComment ? $docComment . "\n" . $content : $content;
 129      }
 130  
 131      /**
 132       * Get method prototype
 133       *
 134       * @param string $format
 135       * @return array|string
 136       */
 137      public function getPrototype($format = FunctionReflection::PROTOTYPE_AS_ARRAY)
 138      {
 139          $returnType = 'mixed';
 140          $docBlock = $this->getDocBlock();
 141          if ($docBlock) {
 142              $return = $docBlock->getTag('return');
 143              $returnTypes = $return->getTypes();
 144              $returnType = count($returnTypes) > 1 ? implode('|', $returnTypes) : $returnTypes[0];
 145          }
 146  
 147          $prototype = [
 148              'namespace' => $this->getNamespaceName(),
 149              'name'      => substr($this->getName(), strlen($this->getNamespaceName()) + 1),
 150              'return'    => $returnType,
 151              'arguments' => [],
 152          ];
 153  
 154          $parameters = $this->getParameters();
 155          foreach ($parameters as $parameter) {
 156              $prototype['arguments'][$parameter->getName()] = [
 157                  'type'     => $parameter->detectType(),
 158                  'required' => ! $parameter->isOptional(),
 159                  'by_ref'   => $parameter->isPassedByReference(),
 160                  'default'  => $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null,
 161              ];
 162          }
 163  
 164          if ($format == FunctionReflection::PROTOTYPE_AS_STRING) {
 165              $line = $prototype['return'] . ' ' . $prototype['name'] . '(';
 166              $args = [];
 167              foreach ($prototype['arguments'] as $name => $argument) {
 168                  $argsLine = ($argument['type']
 169                      ? $argument['type'] . ' '
 170                      : '') . ($argument['by_ref'] ? '&' : '') . '$' . $name;
 171                  if (! $argument['required']) {
 172                      $argsLine .= ' = ' . var_export($argument['default'], true);
 173                  }
 174                  $args[] = $argsLine;
 175              }
 176              $line .= implode(', ', $args);
 177              $line .= ')';
 178  
 179              return $line;
 180          }
 181  
 182          return $prototype;
 183      }
 184  
 185      /**
 186       * Get function parameters
 187       *
 188       * @return ParameterReflection[]
 189       */
 190      public function getParameters()
 191      {
 192          $phpReflections  = parent::getParameters();
 193          $zendReflections = [];
 194          while ($phpReflections && ($phpReflection = array_shift($phpReflections))) {
 195              $instance          = new ParameterReflection($this->getName(), $phpReflection->getName());
 196              $zendReflections[] = $instance;
 197              unset($phpReflection);
 198          }
 199          unset($phpReflections);
 200  
 201          return $zendReflections;
 202      }
 203  
 204      /**
 205       * Get return type tag
 206       *
 207       * @throws Exception\InvalidArgumentException
 208       * @return DocBlockReflection
 209       */
 210      public function getReturn()
 211      {
 212          $docBlock = $this->getDocBlock();
 213          if (! $docBlock->hasTag('return')) {
 214              throw new Exception\InvalidArgumentException(
 215                  'Function does not specify an @return annotation tag; cannot determine return type'
 216              );
 217          }
 218  
 219          $tag    = $docBlock->getTag('return');
 220  
 221          return new DocBlockReflection('@return ' . $tag->getDescription());
 222      }
 223  
 224      /**
 225       * Get method body
 226       *
 227       * @return string|false
 228       */
 229      public function getBody()
 230      {
 231          $fileName = $this->getFileName();
 232          if (false === $fileName) {
 233              throw new Exception\InvalidArgumentException(
 234                  'Cannot determine internals functions body'
 235              );
 236          }
 237  
 238          $startLine = $this->getStartLine();
 239          $endLine = $this->getEndLine();
 240  
 241          // eval'd protect
 242          if (preg_match('#\((\d+)\) : eval\(\)\'d code$#', $fileName, $matches)) {
 243              $fileName = preg_replace('#\(\d+\) : eval\(\)\'d code$#', '', $fileName);
 244              $startLine = $endLine = $matches[1];
 245          }
 246  
 247          $lines = array_slice(
 248              file($fileName, FILE_IGNORE_NEW_LINES),
 249              $startLine - 1,
 250              $endLine - ($startLine - 1),
 251              true
 252          );
 253  
 254          $functionLine = implode("\n", $lines);
 255  
 256          $body = false;
 257          if ($this->isClosure()) {
 258              preg_match('#function\s*\([^\)]*\)\s*(use\s*\([^\)]+\))?\s*\{(.*\;)\s*\}#s', $functionLine, $matches);
 259              if (isset($matches[2])) {
 260                  $body = $matches[2];
 261              }
 262          } else {
 263              $name = substr($this->getName(), strrpos($this->getName(), '\\') + 1);
 264              preg_match('#function\s+' . $name . '\s*\([^\)]*\)\s*{([^{}]+({[^}]+})*[^}]+)}#', $functionLine, $matches);
 265              if (isset($matches[1])) {
 266                  $body = $matches[1];
 267              }
 268          }
 269  
 270          return $body;
 271      }
 272  
 273      /**
 274       * @return string
 275       */
 276      public function toString()
 277      {
 278          return $this->__toString();
 279      }
 280  
 281      /**
 282       * Required due to bug in php
 283       *
 284       * @return string
 285       */
 286      public function __toString()
 287      {
 288          return parent::__toString();
 289      }
 290  }


Generated: Wed Nov 11 20:28:18 2020 Cross-referenced by PHPXref 0.7.1