Yii框架的form处理

  Yii是重量级框架,类似于同ruby on rails,django是同一类型的框架,所以其有的特点在其他框架上都存在,但吸引我研究它的是官方文档凭什么说"Yii 是一个基于组件的高性能 PHP 框架,用于快速开发大型 Web 应用”。以后我也将继续用实践证明他这句话的对错。要知道,django的文档介绍里说的"使用Django,花极少时间即可构建和维护质量上乘的Web应用。"就是说django只适合快速原型,并且原型出来的东西不错,或者说用来做内部管理系统什么的很适合,但外部大型应用不好,而yii说自己是高性能的框架,快速,大型等关键字,很唬人。

  

说明:

1.myController是自己定义的一个控制器,login.php是在myController中login这个action指向执行的view.

2. 虚线表示一个是另一个类的子类.所以myController含有BaseController的那几个方法。所以在login.php中可以使用baseController中的方法。

3. baseController中beginWidget和widget方法都会调用createWidget(),并且在createWidget中使用init方法得到预处理的widget,而后widget和endWidget执行widget对象的run()。

<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'login-form',
    'enableClientValidation'=>true,
    'clientOptions'=>array(
        'validateOnSubmit'=>true,
    ),
)); ?>

        <?php echo $form->textField($model,'username'); ?>

        <?php echo $form->passwordField($model,'password'); ?>

    <div class="row buttons">
        <?php echo CHtml::submitButton('Login'); ?>
    </div>

<?php $this->endWidget(); ?>

以上面代码为例子,beginWidget里的array("id"=>"login-form")等参数实际上是类CActiveForm的属性。查看生成的源码:

<form id="login-form" action="/site/login" method="post">

即当前指定了id,method,那么查看CActiveForm还有action属性,增加该属性如:

<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'login-form',
    'action'=>"helloworld",
    'enableClientValidation'=>true,
    'clientOptions'=>array(
        'validateOnSubmit'=>true,
    ),
)); ?>

查看源码:

<form id="login-form" action="helloworld" method="post">

以上测试证明了beginWidget就是这样实例化出这个form的widget,但是,如何已控制器进行交互了?

控制器处理:

public function actionLogin()
    {
        $model=new LoginForm;


        // collect user input data
        if(isset($_POST['LoginForm']))
        {
            $model->attributes=$_POST['LoginForm'];
            // validate user input and redirect to the previous page if valid
            if($model->validate() && $model->login())
                $this->redirect(Yii::app()->user->returnUrl);
        }
        // display the login form
        $this->render('login',array('model'=>$model));
    }

这段代码很让人迷惑,主要是$_POST['LoginForm']那里来的?一般PHP的post请求无外乎$_POST["username"], $_POST["password"],因为$_POST这个属性无外乎就是个array,所以,可以说在yii中,通过使用yii自己的form表单,会对一些name进行处理,然后对$_POST中的值进行修改!

验证一,原始html

<input name="LoginForm[username]" id="LoginForm_username" type="text" />

生成的表单中是这样的代码。当然主要是CHtml完成的。

public static function resolveNameID($model,&$attribute,&$htmlOptions)
	{
		if(!isset($htmlOptions['name']))
			$htmlOptions['name']=self::resolveName($model,$attribute);
		if(!isset($htmlOptions['id']))
			$htmlOptions['id']=self::getIdByName($htmlOptions['name']);
		else if($htmlOptions['id']===false)
			unset($htmlOptions['id']);
	}

我们的<?php echo $form->textField($model,'username'); ?>这行代码中的textField($model,$attribute,$htmlOptions=array())方法是可以指定$htmlOptions的,即可以指定name属性,但是这里没有指定,所以都各自调用了前面的2个方法

resolveName:

public static function resolveName($model,&$attribute)
    {
        if(($pos=strpos($attribute,'['))!==false)
        {
            if($pos!==0)  // e.g. name[a][b]
                return get_class($model).'['.substr($attribute,0,$pos).']'.substr($attribute,$pos);
            if(($pos=strrpos($attribute,']'))!==false && $pos!==strlen($attribute)-1)  // e.g. [a][b]name
            {
                $sub=substr($attribute,0,$pos+1);
                $attribute=substr($attribute,$pos+1);
                return get_class($model).$sub.'['.$attribute.']';
            }
            if(preg_match('/\](\w+\[.*)$/',$attribute,$matches))
            {
                $name=get_class($model).'['.str_replace(']','][',trim(strtr($attribute,array(']['=>']','['=>']')),']')).']';
                $attribute=$matches[1];
                return $name;
            }
        }
        return get_class($model).'['.$attribute.']';
    }

get_class这里是返回的对象的类名,是哪个类呢?

public function actionLogin()
    {
        $model=new LoginForm;

是最早我们实例化的这个类。

所以说,要使用yii的类最好得有一个自己的form类。

最后,php是最好的程序语言!包括现在我们自己的免费跑腿派单平台柏布来也,也是php写的

 

原文地址:https://www.cnblogs.com/CLTANG/p/2700914.html