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