Browse Source

[HttpKernel] refactored HTTP exceptions to be more flexible

Kris Wallsmith 14 năm trước cách đây
mục cha
commit
10dc18b28b

+ 11 - 0
src/Symfony/Component/HttpKernel/Debug/ExceptionListener.php

@@ -16,6 +16,7 @@ use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
 use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
 use Symfony\Component\HttpKernel\HttpKernelInterface;
 use Symfony\Component\HttpKernel\Exception\FlattenException;
+use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
 use Symfony\Component\HttpFoundation\Request;
 
 /**
@@ -63,6 +64,16 @@ class ExceptionListener
             'format'      => 0 === strncasecmp(PHP_SAPI, 'cli', 3) ? 'txt' : $request->getRequestFormat(),
         );
 
+        $attributes += $exception instanceof HttpExceptionInterface ? array(
+            'code'    => $exception->getStatusCode(),
+            'message' => $exception->getStatusMessage(),
+            'headers' => $exception->getHeaders(),
+        ) : array(
+            'code'    => 500,
+            'message' => 'Internal Server Error',
+            'headers' => array(),
+        );
+
         $request = $request->duplicate(null, null, $attributes);
 
         try {

+ 48 - 0
src/Symfony/Component/HttpKernel/Exception/BaseHttpException.php

@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Exception;
+
+/**
+ * BaseHttpException.
+ *
+ * @author Kris Wallsmith <kris@symfony.com>
+ */
+abstract class BaseHttpException extends \RuntimeException implements HttpExceptionInterface
+{
+    protected $statusCode;
+    protected $statusMessage;
+    protected $headers;
+
+    public function __construct($statusCode, $statusMessage, array $headers = array(), $message = null, $code = 0, \Exception $previous = null)
+    {
+        $this->statusCode = $statusCode;
+        $this->statusMessage = $statusMessage;
+        $this->headers = $headers;
+
+        parent::__construct($message, 0, $previous);
+    }
+
+    public function getStatusCode()
+    {
+        return $this->statusCode;
+    }
+
+    public function getStatusMessage()
+    {
+        return $this->statusMessage;
+    }
+
+    public function getHeaders()
+    {
+        return $this->headers;
+    }
+}

+ 41 - 0
src/Symfony/Component/HttpKernel/Exception/HttpExceptionInterface.php

@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Exception;
+
+/**
+ * Interface for HTTP error exceptions.
+ *
+ * @author Kris Wallsmith <kris@symfony.com>
+ */
+interface HttpExceptionInterface
+{
+    /**
+     * Returns the status code.
+     *
+     * @return integer An HTTP response status code
+     */
+    function getStatusCode();
+
+    /**
+     * Return the status message.
+     *
+     * @return string An HTTP response status message
+     */
+    function getStatusMessage();
+
+    /**
+     * Returns response headers.
+     *
+     * @return array Response headers
+     */
+    function getHeaders();
+}

+ 39 - 0
src/Symfony/Component/HttpKernel/Exception/MethodNotAllowedHttpException.php

@@ -0,0 +1,39 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Exception;
+
+/**
+ * MethodNotAllowedHttpException.
+ *
+ * @author Kris Wallsmith <kris@symfony.com>
+ */
+class MethodNotAllowedHttpException extends BaseHttpException
+{
+    /**
+     * Constructor.
+     *
+     * WARNING: The status message will be sent as a response header
+     * regardless of debug mode.
+     *
+     * @param array     $allow         An array of allowed methods
+     * @param string    $statusMessage The HTTP response status message
+     * @param string    $message       The internal exception message
+     * @param integer   $code          The internal exception code
+     * @param Exception $previous      The previous exception
+     */
+    public function __construct(array $allow, $statusMessage = 'Method Not Allowed', $message = null, $code = 0, \Exception $previous = null)
+    {
+        $headers = array('Allow' => strtoupper(implode(', ', $allow)));
+
+        parent::__construct(405, $statusMessage, $headers, $message ?: $statusMessage, $code, $previous);
+    }
+}

+ 14 - 3
src/Symfony/Component/HttpKernel/Exception/NotFoundHttpException.php

@@ -16,10 +16,21 @@ namespace Symfony\Component\HttpKernel\Exception;
  *
  * @author Fabien Potencier <fabien@symfony.com>
  */
-class NotFoundHttpException extends \RuntimeException
+class NotFoundHttpException extends BaseHttpException
 {
-    public function __construct($message = 'Not Found', \Exception $previous = null)
+    /**
+     * Constructor.
+     *
+     * WARNING: The status message will be sent as a response header
+     * regardless of debug mode.
+     *
+     * @param string    $statusMessage The HTTP response status message
+     * @param string    $message       The internal exception message
+     * @param integer   $code          The internal exception code
+     * @param Exception $previous      The previous exception
+     */
+    public function __construct($statusMessage = 'Not Found', $message = null, $code = 0, \Exception $previous = null)
     {
-        parent::__construct($message, 404, $previous);
+        parent::__construct(404, $statusMessage, array(), $message ?: $statusMessage, $code, $previous);
     }
 }