Verzeichnisstruktur phpBB-3.3.16


Veröffentlicht
27.04.2026

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

FunctionReflection.php

Zuletzt modifiziert: 01.05.2026, 11:27 - Dateigröße: 8.31 KiB


 001  <?php
 002  /**
 003   * Zend Framework (http://framework.zend.com/)
 004   *
 005   * @link      http://github.com/zendframework/zf2 for the canonical source repository
 006   * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
 007   * @license   http://framework.zend.com/license/new-bsd New BSD License
 008   */
 009   
 010  namespace Zend\Code\Reflection;
 011   
 012  use ReflectionFunction;
 013   
 014  use function array_shift;
 015  use function array_slice;
 016  use function count;
 017  use function file;
 018  use function implode;
 019  use function preg_match;
 020  use function preg_quote;
 021  use function preg_replace;
 022  use function sprintf;
 023  use function strlen;
 024  use function strrpos;
 025  use function substr;
 026  use function var_export;
 027   
 028  class FunctionReflection extends ReflectionFunction implements ReflectionInterface
 029  {
 030      /**
 031       * Constant use in @MethodReflection to display prototype as an array
 032       */
 033      const PROTOTYPE_AS_ARRAY = 'prototype_as_array';
 034   
 035      /**
 036       * Constant use in @MethodReflection to display prototype as a string
 037       */
 038      const PROTOTYPE_AS_STRING = 'prototype_as_string';
 039   
 040      /**
 041       * Get function DocBlock
 042       *
 043       * @throws Exception\InvalidArgumentException
 044       * @return DocBlockReflection
 045       */
 046      public function getDocBlock()
 047      {
 048          if ('' == ($comment = $this->getDocComment())) {
 049              throw new Exception\InvalidArgumentException(sprintf(
 050                  '%s does not have a DocBlock',
 051                  $this->getName()
 052              ));
 053          }
 054   
 055          $instance = new DocBlockReflection($comment);
 056   
 057          return $instance;
 058      }
 059   
 060      /**
 061       * Get start line (position) of function
 062       *
 063       * @param  bool $includeDocComment
 064       * @return int
 065       */
 066      public function getStartLine($includeDocComment = false)
 067      {
 068          if ($includeDocComment) {
 069              if ($this->getDocComment() != '') {
 070                  return $this->getDocBlock()->getStartLine();
 071              }
 072          }
 073   
 074          return parent::getStartLine();
 075      }
 076   
 077      /**
 078       * Get contents of function
 079       *
 080       * @param  bool   $includeDocBlock
 081       * @return string
 082       */
 083      public function getContents($includeDocBlock = true)
 084      {
 085          $fileName = $this->getFileName();
 086          if (false === $fileName) {
 087              return '';
 088          }
 089   
 090          $startLine = $this->getStartLine();
 091          $endLine = $this->getEndLine();
 092   
 093          // eval'd protect
 094          if (preg_match('#\((\d+)\) : eval\(\)\'d code$#', $fileName, $matches)) {
 095              $fileName = preg_replace('#\(\d+\) : eval\(\)\'d code$#', '', $fileName);
 096              $startLine = $endLine = $matches[1];
 097          }
 098   
 099          $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  }
 291