教程栏目

joomla中文网出品的官方教程

在本节中我们将介绍组件前台页面的请求过程。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();

代码说明


解释几个地方:

  1. JPATH_COMPONENT 这个常量是系统维护的。他代表这组件的更目录,对于本程序来说就是components/com_guestbook/这个目录
  2. DS表示路径分隔符。windows为“\”。Linux为"/"。也是由系统维护。
  3. 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)

  • 最新在前
  • 最佳在前

第1章 Joomla入门教程

第3章 C计划

第5章 E计划

第6章 H计划

第7章 G计划

第9章 运行环境

第11章 主从与集群

第12章 模块开发

第13章 插件开发

第14章 j2.x组件开发教程

第15章 页面定制教程

第16章 页面构造器

第17章 joomla升级

第18章 其他系统迁移

第19章 流量翻倍计划