我从昨天开始尝试,但找不到任何资源来帮助我。为了学习,我正在构建自己的自定义MVC。当一个uri没有在router类中注册时,它会抛出一条404错误消息。我尝试了很多技巧,但都没用。
router.php
$router->get('', 'homeController@index', 'home');
$router->get('contact', 'contactController@index', 'contact');
$router->get('contact/locations', 'contactController@locations', 'contact');
controller.class.php
class Controller{
public function controller($ContollerMethod = null){
$contoller = explode('@', $ContollerMethod);
if( !empty($contoller[0]) ){
return $contoller[0];
}
}
public function method($ContollerMethod = null){
$method = explode('@', $ContollerMethod);
if( !empty($method[1]) ){
return $method[1];
}
}
public function view($view = null){
if( empty($view) ){
$view = 'page';
}
$file = site_path() . '/app/views/' . $view . '.php';
require_once($file);
}
public function render($ContollerMethod = null, $view = null, $data = array() ){
$controller = $this->controller($ContollerMethod);
$method = $this->method($ContollerMethod);
if( file_exists(site_path() . '/app/controllers/' . $controller . '.php') ){
require_once(site_path() . '/app/controllers/' . $controller . '.php');
if( !method_exists($controller, $method) ){
die('No method ''<em>' . $method . '</em>'' exists on Controller ''<em>' . $controller . '</em>''');
}
$params = array();
call_user_func_array( [$controller, $method], $params );
$master = site_path() . '/app/views/master.php';
if( file_exists($master) ){
require_once( site_path() . '/app/views/master.php');
}
} else {
die('Controller ''<em>' . $controller . '</em>'' doesn''t exists');
}
}
}
router.class.php
class Router extends Controller{
public function get($uri = null, $ContollerMethod = null, $view = null){
$permalink = get_permalink();
if( $permalink == $uri and strtolower($_SERVER['REQUEST_METHOD']) == 'get' ){
$this->render($ContollerMethod, $view);
}
}
public function post($uri = null, $ContollerMethod = null, $view = null){
$permalink = get_permalink();
if( $permalink == $uri and strtolower($_SERVER['REQUEST_METHOD']) == 'post' ){
}
}
public function ajax($uri = null, $ContollerMethod = null, $view = null){
$permalink = get_permalink();
if( $permalink == $uri and !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'){
}
}
}
$router = new Router;
示例:
contact
、contact/locations
已在router.class.php
中注册,因此没有问题,一切正常,但uri errorexample
未注册,它应该显示视图中的404错误消息。
请帮忙。
基本解决方案(但不是最好的)是为Router::get()
添加返回值(boolean
)。如果处理了route
,则返回的值为true
;如果未处理,则返回false
router.php
// route handlers found
$founded = 0;
if( $router->get('', 'homeController@index', 'home') ){
$founded++;
}
if( $router->get('contact', 'contactController@index', 'contact') ){
$founded++;
}
if( $router->get('contact/locations', 'contactController@locations', 'contact') ){
$founded++;
}
// no handlers found... the route is handled by error controller
if( $founded <= 0 ){
$router->get('404', 'errorController@index', '404');
}
controller.class.php
class Router extends Controller{
/**
* Return true if a controller is found for handle the route
* @return boolean
*/
public function get($uri = null, $ContollerMethod = null, $view = null){
$permalink = get_permalink();
if( $permalink == $uri and strtolower($_SERVER['REQUEST_METHOD']) == 'get' ){
return $this->render($ContollerMethod, $view); // return true if a controller and a view are found
}
return false; // added this line
}
//.............
在controller::render()
中实现相同的loginc
controller.class.php
class Controller{
/**
* Return true if a controller is found
* @return boolean
*/
public function render($ContollerMethod = null, $view = null, $data = array() ){
$controller = $this->controller($ContollerMethod);
$method = $this->method($ContollerMethod);
if( file_exists(site_path() . '/app/controllers/' . $controller . '.php') ){
require_once(site_path() . '/app/controllers/' . $controller . '.php');
if( !method_exists($controller, $method) ){
die('No method ''<em>' . $method . '</em>'' exists on Controller ''<em>' . $controller . '</em>''');
}
$params = array();
call_user_func_array( [$controller, $method], $params );
$master = site_path() . '/app/views/master.php';
if( file_exists($master) ){
require_once( site_path() . '/app/views/master.php');
}
return true; // add this line
} else {
die('Controller ''<em>' . $controller . '</em>'' doesn''t exists');
}
return false; // add this line
}
// .....................................
现在。。。我的两美分
在您的逻辑中,每次都会调用每个路由器,即使找到了控制器。一种优化是,如果找到控制器,则停止该过程,例如:
router.php
if( $router->get('', 'homeController@index', 'home') ){
exit;
}
if( $router->get('contact', 'contactController@index', 'contact') ){
exit;
}
if( $router->get('contact/locations', 'contactController@locations', 'contact') ){
exit;
}
// no handlers found... the route is handled by error controller
$router->get('404', 'errorController@index', '404');
旁注:这是一个"意大利面条代码"解决方案,很抱歉我的英语很差:(