PHP MVC-模板/加载变量问题
我正在用PHP创建一个基本的MVC结构的CMS,作为学习MVC如何工作的一种方法(因此我没有使用真正的预构建引擎)。我有一个基本的工作版本,其结构与本教程非常相似。不过,我希望视图能够自动加载,而不需要模板类。如果强烈建议这样做,我将坚持使用模板概念(如果有人能解释为什么它如此必要,我将不胜感激)。无论如何,下面是我的router类,我已经修改过它,可以自动加载控制器上的视图文件PHP MVC-模板/加载变量问题,php,oop,model-view-controller,variables,Php,Oop,Model View Controller,Variables,我正在用PHP创建一个基本的MVC结构的CMS,作为学习MVC如何工作的一种方法(因此我没有使用真正的预构建引擎)。我有一个基本的工作版本,其结构与本教程非常相似。不过,我希望视图能够自动加载,而不需要模板类。如果强烈建议这样做,我将坚持使用模板概念(如果有人能解释为什么它如此必要,我将不胜感激)。无论如何,下面是我的router类,我已经修改过它,可以自动加载控制器上的视图文件 public function loader() { /*** check the rout
public function loader() {
/*** check the route ***/
$this->getPath();
/*** if the file is not there diaf ***/
if (is_readable($this->controller_path) == false) {
$this->controller_path = $this->path.'/controller/error404.php';
$this->action_path = $this->path.'/view/error404.php';
}
/*** include the path files ***/
include $this->controller_path;
include $this->action_path;
/*** a new controller class instance ***/
$class = $this->controller . 'Controller';
$controller = new $class($this->registry);
/*** check if the action is callable ***/
if (is_callable(array($controller, $this->action)) == false) {
$action = 'index';
} else {
$action = $this->action;
}
$controller->$action();
}
/**
*
* @get the controller
*
* @access private
*
* @return void
*
*/
private function getPath() {
/*** get the route from the url ***/
$route = (empty($_GET['rt'])) ? '' : $_GET['rt'];
if (empty($route)) {
$route = 'index';
} else {
/*** get the parts of the route ***/
// mywebsite.com/controller/action
// mywebsite.com/blog/hello
$parts = explode('/', $route);
$this->controller = $parts[0];
if(isset( $parts[1])) {
$this->action = $parts[1];
}
}
if( ! $this->controller ) { $this->controller = 'index'; }
if( ! $this->action ) { $this->action = 'index'; }
/*** set the file path ***/
$this->controller_path = $this->path .'/controller/'. $this->controller . '.php';
$this->action_path = $this->path .'/view/'. $this->controller . '/'. $this->action . '.php';
}
这会阻止我的视图文件加载控制器给出的变量(教程网站对此有更好的演示),但是当设置
$This->registry->template->blog_heading='这是blog索引'代码>视图不加载它,因为template.class被绕过。基本上,我要问的是如何将template.class转换为加载函数?在我自己开发的MVC中,加载视图的工作原理与您所拥有的类似,但方式要比您链接到的示例简单得多。(当我第一次决定学习MVC时,我看了这个例子,我记得它把我搞糊涂了
基本上,在确定该文件存在之后,您只需要要求(是的,需要,我觉得在本例中,file not found是停止执行脚本的一个很好的理由)该文件
所以..与其说是整个模板类的事情(我希望我没有回避你的问题,也没有太离题),不如说这里有一个简单的例子,让一个控制器打开视图文件
<?php
class Pizza_Shop_Controller extends Base_Controller
{
public function index()
{
$data['users'] = array('bob','lisa','bertha');
$data['some_string'] = "Whoa I'm a string!";
$this->render_view('index',$data);
}
public function contact()
{
if($_POST)
{
Contact::process($_POST);
return $this->render_view('contact_success');
}
else
{
return $this->render_view('contact_form');
}
}
}
class Base_Controller
{
protected function render_view($view_name,$data = array())
{
/*
* I also think render_view should take care of loading the layout, and then inject the content into the middle of the layout file,
* so that you aren't trapping yourself to a specific layout, and repeating the header and footer inside of every view file
*/
extract($data); //places all $data variables into the local scope.. very clean and ezy ;].
require($this->root_directory.DS."$view_name.php");
}
/**********************************/
public function _no_action($view_name) //Called if there is no corresponding action
{
/* You can use method_exists to test if a method exists within the controller, if it does not exist,
* you can then call this function, and pass it the name of the view that is attempting to be opened
*/
if($this->view_exists($view_name))
{
$this->render_view($view_name,$data);
}
else
{
$this->render404();
}
}
}
在我自己开发的MVC中,加载视图的工作原理与您所拥有的类似,但比您链接到的示例要简单得多。(当我第一次决定学习MVC时,我看了这个示例,我记得它把我搞糊涂了。)
基本上,在确定该文件存在之后,您只需要要求(是的,需要,我觉得在本例中,file not found是停止执行脚本的一个很好的理由)该文件
所以..与其说是整个模板类的事情(我希望我没有回避你的问题,也没有太离题),不如说这里有一个简单的例子,让一个控制器打开视图文件
<?php
class Pizza_Shop_Controller extends Base_Controller
{
public function index()
{
$data['users'] = array('bob','lisa','bertha');
$data['some_string'] = "Whoa I'm a string!";
$this->render_view('index',$data);
}
public function contact()
{
if($_POST)
{
Contact::process($_POST);
return $this->render_view('contact_success');
}
else
{
return $this->render_view('contact_form');
}
}
}
class Base_Controller
{
protected function render_view($view_name,$data = array())
{
/*
* I also think render_view should take care of loading the layout, and then inject the content into the middle of the layout file,
* so that you aren't trapping yourself to a specific layout, and repeating the header and footer inside of every view file
*/
extract($data); //places all $data variables into the local scope.. very clean and ezy ;].
require($this->root_directory.DS."$view_name.php");
}
/**********************************/
public function _no_action($view_name) //Called if there is no corresponding action
{
/* You can use method_exists to test if a method exists within the controller, if it does not exist,
* you can then call this function, and pass it the name of the view that is attempting to be opened
*/
if($this->view_exists($view_name))
{
$this->render_view($view_name,$data);
}
else
{
$this->render404();
}
}
}
我知道现在这对你没有太大帮助,但几个月前我也遇到了同样的问题。这是基于我构建的框架:
我不确定它在哪里或如何运行,因为我已经有一段时间没有实际查看过它了,但仔细看看,加载控制器、设置变量然后加载视图的代码可能在库文件夹中。它允许您执行以下操作:
/** Controller **/
class ExampleController extends Controller {
public function index() {
$helloworld = 'Hello world';
$this->set('hello_world', $helloworld);
#Renders view automatically
}
}
/** View **/
echo $hello_world;
我知道现在这对你没有太大帮助,但几个月前我也遇到了同样的问题。这是基于我构建的框架:
我不确定它在哪里或如何运行,因为我已经有一段时间没有实际查看过它了,但仔细看看,加载控制器、设置变量然后加载视图的代码可能在库文件夹中。它允许您执行以下操作:
/** Controller **/
class ExampleController extends Controller {
public function index() {
$helloworld = 'Hello world';
$this->set('hello_world', $helloworld);
#Renders view automatically
}
}
/** View **/
echo $hello_world;
“视图只是一个哑模板”这一非常常见的误解主要是由Ruby on Rails和那些遵循其损坏的ORM模板适配器的人所延续的。我不能直截了当地说他们实现了什么作为模型视图控制器
视图应该处理MVC和受MVC启发的设计模式中的表示逻辑。这些设计模式使视图成为对象,能够处理多个模板
根据您在web应用程序中使用的受MVC启发的模式(用PHP实现经典MVC是不可能的),您的视图要么从类似控制器的结构(MVP和MVVM模式)接收数据,要么能够直接从模型层(Model2 MVC和HMVC模式)请求信息.我个人更喜欢从模型层获取数据的活动视图
下面的代码$this->registry->template->blog_heading
让人流血
p.p.S.关于如何实现纯php模板,请阅读。关于“视图只是一个哑模板”的常见误解主要是Ruby on Rails和遵循其损坏的ORM模板适配器的版本所造成的。我不能直截了当地说他们作为模型视图控制器实现了什么
视图应该处理MVC和受MVC启发的设计模式中的表示逻辑。这些设计模式使视图成为对象,能够处理多个模板
根据您在web应用程序中使用的受MVC启发的模式(用PHP实现经典MVC是不可能的),您的视图要么从类似控制器的结构(MVP和MVVM模式)接收数据,要么能够直接从模型层(Model2 MVC和HMVC模式)请求信息.我个人更喜欢从模型层获取数据的活动视图
下面的代码$this->registry->template->blog_heading
让人流血
p.p.S.关于如何实现纯php模板,请阅读。虽然这解决了变量的问题,但我认为OP需要它,以便根据控制器的操作自动加载视图。我在家里有类似的内容,我回来后会发布,但我想到时候会有答案哈哈哈,好吧。我添加了一个method调用了_no_action,表示如果没有与视图文件对应的显式操作,则会调用它。这是可行的,但我想说的唯一一件事是,您需要将其放在调用控制器的部分中。这样,如果您有50多个控制器,则不必重复该代码。哈哈。除此之外,它还可以工作!没错,它应该d可能是父控制器的一部分,并且_no_动作应该仅仅对应于控制器应该独立执行的特殊动作