我的网站使用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));
}
我希望这能有所帮助。