Вообще эту тему можно было бы отнести к инфраструктуре, но я выделил отдельно, и сейчас поймете почему.
Для начала нужно привести в порядок фронт-контроллер:
Core/FrontController.php
<?php
namespace Core;
/**
* Класс FrontController
*
* NOTE: Requires PHP version 5.5 or later
* @author phpforum.su
* @copyright © 2016
* @license WTFPL (http://www.wtfpl.net)
*/
class FrontController
{
/**
* Запуск
*
* @param object $config
*
* @return void
*/
public static function run($config = null)
{
$page = takeGET('page');
$controllerName = self::prepare($page);
$controller = '\App\Controllers\\'. $controllerName .'Controller';
$action = takeGET('action', 'index');
$actionName = self::prepare($action);
$action = 'action'. $actionName;
self::callApplication($controller, $action);
}
/**
* Подготавливает имена контроллера и экшена
*
* @param string $name
*
* @return string
*/
protected static function prepare($name)
{
$name = preg_replace('~[^a-z0-9_]~i', '', $name);
return ucfirst(strtolower($name));
}
/**
* Вызывает контроллер и экшен
*
* @param string $controller
* @param string $action
*
* @return void
*/
protected static function callApplication($controller, $action)
{
if (method_exists($controller, $action)) {
$controller::$action();
} else {
print('404');
}
}
}
Ну а теперь непосредственно к ошибкам. Самая важная из них - 404. Скрипт реагирует на отсутствие запрашиваемого функционала, но этого недостаточно. Нужно красиво оформить эту страничку.
И вот почему я выделил эту тему отдельно. Раз это обычная страница, то и не стоит особо мудрить. Нужно просто сделать контроллер. Пока тоже заглушку. Заодно будет понятно, как устроены и запускаются контроллеры приложения.
App/Controllers/ErrorController.php
<?php
namespace App\Controllers;
class ErrorController
{
public static function action404()
{
header("HTTP/1.1 404 Not Found");
exit('404');
}
}
Ну и соответственно вызвать его, если ничего не найдено:
Core/FrontController.php
/**
* Вызывает контроллер и экшен
*
* @param string $controller
* @param string $action
*
* @return void
*/
protected static function callApplication($controller, $action)
{
if (method_exists($controller, $action)) {
$controller::$action();
} else {
\App\Controllers\ErrorController::action404();
}
}
Но это еще не все. Было бы слишком расточительно использовать целый контроллер для 404. Можно напихать в него разные варианты ошибок. К примеру 500:
App/Controllers/ErrorController.php
<?php
namespace App\Controllers;
class ErrorController
{
public static function action404()
{
header("HTTP/1.1 404 Not Found");
exit('404');
}
public static function action500()
{
header("HTTP/1.1 500 Internal Server Error");
exit('500');
}
}
Ну а чтобы это заработало, нужно сделать две вещи. Первая - зарегистрировать обработчик ошибок. А так, как у нас используется дебаггер, нужно сделать это опционально:
<?php
namespace Core;
use App\Controllers\ErrorController;
/**
* Класс FrontController
*
* NOTE: Requires PHP version 5.5 or later
* @author phpforum.su
* @copyright © 2016
* @license WTFPL (http://www.wtfpl.net)
*/
class FrontController
{
/**
* Запуск
*
* @param object $config
*
* @return void
*/
public static function run($config = null)
{
$config = is_object($config) ? $config->getConfig() : [];
// Регистрируем внутренний обработчик
if (isset($config['debug']) && false === $config['debug']) {
set_error_handler(['\Core\FrontController', 'error500']);
}
$page = takeGET('page');
$controllerName = self::prepare($page);
$controller = '\App\Controllers\\'. $controllerName .'Controller';
$action = takeGET('action', 'index');
$actionName = self::prepare($action);
$action = 'action'. $actionName;
self::callApplication($controller, $action);
}
/**
* Внутренний обработчик ошибки скрипта
*
* @return void
*/
public static function error500($code)
{
if (error_reporting() & $code) {
ErrorController::action500();
exit();
}
}
/**
* Подготавливает имена контроллера и экшена
*
* @param string $name
*
* @return string
*/
protected static function prepare($name)
{
$name = preg_replace('~[^a-z0-9_]~i', '', $name);
return ucfirst(strtolower($name));
}
/**
* Вызывает контроллер и экшен
*
* @param string $controller
* @param string $action
*
* @return void
*/
protected static function callApplication($controller, $action)
{
if (method_exists($controller, $action)) {
$controller::$action();
} else {
ErrorController::action404();
}
}
}
Соответственно появилась первая настройка:
App/config.php
<?php
return [
'debug' => false, // true
];
А раз появилась такая опция, то можно ей же отключать дебаггер:
www/index.php
<?php
error_reporting(E_ALL & ~E_NOTICE);
// Автозагрузчик классов
require __DIR__ .'/../Core/Autoloader.php';
// Конфигурация
$config = new \Core\Configurator(__DIR__ .'/../App/config.php');
/**
* Режим отладки.
* @TODO To clean in release
*/
define('BUGSNARE', $config->getConfig()['debug']);
include_once __DIR__ .'/../vendor/PhpBugsnare/setup.php';
// Функции по умолчанию
include_once __DIR__ .'/../Core/default.php';
\Core\FrontController::run($config);
И втарая. Не гоже реагировать пятисотой ошибкой на нотисы. А поэтому нужно выставить более мягкий уровень ошибок:
www/index.php
<?php
error_reporting(E_ALL & ~E_NOTICE);
На фатальные это кончно не среагирует, но логические и варнинги отловит.
_____________
Если вам недостаточно собственных заблуждений, можно расширить их мнениями экспертов.
Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.
Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.