[ Index ] |
PHP Cross Reference of phpBB-3.1.12-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\Debug; 13 14 use Symfony\Component\HttpFoundation\Response; 15 use Symfony\Component\Debug\Exception\FlattenException; 16 17 /** 18 * ExceptionHandler converts an exception to a Response object. 19 * 20 * It is mostly useful in debug mode to replace the default PHP/XDebug 21 * output with something prettier and more useful. 22 * 23 * As this class is mainly used during Kernel boot, where nothing is yet 24 * available, the Response content is always HTML. 25 * 26 * @author Fabien Potencier <fabien@symfony.com> 27 */ 28 class ExceptionHandler 29 { 30 private $debug; 31 private $charset; 32 33 public function __construct($debug = true, $charset = 'UTF-8') 34 { 35 $this->debug = $debug; 36 $this->charset = $charset; 37 } 38 39 /** 40 * Registers the exception handler. 41 * 42 * @param bool $debug 43 * 44 * @return ExceptionHandler The registered exception handler 45 */ 46 public static function register($debug = true) 47 { 48 $handler = new static($debug); 49 50 set_exception_handler(array($handler, 'handle')); 51 52 return $handler; 53 } 54 55 /** 56 * Sends a response for the given Exception. 57 * 58 * If you have the Symfony HttpFoundation component installed, 59 * this method will use it to create and send the response. If not, 60 * it will fallback to plain PHP functions. 61 * 62 * @param \Exception $exception An \Exception instance 63 * 64 * @see sendPhpResponse() 65 * @see createResponse() 66 */ 67 public function handle(\Exception $exception) 68 { 69 if (class_exists('Symfony\Component\HttpFoundation\Response')) { 70 $this->createResponse($exception)->send(); 71 } else { 72 $this->sendPhpResponse($exception); 73 } 74 } 75 76 /** 77 * Sends the error associated with the given Exception as a plain PHP response. 78 * 79 * This method uses plain PHP functions like header() and echo to output 80 * the response. 81 * 82 * @param \Exception|FlattenException $exception An \Exception instance 83 */ 84 public function sendPhpResponse($exception) 85 { 86 if (!$exception instanceof FlattenException) { 87 $exception = FlattenException::create($exception); 88 } 89 90 if (!headers_sent()) { 91 header(sprintf('HTTP/1.0 %s', $exception->getStatusCode())); 92 foreach ($exception->getHeaders() as $name => $value) { 93 header($name.': '.$value, false); 94 } 95 header('Content-Type: text/html; charset='.$this->charset); 96 } 97 98 echo $this->decorate($this->getContent($exception), $this->getStylesheet($exception)); 99 } 100 101 /** 102 * Creates the error Response associated with the given Exception. 103 * 104 * @param \Exception|FlattenException $exception An \Exception instance 105 * 106 * @return Response A Response instance 107 */ 108 public function createResponse($exception) 109 { 110 if (!$exception instanceof FlattenException) { 111 $exception = FlattenException::create($exception); 112 } 113 114 return Response::create($this->decorate($this->getContent($exception), $this->getStylesheet($exception)), $exception->getStatusCode(), $exception->getHeaders())->setCharset($this->charset); 115 } 116 117 /** 118 * Gets the HTML content associated with the given exception. 119 * 120 * @param FlattenException $exception A FlattenException instance 121 * 122 * @return string The content as a string 123 */ 124 public function getContent(FlattenException $exception) 125 { 126 switch ($exception->getStatusCode()) { 127 case 404: 128 $title = 'Sorry, the page you are looking for could not be found.'; 129 break; 130 default: 131 $title = 'Whoops, looks like something went wrong.'; 132 } 133 134 $content = ''; 135 $flags = PHP_VERSION_ID >= 50400 ? ENT_QUOTES | ENT_SUBSTITUTE : ENT_QUOTES; 136 if ($this->debug) { 137 try { 138 $count = count($exception->getAllPrevious()); 139 $total = $count + 1; 140 foreach ($exception->toArray() as $position => $e) { 141 $ind = $count - $position + 1; 142 $class = $this->abbrClass($e['class']); 143 $message = nl2br(htmlspecialchars($e['message'], $flags, $this->charset)); 144 $content .= sprintf(<<<'EOF' 145 <div class="block_exception clear_fix"> 146 <h2><span>%d/%d</span> %s: %s</h2> 147 </div> 148 <div class="block"> 149 <ol class="traces list_exception"> 150 151 EOF 152 , $ind, $total, $class, $message); 153 foreach ($e['trace'] as $trace) { 154 $content .= ' <li>'; 155 if ($trace['function']) { 156 $content .= sprintf('at %s%s%s(%s)', $this->abbrClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args'])); 157 } 158 if (isset($trace['file']) && isset($trace['line'])) { 159 if ($linkFormat = ini_get('xdebug.file_link_format')) { 160 $link = strtr($linkFormat, array('%f' => $trace['file'], '%l' => $trace['line'])); 161 $link = htmlspecialchars($link, $flags, $this->charset); 162 $content .= sprintf(' in <a href="%s" title="Go to source">%s line %d</a>', $link, htmlspecialchars($trace['file'], $flags, $this->charset), $trace['line']); 163 } else { 164 $content .= sprintf(' in %s line %d', htmlspecialchars($trace['file'], $flags, $this->charset), $trace['line']); 165 } 166 } 167 $content .= "</li>\n"; 168 } 169 170 $content .= " </ol>\n</div>\n"; 171 } 172 } catch (\Exception $e) { 173 // something nasty happened and we cannot throw an exception anymore 174 if ($this->debug) { 175 $title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), htmlspecialchars($e->getMessage(), $flags, $this->charset)); 176 } else { 177 $title = 'Whoops, looks like something went wrong.'; 178 } 179 } 180 } 181 182 return <<<EOF 183 <div id="sf-resetcontent" class="sf-reset"> 184 <h1>$title</h1> 185 $content 186 </div> 187 EOF; 188 } 189 190 /** 191 * Gets the stylesheet associated with the given exception. 192 * 193 * @param FlattenException $exception A FlattenException instance 194 * 195 * @return string The stylesheet as a string 196 */ 197 public function getStylesheet(FlattenException $exception) 198 { 199 return <<<'EOF' 200 .sf-reset { font: 11px Verdana, Arial, sans-serif; color: #333 } 201 .sf-reset .clear { clear:both; height:0; font-size:0; line-height:0; } 202 .sf-reset .clear_fix:after { display:block; height:0; clear:both; visibility:hidden; } 203 .sf-reset .clear_fix { display:inline-block; } 204 .sf-reset * html .clear_fix { height:1%; } 205 .sf-reset .clear_fix { display:block; } 206 .sf-reset, .sf-reset .block { margin: auto } 207 .sf-reset abbr { border-bottom: 1px dotted #000; cursor: help; } 208 .sf-reset p { font-size:14px; line-height:20px; color:#868686; padding-bottom:20px } 209 .sf-reset strong { font-weight:bold; } 210 .sf-reset a { color:#6c6159; } 211 .sf-reset a img { border:none; } 212 .sf-reset a:hover { text-decoration:underline; } 213 .sf-reset em { font-style:italic; } 214 .sf-reset h1, .sf-reset h2 { font: 20px Georgia, "Times New Roman", Times, serif } 215 .sf-reset h2 span { background-color: #fff; color: #333; padding: 6px; float: left; margin-right: 10px; } 216 .sf-reset .traces li { font-size:12px; padding: 2px 4px; list-style-type:decimal; margin-left:20px; } 217 .sf-reset .block { background-color:#FFFFFF; padding:10px 28px; margin-bottom:20px; 218 -webkit-border-bottom-right-radius: 16px; 219 -webkit-border-bottom-left-radius: 16px; 220 -moz-border-radius-bottomright: 16px; 221 -moz-border-radius-bottomleft: 16px; 222 border-bottom-right-radius: 16px; 223 border-bottom-left-radius: 16px; 224 border-bottom:1px solid #ccc; 225 border-right:1px solid #ccc; 226 border-left:1px solid #ccc; 227 } 228 .sf-reset .block_exception { background-color:#ddd; color: #333; padding:20px; 229 -webkit-border-top-left-radius: 16px; 230 -webkit-border-top-right-radius: 16px; 231 -moz-border-radius-topleft: 16px; 232 -moz-border-radius-topright: 16px; 233 border-top-left-radius: 16px; 234 border-top-right-radius: 16px; 235 border-top:1px solid #ccc; 236 border-right:1px solid #ccc; 237 border-left:1px solid #ccc; 238 overflow: hidden; 239 word-wrap: break-word; 240 } 241 .sf-reset li a { background:none; color:#868686; text-decoration:none; } 242 .sf-reset li a:hover { background:none; color:#313131; text-decoration:underline; } 243 .sf-reset ol { padding: 10px 0; } 244 .sf-reset h1 { background-color:#FFFFFF; padding: 15px 28px; margin-bottom: 20px; 245 -webkit-border-radius: 10px; 246 -moz-border-radius: 10px; 247 border-radius: 10px; 248 border: 1px solid #ccc; 249 } 250 EOF; 251 } 252 253 private function decorate($content, $css) 254 { 255 return <<<EOF 256 <!DOCTYPE html> 257 <html> 258 <head> 259 <meta charset="UTF-8" /> 260 <meta name="robots" content="noindex,nofollow" /> 261 <style> 262 /* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html */ 263 html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;} 264 265 html { background: #eee; padding: 10px } 266 img { border: 0; } 267 #sf-resetcontent { width:970px; margin:0 auto; } 268 $css 269 </style> 270 </head> 271 <body> 272 $content 273 </body> 274 </html> 275 EOF; 276 } 277 278 private function abbrClass($class) 279 { 280 $parts = explode('\\', $class); 281 282 return sprintf('<abbr title="%s">%s</abbr>', $class, array_pop($parts)); 283 } 284 285 /** 286 * Formats an array as a string. 287 * 288 * @param array $args The argument array 289 * 290 * @return string 291 */ 292 private function formatArgs(array $args) 293 { 294 if (PHP_VERSION_ID >= 50400) { 295 $flags = ENT_QUOTES | ENT_SUBSTITUTE; 296 } else { 297 $flags = ENT_QUOTES; 298 } 299 $result = array(); 300 foreach ($args as $key => $item) { 301 if ('object' === $item[0]) { 302 $formattedValue = sprintf('<em>object</em>(%s)', $this->abbrClass($item[1])); 303 } elseif ('array' === $item[0]) { 304 $formattedValue = sprintf('<em>array</em>(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]); 305 } elseif ('string' === $item[0]) { 306 $formattedValue = sprintf("'%s'", htmlspecialchars($item[1], $flags, $this->charset)); 307 } elseif ('null' === $item[0]) { 308 $formattedValue = '<em>null</em>'; 309 } elseif ('boolean' === $item[0]) { 310 $formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>'; 311 } elseif ('resource' === $item[0]) { 312 $formattedValue = '<em>resource</em>'; 313 } else { 314 $formattedValue = str_replace("\n", '', var_export(htmlspecialchars((string) $item[1], $flags, $this->charset), true)); 315 } 316 317 $result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue); 318 } 319 320 return implode(', ', $result); 321 } 322 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 11 00:25:41 2018 | Cross-referenced by PHPXref 0.7.1 |