Итак, у меня есть простой базовый класс для сервера - и я понял, что для ряда исключений, которые я выбрасываю, обработка будет достаточно согласованной для всех типов серверов (например, ошибки HTTP 4xx).
Итак, я настроил обратный вызов и обработчик по умолчанию, например:
Класс сервера:
<?php
abstract class Server
{
protected $methodsAllowed = array('POST', 'GET');
protected $requiredParameters = array();
protected function isMethodAllowed()
{
if (!isset($_SERVER['REQUEST_METHOD'])) {
$_SERVER['REQUEST_METHOD'] = 'CLI';
}
if (!in_array($_SERVER['REQUEST_METHOD'], $this->methodsAllowed)) {
throw new Exception_Server_MethodNotAllowed($_SERVER['REQUEST_METHOD'], $this->methodsAllowed);
}
}
protected function areParametersCorrect()
{
foreach ($this->requiredParameters as $parameter) {
if (!in_array($parameter, array_keys($_REQUEST))) {
throw new Exception_Server_MissingParameter('Missing parameter "' . $parameter . '" in request');
}
}
}
protected function init()
{
$this->isMethodAllowed();
$this->areParametersCorrect();
}
protected function sendXML($xml)
{
header('Content-Type: text/xml');
echo $xml;
exit;
}
abstract public function respond();
public static function exceptionHandler($exception)
{
switch (true) {
case $exception instanceof Exception_HTTP_400:
error_log($exception->getMessage());
header('HTTP/1.1 400 Not Found');
exit;
case $exception instanceof Exception_HTTP_404:
error_log($exception->getMessage());
header('HTTP/1.1 404 Not Found');
exit;
case $exception instanceof Exception_HTTP_405:
error_log($exception->getMessage());
header('HTTP/1.1 405 Method Not Allowed');
header('Allow: ' . implode(', ', $exception->getMethodsAllowed()));
exit;
}
}
}
Exception_Handler::register('Server_Factory::exceptionHandler');
class Exception_Server_MethodNotAllowed extends Exception_HTTP_405 { }
class Exception_Server_MissingParameter extends Exception_HTTP_400 { }
Обработчик по умолчанию:
class Exception_Handler
{
protected static $callbacks = array();
public static function register($callback)
{
if (!in_array($callback, self::$callbacks)) {
self::$callbacks[] = $callback;
}
}
public static function handle($exception)
{
foreach (self::$callbacks as $callback) {
call_user_func($callback, $exception);
}
}
}
set_exception_handler('Exception_Handler::handle');
Теперь - любое приложение, которое использует этот базовый класс, может переопределить обработку исключений по умолчанию, перехватывая исключения, но также допускает обработку по умолчанию.
Это хорошее решение для проектирования?
Профикак я понимаю, это - оно допускает базовое поведение и позволяет сохранять группу исключений сервера с кодом сервера, и ???
Недостатки - это использование обратных вызовов (и я нахожу PHPUnitне сообщает о покрытии обратных вызовов), и ???
NB - я, возможно, не использую лучшие методы, чтобы определить природу исключения - instanceof
«чувствовал» о правильном, но если есть лучшеЯ бы хотел то, знаешь ...