教程栏目

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升级