[风雨者]

山高路远,风雨兼程!

用户操作
[即时聊天] [发私信] [加为好友]
伍子ID:letsflytogether
81990次访问,排名1192(1)好友8人,关注者92
一个非计算机专业毕业的,带着对计算机的热爱,如今从事在软件开发领域。我想,我已经证明了专业不应是我们就业的标尺。
除了软件开发,我的爱好还有篮球和美食。
letsflytogether的文章
原创 67 篇
翻译 0 篇
转载 58 篇
评论 117 篇
伍子的公告
    没有比人更高的山,
    没有比脚更长的路。
------------------------
    既然选择了远方,
    便只顾风雨兼程。
------------------------
    失败只有一种,
    就是半途而废。
------------------------
    天下难事必作于易,
    天下大事必作于细。
------------------------
    从用户的角度考虑,
    你就成功了一半。
------------------------
    谁也不能随随便便地成功,
    它来自彻底的自我管理和毅力。
------------------------
月 [下月] [上月]
最近评论
liusping:如果执行一个命令有返回值,这个返回值该如何处理?定义成Command 的一个字段吗?
sap99:www.sap99.com/,SAP99资料多多

SAP免费资料下载
http://www.sap99.com

有很多的学习资料,推荐一下,
cqg1220:机柜
badonly:原来模板技术是这样的!!!谢了~~~
apollosun:恭喜啊

女儿就是宝,享福了啊

我女儿现在虚岁4岁,太可爱了,我每天下班回家的感觉就象过节。
文章分类
收藏
相册
个人风采
精品收藏
文章贴图
个人网站
女儿的博客
我在ITPUB上的博客
我在世界经理人上的博客
技术网站
CSDN
MSDN
UML软件工程组织
中国UI设计网
蓝色理想
软件工程专家网
休闲娱乐
学习网站
ICXO
网页设计师
金桥译港世界通
友情链接
heiyeluren的Blog(RSS)
博客中国上的琴剑楼
小肥羊
汉博园——陈希成
韦子的空中楼阁
资源网站
中国盟动力
太平洋电脑网
存档
软件项目交易
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes

原创 php.MVC系列教程之动作收藏

新一篇: php.MVC系列教程之视图 | 旧一篇: php.MVC系列教程之表单

Action简介

在Action类中可以处理其他输入数据,访问数据库,调用业务逻辑类。本例中我们在Action类中检查用户权限是否可以访问公司报表,调用业务逻辑类查询或更新数据库。

我们通过扩展框架的Action类来实现自己的应用Action类,本例我们使用了一个叫做AbstractBaseAction的抽象类,同样的,这个类也包含了一些通用的逻辑。SalesReportAction类则具体实现了AbstractBaseAction类,在前面的应用程序对象图中我们可以清楚地看到对象之间的关系。

一个Action类在XML配置文件中如下定义:

 <action-mappings>
   <action    path = "salesReport"
              type = "SalesReportAction"
              name = "salesReportForm"
          validate = "true"
             input = "salesReportIndex.tpl"
             scope = "request">
      <forward name="salesReportSuccess" path="salesReport.tpl" />
      <forward name="salesReportFailure" path="salesReportIndex.tpl"/>
   </action>
  </action-mappings>

各种属性的含义在前面都已经讲过,这里就不在赘述了。

AbstractBaseAction类

下面是删减了的AbstractBaseAction类

class AbstractBaseAction extends Action {

   // ----- Instance Variables --------------------------------------------- //
   var $log          = NULL;
   var $actionErrors = NULL;
   var $pmr          = NULL;
   var $locale       = NULL;
   var $dbConn       = NULL;    

   // ----- Constructor ---------------------------------------------------- //
   function AbstractBaseAction() {

      $this->log  = new PhpMVC_Log();

      $this->actionErrors =& new ActionErrors();

      $config = 'MyAppResources';
      $returnNull = False;
      $defaultLocale =& new Locale();
      $factory = NULL;
      $pmr =& new PropertyMessageResources($factory, $config, $returnNull);
      $pmr->setDefaultLocale($defaultLocale);
      $this->pmr = $pmr;
   }

   // ----- Public Methods ------------------------------------------------- //
   function execute($mapping, $form, &$request, &$response) {
      ; // Implement this method in your concrete Action classes
   }
}

构造函数

AbsractBaseAction提供了一些通用服务,比如错误或消息字符串处理,类似于前面AbstractBaseForm类。而且,还提供了一个logging类用来记录错误日志。Locale和PropertyMessageResources类在ActionForm章节已经讲过了。

execute()方法

当框架接收到一个请求将会执行相应action的execute()方法,在后面的SalesReportAction类中我们将具体实现该方法。

SalesReportAction类

下面是删减了的SalesReportAction类。这个类通过继承AbstractBaseAction类来多重继承框架的Action类。

class SalesReportAction extends AbstractBaseAction {

   // ----- Constructor ---------------------------------------------------- //
   function SalesReportAction() {

      parent::AbstractBaseAction();

      $this->log->setLog('isTraceEnabled' , True);

   }

