我总是被教导,在编程中使用异常允许错误处理从抛出错误的对象中抽象出来。看看PHP manual,PHP似乎有一个Exception类和一个ErrorException类,表明并非所有例外都有为错误。所以,我想用它们来帮助页面重定向。我将如何使用PHP例外来定义重定向?
我想要一个硬重定向,将只发送一个头和没有页面内容。什么才是触发这个最好的方法?比方说,我有Controller
类和redirect()
方法。
如果该方法是这样的:
class Controller {
public function redirect($path) {
throw new Exception($path, 301);
}
}
...
try {
$controller->redirect('http://domain.tld/redirected');
} catch (Exception $e) {
if ($e->getCode() == 301) {
header('Location: ' . $e->getMessage());
}
}
或者这样:
class Controller {
public function redirect($path) {
header('Location: ' . $path);
throw new Exception('The page is being redirected', 301);
}
}
...
try {
$controller->redirect('http://domain.tld/redirected');
} catch (Exception $e) {
if ($e->getCode() == 301) {
// Output nothing
}
}
或者我应该创建这样一个新的类型的异常:
class RedirectException extends Exception {
protected $url;
public function __construct($url) {
parent::__construct('The redirects are coming!', 301);
$this->url = (string)$url;
}
public function getURL() {
return $this->url;
}
}
...
class Controller {
public function redirect($path) {
throw new RedirectException($path);
}
}
...
try {
$controller->redirect('http://domain.tld/redirected');
} catch (RedirectException $e) {
header('Location: ' . $e->getURL());
}
虽然我觉得所有这些都会起作用,但他们都不适合我。最后一个似乎是最接近的,因为它明确指出该URL是必需的成员。但是,像这样的例外只会有一个目的。建立一个处理所有3XX,4XX和5XX状态码的RequestException会更有意义吗?另外,消息呢?在这一点上,这只是成为无关的信息吗?
不会触及实际问题,但是如果您想以这种方式使用重定向,则最好对['headers_sent()'](http://php.net/headers_sent)进行一些检查。您的异常处理程序可能会在创建页面的任何阶段启动,并且重定向仅在发生任何输出之前发生异常时才起作用。否则,你只会得到“标题已发送”的警告,不会发生重定向。比较安全的用法是:if(headers_sent()){...输出一个重定向+ javascript document.location块...} else {header('Location:...'); }' –
感谢marc的提示,这对我来说是一个全新的东西,但是,出于好奇,为什么要做meta重定向+ JS块?只是为了更安全一面? – Kumar
@Kumar:是的,更安全的一面。如果您的异常必须执行重定向,那么添加多个重定向尝试层会使重定向发生的可能性更大。 –