[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12 namespace Symfony\Component\HttpKernel\Profiler; 13 14 @trigger_error('The '.__NAMESPACE__.'\RedisProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED); 15 16 /** 17 * RedisProfilerStorage stores profiling information in Redis. 18 * 19 * @author Andrej Hudec <pulzarraider@gmail.com> 20 * @author Stephane PY <py.stephane1@gmail.com> 21 * 22 * @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0. 23 * Use {@link FileProfilerStorage} instead. 24 */ 25 class RedisProfilerStorage implements ProfilerStorageInterface 26 { 27 const TOKEN_PREFIX = 'sf_profiler_'; 28 29 const REDIS_OPT_SERIALIZER = 1; 30 const REDIS_OPT_PREFIX = 2; 31 const REDIS_SERIALIZER_NONE = 0; 32 const REDIS_SERIALIZER_PHP = 1; 33 34 protected $dsn; 35 protected $lifetime; 36 37 /** 38 * @var \Redis 39 */ 40 private $redis; 41 42 /** 43 * @param string $dsn A data source name 44 * @param string $username Not used 45 * @param string $password Not used 46 * @param int $lifetime The lifetime to use for the purge 47 */ 48 public function __construct($dsn, $username = '', $password = '', $lifetime = 86400) 49 { 50 $this->dsn = $dsn; 51 $this->lifetime = (int) $lifetime; 52 } 53 54 /** 55 * {@inheritdoc} 56 */ 57 public function find($ip, $url, $limit, $method, $start = null, $end = null) 58 { 59 $indexName = $this->getIndexName(); 60 61 if (!$indexContent = $this->getValue($indexName, self::REDIS_SERIALIZER_NONE)) { 62 return array(); 63 } 64 65 $profileList = array_reverse(explode("\n", $indexContent)); 66 $result = array(); 67 68 foreach ($profileList as $item) { 69 if (0 === $limit) { 70 break; 71 } 72 73 if ('' == $item) { 74 continue; 75 } 76 77 $values = explode("\t", $item, 7); 78 list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = $values; 79 $statusCode = isset($values[6]) ? $values[6] : null; 80 81 $itemTime = (int) $itemTime; 82 83 if ($ip && false === strpos($itemIp, $ip) || $url && false === strpos($itemUrl, $url) || $method && false === strpos($itemMethod, $method)) { 84 continue; 85 } 86 87 if (!empty($start) && $itemTime < $start) { 88 continue; 89 } 90 91 if (!empty($end) && $itemTime > $end) { 92 continue; 93 } 94 95 $result[] = array( 96 'token' => $itemToken, 97 'ip' => $itemIp, 98 'method' => $itemMethod, 99 'url' => $itemUrl, 100 'time' => $itemTime, 101 'parent' => $itemParent, 102 'status_code' => $statusCode, 103 ); 104 --$limit; 105 } 106 107 return $result; 108 } 109 110 /** 111 * {@inheritdoc} 112 */ 113 public function purge() 114 { 115 // delete only items from index 116 $indexName = $this->getIndexName(); 117 118 $indexContent = $this->getValue($indexName, self::REDIS_SERIALIZER_NONE); 119 120 if (!$indexContent) { 121 return false; 122 } 123 124 $profileList = explode("\n", $indexContent); 125 126 $result = array(); 127 128 foreach ($profileList as $item) { 129 if ('' == $item) { 130 continue; 131 } 132 133 if (false !== $pos = strpos($item, "\t")) { 134 $result[] = $this->getItemName(substr($item, 0, $pos)); 135 } 136 } 137 138 $result[] = $indexName; 139 140 return $this->delete($result); 141 } 142 143 /** 144 * {@inheritdoc} 145 */ 146 public function read($token) 147 { 148 if (empty($token)) { 149 return false; 150 } 151 152 $profile = $this->getValue($this->getItemName($token), self::REDIS_SERIALIZER_PHP); 153 154 if (false !== $profile) { 155 $profile = $this->createProfileFromData($token, $profile); 156 } 157 158 return $profile; 159 } 160 161 /** 162 * {@inheritdoc} 163 */ 164 public function write(Profile $profile) 165 { 166 $data = array( 167 'token' => $profile->getToken(), 168 'parent' => $profile->getParentToken(), 169 'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()), 170 'data' => $profile->getCollectors(), 171 'ip' => $profile->getIp(), 172 'method' => $profile->getMethod(), 173 'url' => $profile->getUrl(), 174 'time' => $profile->getTime(), 175 ); 176 177 $profileIndexed = false !== $this->getValue($this->getItemName($profile->getToken())); 178 179 if ($this->setValue($this->getItemName($profile->getToken()), $data, $this->lifetime, self::REDIS_SERIALIZER_PHP)) { 180 if (!$profileIndexed) { 181 // Add to index 182 $indexName = $this->getIndexName(); 183 184 $indexRow = implode("\t", array( 185 $profile->getToken(), 186 $profile->getIp(), 187 $profile->getMethod(), 188 $profile->getUrl(), 189 $profile->getTime(), 190 $profile->getParentToken(), 191 $profile->getStatusCode(), 192 ))."\n"; 193 194 return $this->appendValue($indexName, $indexRow, $this->lifetime); 195 } 196 197 return true; 198 } 199 200 return false; 201 } 202 203 /** 204 * Internal convenience method that returns the instance of Redis. 205 * 206 * @return \Redis 207 * 208 * @throws \RuntimeException 209 */ 210 protected function getRedis() 211 { 212 if (null === $this->redis) { 213 $data = parse_url($this->dsn); 214 215 if (false === $data || !isset($data['scheme']) || 'redis' !== $data['scheme'] || !isset($data['host']) || !isset($data['port'])) { 216 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)); 217 } 218 219 if (!\extension_loaded('redis')) { 220 throw new \RuntimeException('RedisProfilerStorage requires that the redis extension is loaded.'); 221 } 222 223 $redis = new \Redis(); 224 $redis->connect($data['host'], $data['port']); 225 226 if (isset($data['path'])) { 227 $redis->select(substr($data['path'], 1)); 228 } 229 230 if (isset($data['pass'])) { 231 $redis->auth($data['pass']); 232 } 233 234 $redis->setOption(self::REDIS_OPT_PREFIX, self::TOKEN_PREFIX); 235 236 $this->redis = $redis; 237 } 238 239 return $this->redis; 240 } 241 242 /** 243 * Set instance of the Redis. 244 * 245 * @param \Redis $redis 246 */ 247 public function setRedis($redis) 248 { 249 $this->redis = $redis; 250 } 251 252 private function createProfileFromData($token, $data, $parent = null) 253 { 254 $profile = new Profile($token); 255 $profile->setIp($data['ip']); 256 $profile->setMethod($data['method']); 257 $profile->setUrl($data['url']); 258 $profile->setTime($data['time']); 259 $profile->setCollectors($data['data']); 260 261 if (!$parent && $data['parent']) { 262 $parent = $this->read($data['parent']); 263 } 264 265 if ($parent) { 266 $profile->setParent($parent); 267 } 268 269 foreach ($data['children'] as $token) { 270 if (!$token) { 271 continue; 272 } 273 274 if (!$childProfileData = $this->getValue($this->getItemName($token), self::REDIS_SERIALIZER_PHP)) { 275 continue; 276 } 277 278 $profile->addChild($this->createProfileFromData($token, $childProfileData, $profile)); 279 } 280 281 return $profile; 282 } 283 284 /** 285 * Gets the item name. 286 * 287 * @param string $token 288 * 289 * @return string 290 */ 291 private function getItemName($token) 292 { 293 $name = $token; 294 295 if ($this->isItemNameValid($name)) { 296 return $name; 297 } 298 299 return false; 300 } 301 302 /** 303 * Gets the name of the index. 304 * 305 * @return string 306 */ 307 private function getIndexName() 308 { 309 $name = 'index'; 310 311 if ($this->isItemNameValid($name)) { 312 return $name; 313 } 314 315 return false; 316 } 317 318 private function isItemNameValid($name) 319 { 320 $length = \strlen($name); 321 322 if ($length > 2147483648) { 323 throw new \RuntimeException(sprintf('The Redis item key "%s" is too long (%s bytes). Allowed maximum size is 2^31 bytes.', $name, $length)); 324 } 325 326 return true; 327 } 328 329 /** 330 * Retrieves an item from the Redis server. 331 * 332 * @param string $key 333 * @param int $serializer 334 * 335 * @return mixed 336 */ 337 private function getValue($key, $serializer = self::REDIS_SERIALIZER_NONE) 338 { 339 $redis = $this->getRedis(); 340 $redis->setOption(self::REDIS_OPT_SERIALIZER, $serializer); 341 342 return $redis->get($key); 343 } 344 345 /** 346 * Stores an item on the Redis server under the specified key. 347 * 348 * @param string $key 349 * @param mixed $value 350 * @param int $expiration 351 * @param int $serializer 352 * 353 * @return bool 354 */ 355 private function setValue($key, $value, $expiration = 0, $serializer = self::REDIS_SERIALIZER_NONE) 356 { 357 $redis = $this->getRedis(); 358 $redis->setOption(self::REDIS_OPT_SERIALIZER, $serializer); 359 360 return $redis->setex($key, $expiration, $value); 361 } 362 363 /** 364 * Appends data to an existing item on the Redis server. 365 * 366 * @param string $key 367 * @param string $value 368 * @param int $expiration 369 * 370 * @return bool 371 */ 372 private function appendValue($key, $value, $expiration = 0) 373 { 374 $redis = $this->getRedis(); 375 $redis->setOption(self::REDIS_OPT_SERIALIZER, self::REDIS_SERIALIZER_NONE); 376 377 if ($redis->exists($key)) { 378 $redis->append($key, $value); 379 380 return $redis->setTimeout($key, $expiration); 381 } 382 383 return $redis->setex($key, $expiration, $value); 384 } 385 386 /** 387 * Removes the specified keys. 388 * 389 * @return bool 390 */ 391 private function delete(array $keys) 392 { 393 return (bool) $this->getRedis()->delete($keys); 394 } 395 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |