php MVC 控制器的示例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1737868/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
An example of an MVC controller
提问by BDuelz
I have been reading a lot about how and why to use an MVC approach in an application. I have seen and understand examples of a Model, I have seen and understand examples of the View.... but I am STILL kind of fuzzy on the controller. I would really love to see a thorough enough example of a controller(s). (in PHP if possible, but any language will help)
我已经阅读了很多关于如何以及为什么在应用程序中使用 MVC 方法的文章。我已经看到并理解了模型的例子,我已经看到并理解了视图的例子......但我仍然对控制器有点模糊。我真的很想看到一个足够完整的控制器示例。(如果可能,使用 PHP,但任何语言都会有所帮助)
Thank you.
谢谢你。
PS: It would also be great if I could see an example of an index.php page, which decides which controller to use and how.
PS:如果我能看到一个 index.php 页面的例子,它会决定使用哪个控制器以及如何使用。
EDIT:I know what the job of the controller is, I just don't really understand how to accomplish this in OOP.
编辑:我知道控制器的工作是什么,我只是不明白如何在 OOP 中完成它。
回答by Franz
Request example
请求示例
Put something like this in your index.php:
把这样的东西放在你的index.php:
<?php
// Holds data like $baseUrl etc.
include 'config.php';
$requestUrl = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$requestString = substr($requestUrl, strlen($baseUrl));
$urlParams = explode('/', $requestString);
// TODO: Consider security (see comments)
$controllerName = ucfirst(array_shift($urlParams)).'Controller';
$actionName = strtolower(array_shift($urlParams)).'Action';
// Here you should probably gather the rest as params
// Call the action
$controller = new $controllerName;
$controller->$actionName();
Really basic, but you get the idea... (I also didn't take care of loading the controller class, but I guess that can be done either via autoloading or you know how to do it.)
非常基本,但你明白了......(我也没有负责加载控制器类,但我想这可以通过自动加载来完成,或者你知道如何去做。)
Simple controller example(controllers/login.php):
简单的控制器示例(controllers/login.php):
<?php
class LoginController
{
function loginAction()
{
$username = $this->request->get('username');
$password = $this->request->get('password');
$this->loadModel('users');
if ($this->users->validate($username, $password))
{
$userData = $this->users->fetch($username);
AuthStorage::save($username, $userData);
$this->redirect('secret_area');
}
else
{
$this->view->message = 'Invalid login';
$this->view->render('error');
}
}
function logoutAction()
{
if (AuthStorage::logged())
{
AuthStorage::remove();
$this->redirect('index');
}
else
{
$this->view->message = 'You are not logged in.';
$this->view->render('error');
}
}
}
As you see, the controller takes care of the "flow" of the application - the so-called application logic. It does not take care about data storage and presentation. It rather gathers all the necessary data (depending on the current request) and assigns it to the view...
如您所见,控制器负责应用程序的“流程”——即所谓的应用程序逻辑。它不关心数据存储和呈现。它而是收集所有必要的数据(取决于当前请求)并将其分配给视图......
Note that this would not work with any framework I know, but I'm sure you know what the functions are supposed to do.
请注意,这不适用于我知道的任何框架,但我确定您知道这些功能应该做什么。
回答by djna
Imagine three screens in a UI, a screen where a user enters some search criteria, a screen where a list of summaries of matching records is displayed and a screen where, once a record is selected it is displayed for editing. There will be some logic relating to the initial search on the lines of
想象一下 UI 中的三个屏幕,一个是用户输入搜索条件的屏幕,一个是显示匹配记录摘要列表的屏幕,一个是选择记录后显示进行编辑的屏幕。将有一些与初始搜索相关的逻辑
if search criteria are matched by no records
redisplay criteria screen, with message saying "none found"
else if search criteria are matched by exactly one record
display edit screen with chosen record
else (we have lots of records)
display list screen with matching records
Where should that logic go? Not in the view or model surely? Hence this is the job of the controller. The controller would also be responsible for taking the criteria and invoking the Model method for the search.
这个逻辑应该去哪里?肯定不在视图或模型中?因此,这是控制器的工作。控制器还将负责采用标准并调用 Model 方法进行搜索。
回答by David
<?php
class Router {
protected $uri;
protected $controller;
protected $action;
protected $params;
protected $route;
protected $method_prefix;
/**
*
* @return mixed
*/
function getUri() {
return $this->uri;
}
/**
*
* @return mixed
*/
function getController() {
return $this->controller;
}
/**
*
* @return mixed
*/
function getAction() {
return $this->action;
}
/**
*
* @return mixed
*/
function getParams() {
return $this->params;
}
function getRoute() {
return $this->route;
}
function getMethodPrefix() {
return $this->method_prefix;
}
public function __construct($uri) {
$this->uri = urldecode(trim($uri, "/"));
//defaults
$routes = Config::get("routes");
$this->route = Config::get("default_route");
$this->controller = Config::get("default_controller");
$this->action = Config::get("default_action");
$this->method_prefix= isset($routes[$this->route]) ? $routes[$this->route] : '';
//get uri params
$uri_parts = explode("?", $this->uri);
$path = $uri_parts[0];
$path_parts = explode("/", $path);
if(count($path_parts)){
//get route
if(in_array(strtolower(current($path_parts)), array_keys($routes))){
$this->route = strtolower(current($path_parts));
$this->method_prefix = isset($routes[$this->route]) ? $routes[$this->route] : '';
array_shift($path_parts);
}
//get controller
if(current($path_parts)){
$this->controller = strtolower(current($path_parts));
array_shift($path_parts);
}
//get action
if(current($path_parts)){
$this->action = strtolower(current($path_parts));
array_shift($path_parts);
}
//reset is for parameters
//$this->params = $path_parts;
//processing params from url to array
$aParams = array();
if(current($path_parts)){
for($i=0; $i<count($path_parts); $i++){
$aParams[$path_parts[$i]] = isset($path_parts[$i+1]) ? $path_parts[$i+1] : null;
$i++;
}
}
$this->params = (object)$aParams;
}
}
}
回答by David
<?php
class App {
protected static $router;
public static function getRouter() {
return self::$router;
}
public static function run($uri) {
self::$router = new Router($uri);
//get controller class
$controller_class = ucfirst(self::$router->getController()) . 'Controller';
//get method
$controller_method = strtolower((self::$router->getMethodPrefix() != "" ? self::$router->getMethodPrefix() . '_' : '') . self::$router->getAction());
if(method_exists($controller_class, $controller_method)){
$controller_obj = new $controller_class();
$view_path = $controller_obj->$controller_method();
$view_obj = new View($controller_obj->getData(), $view_path);
$content = $view_obj->render();
}else{
throw new Exception("Called method does not exists!");
}
//layout
$route_path = self::getRouter()->getRoute();
$layout = ROOT . '/views/layout/' . $route_path . '.phtml';
$layout_view_obj = new View(compact('content'), $layout);
echo $layout_view_obj->render();
}
public static function redirect($uri){
print("<script>window.location.href='{$uri}'</script>");
exit();
}
}
回答by David
- Create folder structure
- Setup .htaccess & virtual hosts
- Create config class to build config array
- 创建文件夹结构
- 设置 .htaccess 和虚拟主机
- 创建配置类以构建配置数组
Controller
控制器
- Create router class with protected non static, with getters
- Create init.php with config include & autoload and include paths (lib, controlelrs,models)
- Create config file with routes, default values (route, controllers, action)
- Set values in router - defaults
- Set uri paths, explode the uri and set route, controller, action, params ,process params.
- Create app class to run the application by passing uri - (protected router obj, run func)
- Create controller parent class to inherit all other controllers (protected data, model, params - non static) set data, params in constructor.
- Create controller and extend with above parent class and add default method.
- Call the controller class and method in run function. method has to be with prefix.
- Call the method if exisist
- 使用受保护的非静态创建路由器类,使用 getter
- 使用配置包含和自动加载并包含路径(lib、controlelrs、models)创建 init.php
- 使用路由、默认值(路由、控制器、操作)创建配置文件
- 在路由器中设置值 - 默认值
- 设置 uri 路径,分解 uri 并设置路由、控制器、动作、参数、流程参数。
- 通过传递uri来创建应用程序类来运行应用程序 - (protected router obj, run func)
- 创建控制器父类以继承所有其他控制器(受保护的数据、模型、参数 - 非静态)设置数据、构造函数中的参数。
- 创建控制器并扩展上面的父类并添加默认方法。
- 在 run 函数中调用控制器类和方法。方法必须带有前缀。
- 如果存在则调用该方法
Views
观看次数
- Create a parent view class to generate views. (data, path) with default path, set controller, , render funcs to return the full tempalte path (non static)
- Create render function with ob_start(), ob_get_clean to return and send the content to browser.
- Change app class to parse the data to view class. if path is returned, pass to view class too.
- Layouts..layout is depend on router. re parse the layout html to view and render
- 创建一个父视图类来生成视图。(data, path) with default path, set controller, , render funcs to return full tempalte path (non static)
- 使用 ob_start() 创建渲染函数,ob_get_clean 返回并将内容发送到浏览器。
- 更改应用程序类以解析数据以查看类。如果返回路径,也传递给视图类。
- 布局..布局取决于路由器。重新解析布局html进行查看和渲染
回答by irenecarnay
Please check this:
请检查这个:
<?php
global $conn;
require_once("../config/database.php");
require_once("../config/model.php");
$conn= new Db;
$event = isset($_GET['event']) ? $_GET['event'] : '';
if ($event == 'save') {
if($conn->insert("employee", $_POST)){
$data = array(
'success' => true,
'message' => 'Saving Successful!',
);
}
echo json_encode($data);
}
if ($event == 'update') {
if($conn->update("employee", $_POST, "id=" . $_POST['id'])){
$data = array(
'success' => true,
'message' => 'Update Successful!',
);
}
echo json_encode($data);
}
if ($event == 'delete') {
if($conn->delete("employee", "id=" . $_POST['id'])){
$data = array(
'success' => true,
'message' => 'Delete Successful!',
);
}
echo json_encode($data);
}
if ($event == 'edit') {
$data = $conn->get("select * from employee where id={$_POST['id']};")[0];
echo json_encode($data);
}
?>

