当uri未在路由器类

时间:2015-12-05 10:58:54

标签: php model-view-controller

我从昨天开始尝试这个,但找不到任何资源来帮助我。我正在构建我自己的定制MVC用于学习目的。我被困在一个点,当一个uri没有在路由器类中注册时,它应该抛出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;

实施例

contactcontact/locations已在router.class.php注册,因此没有任何问题,一切正常,但uri errorexample未注册且应显示404错误来自观点的消息。

请任何帮助。

1 个答案:

答案 0 :(得分:2)

基本解决方案(但不是best)是为boolean添加返回值(Router::get())。如果处理了true,则返回的值为route;如果未处理该路由,则返回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');

旁注:这是一个“意大利面条代码”解决方案并对我非常糟糕的英语表示抱歉:(