PHP MVC路由>;如何创建自定义路线


PHP MVC Routing > How can I create a custom route?

我的网站使用PHP MVC,路由有问题。

当我转到索引(首页)时,我使用http://www.example.com或http://www.example.com/index.

当我转到联系人页面时,我使用http://www.example.com/contact.

当我访问服务或关于页面时,我使用http://www.example.com/content/page/services或http://www.example.com/content/page/about.

我的索引和联系人页面都有自己的控制器,因为它们是静态页面。但是服务和about页面是从我的数据库中提取的,因此是动态的。所以我创建了一个控制器,将其命名为content,并传递所需的参数来获得我想要的任何页面。

我想使我的URL更加一致。如果我转到服务或about页面,我想使用http://www.example.com/services或http://www.example.com/about.

如何更改路由以满足此要求?我最终希望能够在我的数据库中创建页面,然后用一个看起来像有自己控制器的URL来拉取页面。而不是必须调用内容控制器才能使其工作。

下面是我的控制器及其包含的方法,以及我的路由代码。

控制器:

IndexController
  function: index
ContentController
  function: page
  function: sitemap
ContactController
  function: index
  function: process

路由

class Application
{
// @var mixed Instance of the controller
private $controller;
// @var array URL parameters, will be passed to used controller-method
private $parameters = array();
// @var string Just the name of the controller, useful for checks inside the view ("where am I ?")
private $controller_name;
// @var string Just the name of the controller's method, useful for checks inside the view ("where am I ?")
private $action_name;
// Start the application, analyze URL elements, call according controller/method or relocate to fallback location
public function __construct()
{
    // Create array with URL parts in $url
    $this->splitUrl();
    // Check for controller: no controller given ? then make controller = default controller (from config)
    if (!$this->controller_name) {
        $this->controller_name = Config::get('DEFAULT_CONTROLLER');
    }
    // Check for action: no action given ? then make action = default action (from config)
    if (!$this->action_name OR (strlen($this->action_name) == 0)) {
        $this->action_name = Config::get('DEFAULT_ACTION');
    }
    // Rename controller name to real controller class/file name ("index" to "IndexController")
    $this->controller_name = ucwords($this->controller_name) . 'Controller';
    // Check if controller exists
    if (file_exists(Config::get('PATH_CONTROLLER') . $this->controller_name . '.php')) {
        // Load file and create controller
        // example: if controller would be "car", then this line would translate into: $this->car = new car();
        require Config::get('PATH_CONTROLLER') . $this->controller_name . '.php';
        $this->controller = new $this->controller_name();
        // Check for method: does such a method exist in the controller?
        if (method_exists($this->controller, $this->action_name)) {
            if (!empty($this->parameters)) {
                // Call the method and pass arguments to it
                call_user_func_array(array($this->controller, $this->action_name), $this->parameters);
            } else {
                // If no parameters are given, just call the method without parameters, like $this->index->index();
                $this->controller->{$this->action_name}();
            }
        } else {
            header('location: ' . Config::get('URL') . 'error');
        }
    } else {
        header('location: ' . Config::get('URL') . 'error');
    }
}
// Split URL
private function splitUrl()
{
    if (Request::get('url')) {
        // Split URL
        $url = trim(Request::get('url'), '/');
        $url = filter_var($url, FILTER_SANITIZE_URL);
        $url = explode('/', $url);
        // Put URL parts into according properties
        $this->controller_name = isset($url[0]) ? $url[0] : null;
        $this->action_name = isset($url[1]) ? $url[1] : null;
        // Remove controller name and action name from the split URL
        unset($url[0], $url[1]);
        // rebase array keys and store the URL parameters
        $this->parameters = array_values($url);
        }
    }
}

为了做到这一点,您应该将URL映射到控制器,请查看以下示例:

// route mapping 'route' => 'controller:method'
$routes = array(
   '/service' => 'Content:service'
);

控制器也可以是任何php可调用函数。

答案版本2:

兄弟在最简单的模式下,假设你有一个如下实体:

uri: varchar(255), title: varchar(255), meta_tags: varchar(500), body: text

并且可以从www.example.com/page/ url访问StaticPageController,并且该url之后的内容将作为uri参数传递给控制器

public function StaticPageController($uri){
  // this can return a page entity
  // that contains what ever a page needs.
  $page = $pageRepository->findByUri($uri)
  // pass it to view layer
  $this->renderView('static_page.phtml', array('page' => $page));
}

我希望这能有所帮助。