   // ----- Public Methods ------------------------------------------------- //
   function execute($mapping, $form, &$request, &$response) {

      $trace = $this->log->getLog('isTraceEnabled');

      if($trace) {
         $this->log->trace('Start: SalesReportAction->execute(...)'.
                           '['.__LINE__.']');
      }

      $actionErrors =& $this->actionErrors;
      $pmr =& $this->pmr;
      $locale =& $this->locale;

      $username = $request->getParameter('uname');
      $password = $request->getParameter('pword');
      $group    = $request->getParameter('urole');

      // SQL as required

      $aclCheck = False;
      if($group == 'accounts') {
         $aclCheck = True;
      }

      $myForward = NULL;

      if($aclCheck == True) {
         $myForward = $mapping->findForwardConfig('salesReportSuccess');
         $sales = NULL;

         $salesReport =& new ReportsBusinessClass();
         $sales = $salesReport->getSales($this->dbConn);

         $request->setAttribute('FORM_DATA', $sales);
      } else {
         $myForward = $mapping->findForwardConfig('salesReportFailure');

         $msg = $pmr->getMessage($locale, 'report.auth.failed');
         $actionErrors->add( 'report_auth_failed', new ActionError($msg) );
         $request->setAttribute(Action::getKey('ERROR_KEY'), $actionErrors);
  
         $form->setUserName($username);
         $form->setPassWord($password);
         $form->setUserRole($group);
         $request->setAttribute( 'ACTION_FORM', $form );
 
      } 

      return $myForward;

   }
}

构造函数

当类被实例化时构造函数自动被调用,在本构造函数中我们调用父类的构造函数(parent::AbstractBaseAction())设置通用服务。另外我们可以设置是否记录日志,比如:$this->log->setLog('isTraceEnabled', True)。

execute()方法

在前面我们已经看到框架会根据请求路径找到相应的Action然后调用其execute()方法。

日志

在execute()方法中可以使用logging来记录程序的执行路径,我们能使用如下方法:

 $trace = $this->log->getLog('isTraceEnabled');
 if($trace) {
   $this->log->trace('Start: SalesReportAction->execute(...)'.
                     '['.__LINE__.']');
 }

在程序运行时输出可能是:Trace: Start: SalesReportAction->execute(...)[85]

错误对象,属性消息资源和现场

 $actionErrors =& $this->actionErrors;
 $pmr =& $this->pmr;
 $locale =& $this->locale;

其用法类似于ActionForm。

访问表单域

我们可以得到表单域的值,进一步地执行验证。注意我们已经在ActionForm类中验证了表单域的正确性,因此现在我们可以假设表单域是有效的。

 $username = $request->getParameter('uname');
 $password = $request->getParameter('pword');
 $group    = $request->getParameter('urole');

检查用户权限

在这个阶段我们可以检查用户是否有权限去访问资源,我们能查询数据库,或者使用专门的认证与权限管理系统比如phpLIB::auth或PEAR::LiveUser进行验证。在本例中我们仅仅是检查urole表单域是否设置为'accounts',如下:

$aclCheck = False;
if($group == 'accounts') {
   $aclCheck = True;
}

假如用户有正确的权限,我们就设置访问控制列表(ACL)变量($aclCheck)为True,指示用户可以访问我们的资源。

业务逻辑

现在我们可以访问业务逻辑类ReportsBusinessClass,因为ACL变量($aclCheck)已经置True;

 if($aclCheck == True) {
    ...

接下来,我们得到一个名为'salesReportSuccess'的Forward配置对象:

$myForward = $mapping->findForwardConfig('salesReportSuccess')

对应着phpmvc-config.xml文件的action节点中的forward元素

<forward name="salesReportSuccess" path="salesReport.tpl" />。

现在,我们为业务类创建一个新的实例

$salesReport =& new ReportsBusinessClass();

并调用其getSales()方法:

$sales = $salesReport->getSales($this->dbConn)。

业务逻辑类返回一个$sales对象包含了几个类变量,在后面的报表模板中将访问它。

class Sales {
    var $salesNorth;
    var $salesSouth;
    ...
 }

注意:为了降低耦合提高代码可重用性,我们允许为业务逻辑类指定对象作为参数。在实例中我们便把数据库对象参照赋给了业务对象方法,这种设计可以让我们在其他应用程序中重用业务逻辑类。

最终保存$sales对象到request,我们就可以在显示模板中访问这个对象了。

$request->setAttribute('FORM_DATA', $sales);


权限拒绝

假如用户没有通过验证($aclCheck=False),我们便得到一个名为'salesReportFailure'的Forward配置对象:

 $myForward = $mapping->findForwardConfig('salesReportFailure');

同样的,这也将查找XML配置文件的action节点中的forward元素

<forward name="salesReportFailure" path="salesReportIndex.tpl"/>;

接下来的任务就是为表单设置适当的错误消息,前面已经讲过PropertyMessageResources和ActionErrors类的用法

$msg = $pmr->getMessage($locale, 'report.auth.failed');
$actionErrors->add( 'report_auth_failed', new ActionError($msg) );


注意,这里我们没有创建可替换参数。

下面,就保存错误对象到request对象中:

 $request->setAttribute(Action::getKey('ERROR_KEY'), $actionErrors);

在后面我们可以得到这个错误对象:

$errors = $request->getAttribute( Action::getKey('ERROR_KEY') );

相应的表单域现在也保存到ActionForm对象$form中,

 $form->setUserName($username);
 $form->setPassWord($password);
 $form->setUserRole($group);

同样的,$form对象也被保存到request对象中:

$request->setAttribute( 'ACTION_FORM', $form );

这个对象也可以这样被得到:

$form = $request->getAttribute('ACTION_FORM');

然后,就是返回Forward对象

return $myForward;

接下来,控制器将调用自定义的ActionDispatcher类来进行处理。

 

 

 

 


 

发表于 @ 2004年12月31日 08:21:00|评论(loading...)|编辑

新一篇: php.MVC系列教程之视图 | 旧一篇: php.MVC系列教程之表单

评论:没有评论。

发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © 伍子