Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

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

RedisProfilerStorage.php

Zuletzt modifiziert: 09.10.2024, 12:58 - Dateigröße: 9.93 KiB


 001  <?php
 002   
 003  /*
 004   * This file is part of the Symfony package.
 005   *
 006   * (c) Fabien Potencier <fabien@symfony.com>
 007   *
 008   * For the full copyright and license information, please view the LICENSE
 009   * file that was distributed with this source code.
 010   */
 011   
 012  namespace Symfony\Component\HttpKernel\Profiler;
 013   
 014  /**
 015   * RedisProfilerStorage stores profiling information in Redis.
 016   *
 017   * @author Andrej Hudec <pulzarraider@gmail.com>
 018   * @author Stephane PY <py.stephane1@gmail.com>
 019   */
 020  class RedisProfilerStorage implements ProfilerStorageInterface
 021  {
 022      const TOKEN_PREFIX = 'sf_profiler_';
 023   
 024      const REDIS_OPT_SERIALIZER = 1;
 025      const REDIS_OPT_PREFIX = 2;
 026      const REDIS_SERIALIZER_NONE = 0;
 027      const REDIS_SERIALIZER_PHP = 1;
 028   
 029      protected $dsn;
 030      protected $lifetime;
 031   
 032      /**
 033       * @var \Redis
 034       */
 035      private $redis;
 036   
 037      /**
 038       * Constructor.
 039       *
 040       * @param string $dsn      A data source name
 041       * @param string $username Not used
 042       * @param string $password Not used
 043       * @param int    $lifetime The lifetime to use for the purge
 044       */
 045      public function __construct($dsn, $username = '', $password = '', $lifetime = 86400)
 046      {
 047          $this->dsn = $dsn;
 048          $this->lifetime = (int) $lifetime;
 049      }
 050   
 051      /**
 052       * {@inheritdoc}
 053       */
 054      public function find($ip, $url, $limit, $method, $start = null, $end = null)
 055      {
 056          $indexName = $this->getIndexName();
 057   
 058          if (!$indexContent = $this->getValue($indexName, self::REDIS_SERIALIZER_NONE)) {
 059              return array();
 060          }
 061   
 062          $profileList = array_reverse(explode("\n", $indexContent));
 063          $result = array();
 064   
 065          foreach ($profileList as $item) {
 066              if ($limit === 0) {
 067                  break;
 068              }
 069   
 070              if ($item == '') {
 071                  continue;
 072              }
 073   
 074              list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = explode("\t", $item, 6);
 075   
 076              $itemTime = (int) $itemTime;
 077   
 078              if ($ip && false === strpos($itemIp, $ip) || $url && false === strpos($itemUrl, $url) || $method && false === strpos($itemMethod, $method)) {
 079                  continue;
 080              }
 081   
 082              if (!empty($start) && $itemTime < $start) {
 083                  continue;
 084              }
 085   
 086              if (!empty($end) && $itemTime > $end) {
 087                  continue;
 088              }
 089   
 090              $result[] = array(
 091                  'token'  => $itemToken,
 092                  'ip'     => $itemIp,
 093                  'method' => $itemMethod,
 094                  'url'    => $itemUrl,
 095                  'time'   => $itemTime,
 096                  'parent' => $itemParent,
 097              );
 098              --$limit;
 099          }
 100   
 101          return $result;
 102      }
 103   
 104      /**
 105       * {@inheritdoc}
 106       */
 107      public function purge()
 108      {
 109          // delete only items from index
 110          $indexName = $this->getIndexName();
 111   
 112          $indexContent = $this->getValue($indexName, self::REDIS_SERIALIZER_NONE);
 113   
 114          if (!$indexContent) {
 115              return false;
 116          }
 117   
 118          $profileList = explode("\n", $indexContent);
 119   
 120          $result = array();
 121   
 122          foreach ($profileList as $item) {
 123              if ($item == '') {
 124                  continue;
 125              }
 126   
 127              if (false !== $pos = strpos($item, "\t")) {
 128                  $result[] = $this->getItemName(substr($item, 0, $pos));
 129              }
 130          }
 131   
 132          $result[] = $indexName;
 133   
 134          return $this->delete($result);
 135      }
 136   
 137      /**
 138       * {@inheritdoc}
 139       */
 140      public function read($token)
 141      {
 142          if (empty($token)) {
 143              return false;
 144          }
 145   
 146          $profile = $this->getValue($this->getItemName($token), self::REDIS_SERIALIZER_PHP);
 147   
 148          if (false !== $profile) {
 149              $profile = $this->createProfileFromData($token, $profile);
 150          }
 151   
 152          return $profile;
 153      }
 154   
 155      /**
 156       * {@inheritdoc}
 157       */
 158      public function write(Profile $profile)
 159      {
 160          $data = array(
 161              'token'    => $profile->getToken(),
 162              'parent'   => $profile->getParentToken(),
 163              'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()),
 164              'data'     => $profile->getCollectors(),
 165              'ip'       => $profile->getIp(),
 166              'method'   => $profile->getMethod(),
 167              'url'      => $profile->getUrl(),
 168              'time'     => $profile->getTime(),
 169          );
 170   
 171          $profileIndexed = false !== $this->getValue($this->getItemName($profile->getToken()));
 172   
 173          if ($this->setValue($this->getItemName($profile->getToken()), $data, $this->lifetime, self::REDIS_SERIALIZER_PHP)) {
 174              if (!$profileIndexed) {
 175                  // Add to index
 176                  $indexName = $this->getIndexName();
 177   
 178                  $indexRow = implode("\t", array(
 179                      $profile->getToken(),
 180                      $profile->getIp(),
 181                      $profile->getMethod(),
 182                      $profile->getUrl(),
 183                      $profile->getTime(),
 184                      $profile->getParentToken(),
 185                  ))."\n";
 186   
 187                  return $this->appendValue($indexName, $indexRow, $this->lifetime);
 188              }
 189   
 190              return true;
 191          }
 192   
 193          return false;
 194      }
 195   
 196      /**
 197       * Internal convenience method that returns the instance of Redis.
 198       *
 199       * @return \Redis
 200       *
 201       * @throws \RuntimeException
 202       */
 203      protected function getRedis()
 204      {
 205          if (null === $this->redis) {
 206              $data = parse_url($this->dsn);
 207   
 208              if (false === $data || !isset($data['scheme']) || $data['scheme'] !== 'redis' || !isset($data['host']) || !isset($data['port'])) {
 209                  throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Redis with an invalid dsn "%s". The minimal expected format is "redis://[host]:port".', $this->dsn));
 210              }
 211   
 212              if (!extension_loaded('redis')) {
 213                  throw new \RuntimeException('RedisProfilerStorage requires that the redis extension is loaded.');
 214              }
 215   
 216              $redis = new \Redis();
 217              $redis->connect($data['host'], $data['port']);
 218   
 219              if (isset($data['path'])) {
 220                  $redis->select(substr($data['path'], 1));
 221              }
 222   
 223              if (isset($data['pass'])) {
 224                  $redis->auth($data['pass']);
 225              }
 226   
 227              $redis->setOption(self::REDIS_OPT_PREFIX, self::TOKEN_PREFIX);
 228   
 229              $this->redis = $redis;
 230          }
 231   
 232          return $this->redis;
 233      }
 234   
 235      /**
 236       * Set instance of the Redis
 237       *
 238       * @param \Redis $redis
 239       */
 240      public function setRedis($redis)
 241      {
 242          $this->redis = $redis;
 243      }
 244   
 245      private function createProfileFromData($token, $data, $parent = null)
 246      {
 247          $profile = new Profile($token);
 248          $profile->setIp($data['ip']);
 249          $profile->setMethod($data['method']);
 250          $profile->setUrl($data['url']);
 251          $profile->setTime($data['time']);
 252          $profile->setCollectors($data['data']);
 253   
 254          if (!$parent && $data['parent']) {
 255              $parent = $this->read($data['parent']);
 256          }
 257   
 258          if ($parent) {
 259              $profile->setParent($parent);
 260          }
 261   
 262          foreach ($data['children'] as $token) {
 263              if (!$token) {
 264                  continue;
 265              }
 266   
 267              if (!$childProfileData = $this->getValue($this->getItemName($token), self::REDIS_SERIALIZER_PHP)) {
 268                  continue;
 269              }
 270   
 271              $profile->addChild($this->createProfileFromData($token, $childProfileData, $profile));
 272          }
 273   
 274          return $profile;
 275      }
 276   
 277      /**
 278       * Gets the item name.
 279       *
 280       * @param string $token
 281       *
 282       * @return string
 283       */
 284      private function getItemName($token)
 285      {
 286          $name = $token;
 287   
 288          if ($this->isItemNameValid($name)) {
 289              return $name;
 290          }
 291   
 292          return false;
 293      }
 294   
 295      /**
 296       * Gets the name of the index.
 297       *
 298       * @return string
 299       */
 300      private function getIndexName()
 301      {
 302          $name = 'index';
 303   
 304          if ($this->isItemNameValid($name)) {
 305              return $name;
 306          }
 307   
 308          return false;
 309      }
 310   
 311      private function isItemNameValid($name)
 312      {
 313          $length = strlen($name);
 314   
 315          if ($length > 2147483648) {
 316              throw new \RuntimeException(sprintf('The Redis item key "%s" is too long (%s bytes). Allowed maximum size is 2^31 bytes.', $name, $length));
 317          }
 318   
 319          return true;
 320      }
 321   
 322      /**
 323       * Retrieves an item from the Redis server.
 324       *
 325       * @param string $key
 326       * @param int    $serializer
 327       *
 328       * @return mixed
 329       */
 330      private function getValue($key, $serializer = self::REDIS_SERIALIZER_NONE)
 331      {
 332          $redis = $this->getRedis();
 333          $redis->setOption(self::REDIS_OPT_SERIALIZER, $serializer);
 334   
 335          return $redis->get($key);
 336      }
 337   
 338      /**
 339       * Stores an item on the Redis server under the specified key.
 340       *
 341       * @param string $key
 342       * @param mixed  $value
 343       * @param int    $expiration
 344       * @param int    $serializer
 345       *
 346       * @return bool
 347       */
 348      private function setValue($key, $value, $expiration = 0, $serializer = self::REDIS_SERIALIZER_NONE)
 349      {
 350          $redis = $this->getRedis();
 351          $redis->setOption(self::REDIS_OPT_SERIALIZER, $serializer);
 352   
 353          return $redis->setex($key, $expiration, $value);
 354      }
 355   
 356      /**
 357       * Appends data to an existing item on the Redis server.
 358       *
 359       * @param string $key
 360       * @param string $value
 361       * @param int    $expiration
 362       *
 363       * @return bool
 364       */
 365      private function appendValue($key, $value, $expiration = 0)
 366      {
 367          $redis = $this->getRedis();
 368          $redis->setOption(self::REDIS_OPT_SERIALIZER, self::REDIS_SERIALIZER_NONE);
 369   
 370          if ($redis->exists($key)) {
 371              $redis->append($key, $value);
 372   
 373              return $redis->setTimeout($key, $expiration);
 374          }
 375   
 376          return $redis->setex($key, $expiration, $value);
 377      }
 378   
 379      /**
 380       * Removes the specified keys.
 381       *
 382       * @param array $keys
 383       *
 384       * @return bool
 385       */
 386      private function delete(array $keys)
 387      {
 388          return (bool) $this->getRedis()->delete($keys);
 389      }
 390  }
 391