公司内部管理系统-用YII开发中遇到的问题(更新中...)

来源:互联网 发布:latex windows 10 编辑:程序博客网 时间:2024/05/01 22:26

1、YII中控制器中actionDelete方法


以前的方案,对于“删除”功能来说,我是通过<form>中的隐藏域包含id,部门名称(name)等信息,然后通过jquery的post来提交。在用YII时,对控制器中的actionDelete($id)方法有了更进一步了解。

一般YII中自动生成的actionDelete()方法如下

/** * Deletes a particular model. * If deletion is successful, the browser will be redirected to the 'admin' page. * @param integer $id the ID of the model to be deleted */public function actionDelete($id){$this->loadModel($id)->delete();// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browserif(!isset($_GET['ajax']))$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));}
一开始一直以为,actionDelete方法的参数$id,是通过get方式传递的。似乎CI框架中就是这样,在YII的示例中,提交的URL都是通过类似下面语句生成的

$this->createUrl('controller/action',array('id'=>$id));
所以,我在做项目中关于“部门分类”删除功能,就在想,如果这样的话(通过GET方式提交),那只要在浏览器提交相应的URL,更改id值,这样数据的安全性如何保证呢?

后来,在js中,我特意将post提交,改为get提交,代码如下:

  $(".del").bind("click",function(event){var id=$("input[name='id']",$(this).parents("form:first")).attr("value");var name=$("input[name='name']",$(this).parents('form:first')).val();var url=$(this).attr('href');//例如:index.php?r=controller/action&id=1art.dialog.confirm('你确认删除['+name+']该分类吗?',function(){    $.post(url,function(tips)//<------------------这里改为get    {                alert('tips');                return false;        var json=eval("("+tips+")");                if(json.result=='success'){                art.dialog.tips(json.msg);                $(event.target).parents('ul:first').hide();                }                if(json.result=='error'){                    var str='';                    $.each(json,function(idx,item){                        if(idx=='msg')                    str+=item;                    });                    art.dialog.tips(str);                }    });});return false;  });
在actionDelete方法中,echo一个字符串,并exit();结果发现,根本不执行actionDelete方法。研究了半天,最终恍然大悟,原来控制器的上面有这样一句代码:

public function filters(){return array('accessControl', // perform access control for CRUD operations'postOnly + delete', // we only allow deletion via POST request);}
就是说:delete方法只能用POST方式提交。

关于YII中删除不安全的想法一下就没有了。接下来就做了一个测试,actionDelete($id),post提交和get提交,能否能获取到。

假如我通过URL:index.php?r=controller/test&id=3

public function actionTest($id){echo $id;exit;}
测试结果:

POST提交,$id值为3

GET提交,$id值为3

真相终于大白。

二、CActiveForm的ajax验证

<?php $form=$this->beginWidget('CActiveForm', array('id'=>'post-form','enableAjaxValidation'=>true,)); ?>
如果开启ajax验证,如上:将属性enableAjaxValidation设置为true,那么在控制器中要调用以下方法:

protected function performAjaxValidation($model){if(isset($_POST['ajax']) && $_POST['ajax']==='costcategory-form')//这里的$_POST['ajax']的值默认为表单的id{echo CActiveForm::validate($model);Yii::app()->end();}}
在实际项目开发中遇到的问题说明一下:

1、在控制器中调用performAjaxValidation,这个方法是在数据未提交(点击submit按钮)之前所执行的,即 未提交数据时的ajax验证。

2、如果有错误,CActiveForm::validate($model);返回的是json格式的数据

3、自定义表单注意,如果要使用ajax验证,针对验证字段,比如我要对name这个字段进行ajax验证,要加上

<?php echo $form->error($model,'name'); ?>
否则,无法开启ajax验证。

4、下面对我本人有用

由于上述表单中没有submit按钮,上图中的“保存”按钮,是基于artDialog插件生成。源码如下:

function btn_restore(){  api=art.dialog.open.api;  api.button({    name:'保存',    disabled:false  });}$(document).ready(function(){  //$(document).bind("contextmenu",function(){return false;});  setTimeout(function () {$("#name").focus()}, 240);  var parent=art.dialog.parent,  api=art.dialog.open.api;  if(!api) return;  api.button(    {      name:'保存',      callback:function(){        this.button({          name:'保存',          disabled:true        });        $.post($("#costcategory-form").attr("action"),$("#costcategory-form").serialize(),function(s){        var json=eval("("+s+")");            if(json.result=='success')            {            msg(1,"操作成功",true);            }            if(json.result=='error')            {                var str='';                $.each(json,function(idx,item){                if(idx=='msg')                str+=item;                });                //$("#error").html(str);                art.dialog.tips(str);                btn_restore();            }        });        return false;      },      focus:true    },    {      name:'放弃'    }  );});
所以,即使我在CActiveForm中做以下配置:

<?phpCHtml::$afterRequiredLabel=':';$form=$this->beginWidget('CActiveForm',array('id'=>'costcategory-form',//该值也是默认的$_POST['ajax']的值。'enableClientValidation'=>true,'enableAjaxValidation'=>true,'clientOptions'=>array('validateOnSubmit'=>true),));?>
当点击“保存”按钮时,无法触发enableClientValidation(客户端验证)以及validateOnSubmit

validateOnSubmit: boolean, 当表单被提交时是否执行AJAX验证。如果存在任何验证错误,表单的提交动作将被停止。默认值是false。

ajax验证的情况在:在分类名称中输入内容,鼠标在旁边空白处单击后,可触发ajax验证。但是当点击“保存”按钮时,不会触发ajax验证。具体的可通过chrome浏览器中“审查元素”->NetWork中可查看。