[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <[email protected]> 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\ErrorHandler\Exception; 13 14 use Symfony\Component\HttpFoundation\Exception\RequestExceptionInterface; 15 use Symfony\Component\HttpFoundation\Response; 16 use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; 17 18 /** 19 * FlattenException wraps a PHP Error or Exception to be able to serialize it. 20 * 21 * Basically, this class removes all objects from the trace. 22 * 23 * @author Fabien Potencier <[email protected]> 24 */ 25 class FlattenException 26 { 27 /** @var string */ 28 private $message; 29 30 /** @var int|string */ 31 private $code; 32 33 /** @var self|null */ 34 private $previous; 35 36 /** @var array */ 37 private $trace; 38 39 /** @var string */ 40 private $traceAsString; 41 42 /** @var string */ 43 private $class; 44 45 /** @var int */ 46 private $statusCode; 47 48 /** @var string */ 49 private $statusText; 50 51 /** @var array */ 52 private $headers; 53 54 /** @var string */ 55 private $file; 56 57 /** @var int */ 58 private $line; 59 60 /** @var string|null */ 61 private $asString; 62 63 /** 64 * @return static 65 */ 66 public static function create(\Exception $exception, int $statusCode = null, array $headers = []): self 67 { 68 return static::createFromThrowable($exception, $statusCode, $headers); 69 } 70 71 /** 72 * @return static 73 */ 74 public static function createFromThrowable(\Throwable $exception, int $statusCode = null, array $headers = []): self 75 { 76 $e = new static(); 77 $e->setMessage($exception->getMessage()); 78 $e->setCode($exception->getCode()); 79 80 if ($exception instanceof HttpExceptionInterface) { 81 $statusCode = $exception->getStatusCode(); 82 $headers = array_merge($headers, $exception->getHeaders()); 83 } elseif ($exception instanceof RequestExceptionInterface) { 84 $statusCode = 400; 85 } 86 87 if (null === $statusCode) { 88 $statusCode = 500; 89 } 90 91 if (class_exists(Response::class) && isset(Response::$statusTexts[$statusCode])) { 92 $statusText = Response::$statusTexts[$statusCode]; 93 } else { 94 $statusText = 'Whoops, looks like something went wrong.'; 95 } 96 97 $e->setStatusText($statusText); 98 $e->setStatusCode($statusCode); 99 $e->setHeaders($headers); 100 $e->setTraceFromThrowable($exception); 101 $e->setClass(\get_class($exception)); 102 $e->setFile($exception->getFile()); 103 $e->setLine($exception->getLine()); 104 105 $previous = $exception->getPrevious(); 106 107 if ($previous instanceof \Throwable) { 108 $e->setPrevious(static::createFromThrowable($previous)); 109 } 110 111 return $e; 112 } 113 114 public function toArray(): array 115 { 116 $exceptions = []; 117 foreach (array_merge([$this], $this->getAllPrevious()) as $exception) { 118 $exceptions[] = [ 119 'message' => $exception->getMessage(), 120 'class' => $exception->getClass(), 121 'trace' => $exception->getTrace(), 122 ]; 123 } 124 125 return $exceptions; 126 } 127 128 public function getStatusCode(): int 129 { 130 return $this->statusCode; 131 } 132 133 /** 134 * @return $this 135 */ 136 public function setStatusCode(int $code): self 137 { 138 $this->statusCode = $code; 139 140 return $this; 141 } 142 143 public function getHeaders(): array 144 { 145 return $this->headers; 146 } 147 148 /** 149 * @return $this 150 */ 151 public function setHeaders(array $headers): self 152 { 153 $this->headers = $headers; 154 155 return $this; 156 } 157 158 public function getClass(): string 159 { 160 return $this->class; 161 } 162 163 /** 164 * @return $this 165 */ 166 public function setClass(string $class): self 167 { 168 $this->class = false !== strpos($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class; 169 170 return $this; 171 } 172 173 public function getFile(): string 174 { 175 return $this->file; 176 } 177 178 /** 179 * @return $this 180 */ 181 public function setFile(string $file): self 182 { 183 $this->file = $file; 184 185 return $this; 186 } 187 188 public function getLine(): int 189 { 190 return $this->line; 191 } 192 193 /** 194 * @return $this 195 */ 196 public function setLine(int $line): self 197 { 198 $this->line = $line; 199 200 return $this; 201 } 202 203 public function getStatusText(): string 204 { 205 return $this->statusText; 206 } 207 208 /** 209 * @return $this 210 */ 211 public function setStatusText(string $statusText): self 212 { 213 $this->statusText = $statusText; 214 215 return $this; 216 } 217 218 public function getMessage(): string 219 { 220 return $this->message; 221 } 222 223 /** 224 * @return $this 225 */ 226 public function setMessage(string $message): self 227 { 228 if (false !== strpos($message, "@anonymous\0")) { 229 $message = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { 230 return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0]; 231 }, $message); 232 } 233 234 $this->message = $message; 235 236 return $this; 237 } 238 239 /** 240 * @return int|string int most of the time (might be a string with PDOException) 241 */ 242 public function getCode() 243 { 244 return $this->code; 245 } 246 247 /** 248 * @param int|string $code 249 * 250 * @return $this 251 */ 252 public function setCode($code): self 253 { 254 $this->code = $code; 255 256 return $this; 257 } 258 259 public function getPrevious(): ?self 260 { 261 return $this->previous; 262 } 263 264 /** 265 * @return $this 266 */ 267 public function setPrevious(?self $previous): self 268 { 269 $this->previous = $previous; 270 271 return $this; 272 } 273 274 /** 275 * @return self[] 276 */ 277 public function getAllPrevious(): array 278 { 279 $exceptions = []; 280 $e = $this; 281 while ($e = $e->getPrevious()) { 282 $exceptions[] = $e; 283 } 284 285 return $exceptions; 286 } 287 288 public function getTrace(): array 289 { 290 return $this->trace; 291 } 292 293 /** 294 * @return $this 295 */ 296 public function setTraceFromThrowable(\Throwable $throwable): self 297 { 298 $this->traceAsString = $throwable->getTraceAsString(); 299 300 return $this->setTrace($throwable->getTrace(), $throwable->getFile(), $throwable->getLine()); 301 } 302 303 /** 304 * @return $this 305 */ 306 public function setTrace(array $trace, ?string $file, ?int $line): self 307 { 308 $this->trace = []; 309 $this->trace[] = [ 310 'namespace' => '', 311 'short_class' => '', 312 'class' => '', 313 'type' => '', 314 'function' => '', 315 'file' => $file, 316 'line' => $line, 317 'args' => [], 318 ]; 319 foreach ($trace as $entry) { 320 $class = ''; 321 $namespace = ''; 322 if (isset($entry['class'])) { 323 $parts = explode('\\', $entry['class']); 324 $class = array_pop($parts); 325 $namespace = implode('\\', $parts); 326 } 327 328 $this->trace[] = [ 329 'namespace' => $namespace, 330 'short_class' => $class, 331 'class' => $entry['class'] ?? '', 332 'type' => $entry['type'] ?? '', 333 'function' => $entry['function'] ?? null, 334 'file' => $entry['file'] ?? null, 335 'line' => $entry['line'] ?? null, 336 'args' => isset($entry['args']) ? $this->flattenArgs($entry['args']) : [], 337 ]; 338 } 339 340 return $this; 341 } 342 343 private function flattenArgs(array $args, int $level = 0, int &$count = 0): array 344 { 345 $result = []; 346 foreach ($args as $key => $value) { 347 if (++$count > 1e4) { 348 return ['array', '*SKIPPED over 10000 entries*']; 349 } 350 if ($value instanceof \__PHP_Incomplete_Class) { 351 $result[$key] = ['incomplete-object', $this->getClassNameFromIncomplete($value)]; 352 } elseif (\is_object($value)) { 353 $result[$key] = ['object', \get_class($value)]; 354 } elseif (\is_array($value)) { 355 if ($level > 10) { 356 $result[$key] = ['array', '*DEEP NESTED ARRAY*']; 357 } else { 358 $result[$key] = ['array', $this->flattenArgs($value, $level + 1, $count)]; 359 } 360 } elseif (null === $value) { 361 $result[$key] = ['null', null]; 362 } elseif (\is_bool($value)) { 363 $result[$key] = ['boolean', $value]; 364 } elseif (\is_int($value)) { 365 $result[$key] = ['integer', $value]; 366 } elseif (\is_float($value)) { 367 $result[$key] = ['float', $value]; 368 } elseif (\is_resource($value)) { 369 $result[$key] = ['resource', get_resource_type($value)]; 370 } else { 371 $result[$key] = ['string', (string) $value]; 372 } 373 } 374 375 return $result; 376 } 377 378 private function getClassNameFromIncomplete(\__PHP_Incomplete_Class $value): string 379 { 380 $array = new \ArrayObject($value); 381 382 return $array['__PHP_Incomplete_Class_Name']; 383 } 384 385 public function getTraceAsString(): string 386 { 387 return $this->traceAsString; 388 } 389 390 /** 391 * @return $this 392 */ 393 public function setAsString(?string $asString): self 394 { 395 $this->asString = $asString; 396 397 return $this; 398 } 399 400 public function getAsString(): string 401 { 402 if (null !== $this->asString) { 403 return $this->asString; 404 } 405 406 $message = ''; 407 $next = false; 408 409 foreach (array_reverse(array_merge([$this], $this->getAllPrevious())) as $exception) { 410 if ($next) { 411 $message .= 'Next '; 412 } else { 413 $next = true; 414 } 415 $message .= $exception->getClass(); 416 417 if ('' != $exception->getMessage()) { 418 $message .= ': '.$exception->getMessage(); 419 } 420 421 $message .= ' in '.$exception->getFile().':'.$exception->getLine(). 422 "\nStack trace:\n".$exception->getTraceAsString()."\n\n"; 423 } 424 425 return rtrim($message); 426 } 427 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |