我在我的网站上使用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。
我的索引和联系页面有自己的控制器,因为它们是静态页面。但是服务和关于页面是从我的数据库中提取的,因此是动态的。所以我创建了一个控制器,将其命名为content并只传递获取我想要的任何页面所需的参数。
我想让我的网址更加一致。如果我转到服务或网页,我想使用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);
}
}
}
答案 0 :(得分:1)
为了做到这一点,您应该将您的网址映射到控制器,请查看以下示例:
// route mapping 'route' => 'controller:method'
$routes = array(
'/service' => 'Content:service'
);
也可以是任何php可调用函数。
回答版本2:
兄弟在最简单的模式下,让我们说你有一个像下面这样的实体:
uri: varchar(255), title: varchar(255), meta_tags: varchar(500), body: text
并且可以访问StaticPageController
来自www.example.com/page/
网址的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));
}
参数传递给控制器之后的内容
{{1}}
我希望这会有所帮助。