在本节中我们将介绍组件前台页面的请求过程。Joomla的组件是完全依据MVC模式来编写的。因此,在本章中你可以会涉及到较多的MVC相关概念。
在上一节中提到,可以在guestbook.php文件中输出我们想要输出的任何信息。但是Joomla高手是不会这样使用这个文件的。那么joomla高手是怎样使用这个文件的呢?
Joomla MVC
说明这个问题之前,先谈一下MVC.
MVC是什么?MVC是模型,视图,控制器的缩写,是一个常用的设计模式。他解决的问题就是将控制逻辑,数据,和表现层分开。以便增加程序的灵活性。
看一下系统的核心文章组件的文件结构:
我们可以清楚的看到controllers目录(及C,控制器),models目录(及M,模型),views目录(及V,视图)。当然你还看到了controller.php这个文件。
他 就很清晰的将控制逻辑的文件都放到了controllers目录下,将数据层(模型层)都放到models这个目录下,将视图层都放到了views这个目 录下了。对程序员来说,这样更加的清晰。当你想修改程序的逻辑的时候,你只需修改控制器中的文件就行了。当你不满意程序输出的外观的时候,你可以修改 views这个目下的文件。
修改入口点文件
说了这么多,估计你还是对MVC不是很理解。但这个问题不大,有一个大概的认识就行了。我们接着完善留言板组件。
修改guestbook.php(入口点文件)如下:
// 禁止直接访问这个文件 这是joomla中常用的安全机制 defined('_JEXEC') or die('you can not access this file!'); // 包含本组件根目录下的controller.php文件 我喜欢叫这个文件为主控制器文件 require_once(JPATH_COMPONENT.DS.'controller.php'); //检查是否请求了特殊控制器 if($controller = JRequest::getWord('controller')) { $path = JPATH_COMPONENT.DS.'controllers'.DS.$controller.'.php'; if(file_exists($path)) { require_once $path; } else { $controller = ''; } } //实例化控制器 $className = 'GuestBookController'.$controller; $controller = new $className(); //检查需要执行的任务 $task = JRequest::getWord('task'); // 执行任务 $controller-> execute($task); // 执行重定向 $controller->redirect();
代码说明
解释几个地方:
- JPATH_COMPONENT 这个常量是系统维护的。他代表这组件的更目录,对于本程序来说就是components/com_guestbook/这个目录
- DS表示路径分隔符。windows为“\”。Linux为"/"。也是由系统维护。
- JRequest::getWord()这个函数的功能是取得URL中包含变量的值。JRequest::getWord('controller');就是检查URL中controller变量的值
于2014-10-23日改:在joomla 3.x版本中 已经不提供DS定义了,用户需要自己定义。相关的解决方案,请参考本站论坛部分
上面代码的执行流程非常的清新。首先导入主控制器文件。然后检查是否存在特殊控制器,如果存在就加载他的实现文件。然后实例化控制器。控制器确定之后,就是检查需要执行的任务。明确了执行的任务之后,就是开始执行任务。任务执行完成之后,就执行重定向。
于2014-02-23 更正:
上面的代码执行思路非常的清新,但这是1.5的时代写代码的方法,在j2.5中,对一些操作进行更大程度上的封装(我一直认为更大的封装对程序员来说没有多少好处,隐藏了过多的细节) 下面展示一下2.5推荐的方法:
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import joomla controller library
jimport('joomla.application.component.controller');
// Get an instance of controller prefixed by Helloworld
$controller = JController::getInstance('HelloWorld');
// Perform the Request task
$input = JFactory::getApplication()->input;
$controller->execute($input->getCmd('task'));
// Redirect if set by the controller
$controller->redirect();
于2014-03-01更正:
在2.5中引入了新的方法,子控制器。将会采用控制器和任务的方式来执行任务。举例来说:task=item.add.那么joomla系统会执行特殊控制器item中的add方法。而这种特殊的task=item.add利用上面的第一种做法是不能够区分子控制的。
现在访问一下组件,下面是执行的结果:
Warning: require_once(D:\program files\wamp\www\j25/components/com_guestbook\controller.php) [function.require-once]: failed to open stream: No such file or directory in D:\program files\wamp\www\j25\components\com_guestbook\guestbook.php on line 6
Fatal error: require_once() [function.require]: Failed opening required 'D:\program files\wamp\www\j25/components/com_guestbook\controller.php' (include_path='.;C:\php5\pear') in D:\program files\wamp\www\j25\components\com_guestbook\guestbook.php on line 6
很明显我们需要新建一个文件了。在根目录下新建一个文件。文件名为controller.php(主控制器文件)
controller.php文件的内容:
//主控制器文件 controler.php defined('_JEXEC') or die ('Restricted Access'); // 导入joomla控制实现的库文件 jimport('joomla.application.component.controller'); /*** * GuestBook 的控制器 * */ //注意PHP对类名的大小写不敏感 class GuestBookController extends JController { function __construct() { parent::__construct(); } }
现在再次访问http://localhost/j25/index.php?option=com_guestbook 。下面是执行截图
刚才的PHP执行错误没有出现了,但是出现了500错误。很清楚,这个页面就是告诉我们请求的页面没有找到。我们不经要思考了,现在是在请求哪一个页面?
看一下刚才写的代码:
说一下jimport('joomla.application.componet.controller');这句话的意思是说要包含libraries\joomla\application\componet\目录下的controlelr.php这个文件。
这个文件做的事情就是从JController这个类中派生一个GuestBookController类。然后给它实现了一个构造函数。并且这个构造函数只是简单的调用了父类的构造函数。非常的简洁。
在上面提到MVC中控制器是控制程序的逻辑的。V是控制表现层的。M,V,C这三者是息息相关的。M是数据层。当我们不需要数据的时候,M是可以没有的。但是V是不能没有的。V也就是视图层。简单点就是页面。上面出现500错误,就是因为我们缺少了视图层。
OK!知道了问题所在。开始解决这个问题。建立下面的文件结构:
views/guestbook/view.html.php
view.html.php文件的内容:
// 禁止直接访问这个文件 defined('_JEXEC') or die ('you can not access this file!'); jimport('joomla.application.component.view'); /** * Guestbook组件的HTML视图类 */ class GuestBookViewGuestBook extends JView { function __construct() { parent::__construct(); } function display($tpl = null) { parent::display($tpl); } }
看一下执行的效果:
500问题也成功解决了。
这篇文章现在已经很长了。关于为什么现在能够执行成功,将在下一节中介绍。敬请期待!
于2014-11-06日改:当我学习Joomla的时候,我很疑惑,我的确需要建一个视图,那么视图的名称该是什么?为什么是guestbook(views/guestbook)为什么不能是其他的?其实这个问题涉及到了JoomlaMVC比较核心的内容了。在请求页面的时候,我们可以在URL中加上一个view变量。这个变量和option的功能一样。是用来让组件区分视图的。有了这个变量,你可以让组件执行任何一个视图。至于说为什么这里我们要用guestbook作为视图的名称,这是因为当系统没有检查到view变量的时候,系统会自动将view变量赋值为组件的名称,对于本组件来说,就是guestbook.
评论 (0)