yii的一些常用方法和技巧大全

jerry Yii 2015年08月23日 收藏

1.  存取数据库方法
存储第一种(SAVE )
   存表时候用到  
   例子:

  1. $post=new Post;
  2.    $post->title='sample post';
  3.    $post->content='content for the sample post';
  4.    $post->createTime=time();/$post->createTime=new CDbexpression_r('NOW()');
  5.    $post->save();   
  6.   $user_field_data= new user_field_data;
  7.   $user_field_data->flag=0;
  8.   $user_field_data->user_id=$profile->id;
  9.   $user_field_data->field_id=$_POST['emailhiden'];
  10.   $user_field_data->value1=$_POST['email'];
  11.   $user_field_data->save();   //注:当一个表存储4次的时候,需要创建4个handle new4次

存储第二种(存储)  

存储后我们需要找到这条记录的流水id 这样做 $profile = new profile; $profile->id;
存储第三种 用于更加安全的方法,来绑定变量类型  这样可以在同一个表中存储两个记录

  1.   $sql="insert into user_field_data(user_id,field_id,flag,value1) values(:user_id,:field_id,:flag,:value1);";
  2.      $command=user_field_data::model()->dbConnection->createCommand($sql);
  3.      $command->bindParam(":user_id",$profile->id,PDO::PARAM_INT);
  4.      $command->bindParam(":field_id",$_POST['firstnamehiden'],PDO::PARAM_INT);
  5.      $command->bindParam(":flag",$tmpflag,PDO::PARAM_INT);
  6.      $command->bindParam(":value1",$_POST['firstname'],PDO::PARAM_STR);
  7.      $command->execute();
  8.      $command->bindParam(":user_id",$profile->id,PDO::PARAM_INT);
  9.      $command->bindParam(":field_id",$_POST['emailhiden'],PDO::PARAM_INT);
  10.      $command->bindParam(":flag",$tmpflag,PDO::PARAM_INT);
  11.      $command->bindParam(":value1",$_POST['email'],PDO::PARAM_STR);
  12.      $rowchange = $command->execute();
  13.      // 用来判断
  14.      if( $rowchange != 0){  修改成功 }

注:update delete都可以用这个方法

  1. $sql="delete from profile where id=:id";
  2.      $command=profile::model()->dbConnection->createCommand($sql);
  3.      $command->bindParam(":id",$userid,PDO::PARAM_INT);
  4.      $this->rowflag=$command->execute();
  5.     
  6.      $sql="update profile set pass=:pass,role=:role where id=:id";
  7.      $command=profile::model()->dbConnection->createCommand($sql);
  8.      $command->bindParam(":pass",$password,PDO::PARAM_STR);
  9.      $command->bindParam(":role",$role,PDO::PARAM_INT);
  10.      $command->bindParam(":id",$userid,PDO::PARAM_INT);
  11.      $this->rowflag=$command->execute();     // 同理变更updateAll()模式
  12.      $sql="update user_field_data set flag = :flag where user_id= :user_id and field_id= :field_id ";

//原始sql语句

  1. $criteria = new CDbCriteria;
  2.      $criteria->condition = 'user_id = :user_id and field_id= :field_id';
  3.      $criteria->params = array(':user_id' => $userid,':field_id' => $fieldid);
  4.      $arrupdate = array('flag' => $flag);
  5.      if(user_field_data::model()->updateAll($arrupdate,$criteria) != 0)
  6.         {
  7.            //更新成功后。。。
  8.          }

第四种更新和存储应用同一个handle 流程:先查询记录是否存在,若存在就更新,不存在就新创建
注:1.第一次查询的变量,要跟save()前的变量一致。
       2.存储时候需要再次 new一下库对象     

  1. $user_field_data = user_field_data::model()->findByAttributes(
  2. $attributes = array('user_id' => Yii::app()->user->user_id, 'field_id' => $key));
  3.                 if ($user_field_data !== null)
  4.                    {
  5.                       $user_field_data->value1 = $value;
  6.                       $user_field_data->save();
  7.                   }
  8.                  else
  9.                     {
  10.                         $user_field_data = new user_field_data;
  11.                         $user_field_data->user_id = Yii::app()->user->user_id;
  12.                         $user_field_data->field_id = $key;
  13.                         $user_field_data->value1 = $value;
  14.                         $user_field_data->save();
  15.                     }

2、查询数据
   注:当项目没查找到整个对象会为空需要这样判定

  1.        if($rows !== null) 当对象不为空
  2.            {
  3.                  return true;
  4.            }else{
  5.                  return false;
  6.            }

   SELECT
   读表时候用到
  第一种find()

  1. // find the first row satisfying the specified condition
  2.    $post=Post::model()->find($condition,$params);
  3.    // find the row with postID=10
  4.    $post=Post::model()->find('postID=:postID', array(':postID'=>10));   同样的语句,用另种方式表示
  5.    $criteria=new CDbCriteria;
  6.    $criteria->select='title';  // only select the 'title' column
  7.    $criteria->condition='postID=:postID';
  8.    $criteria->params=array(':postID'=>10);
  9.    $post=Post::model()->find($criteria); // $params is not needed   第二种 find()
  10.    $post=Post::model()->find(array(
  11.        'select'=>'title',
  12.        'condition'=>'postID=:postID',
  13.        'params'=>array(':postID'=>10),
  14.    ));   // find the row with the specified primary key
  15.    $post=Post::model()->findByPk($postID,$condition,$params);
  16.       
  17.    // find the row with the specified attribute values
  18.    $post=Post::model()->findByAttributes($attributes,$condition,$params);

示例:第一种 findByAttributes()

  1. $checkuser = user_field_data::model()->findByAttributes(
  2.    array('user_id' => Yii::app()->user->user_id, 'field_id' => $fieldid));

第二种 findByAttributes()

  1. $checkuser = user_field_data::model()->findByAttributes(
  2.    $attributes = array('user_id' => Yii::app()->user->user_id, 'field_id' => $fieldid));

第三种 当没有conditions时候,不用params

  1. $user_field_data = user_field_data::model()->findAllByAttributes(
  2.    $attributes = array('user_id' => ':user_id'),
  3.    $condition = "field_id in (:fields)",
  4.    $params = array(':user_id' => Yii::app()->user->user_id, ':fields' => "$rule->dep_fields"));
  5.    
  6.    // find the first row using the specified SQL statement
  7.    $post=Post::model()->findBySql($sql,$params);

例子

  1. user_field_data::model()->findBySql("select id from user_field_data where user_id = :user_id and field_id = :field_id ", array(':user_id' => $userid,':field_id'=>$fieldid));

此时回传的是一个对象
 第四种  添加其他条件 

  1.   $criteria = new CDbCriteria;
  2.       $criteria->select ='newtime';  //选择只显示哪几个字段要与库中名字相同,但是不能COUNT(newtime) as name这样写
  3.       $criteria->join = 'LEFT JOIN Post ON Post.id=Date.id';

1. 先要在relation函数中增加与Post表的关系语句

  1.     
  2.     2. Date::model()->with('post')->findAll($criteria)
  3.        $criteria->group  = 'newtime';
  4.        $criteria->limit  = 2; // 都是从0开始,选取几个
  5.        $criteria-> offset = 2;// 从哪个偏移量开始
  6.        print_r(Date::model()->findAll($criteria))

得到行数目或者其他数目 count

  1. // get the number of rows satisfying the specified condition
  2.    $n=Post::model()->count($condition,$params);
  3.    // get the number of rows using the specified SQL statement
  4.    $n=Post::model()->countBySql($sql,$params);
  5.    // check if there is at least a row satisfying the specified condition
  6.    $exists=Post::model()->exists($condition,$params);

3、更新(UPDATE)
   例子:

  1. $post=Post::model()->findByPk(10);
  2.    $post->title='new post title';
  3.    $post->save(); // save the change to database
  4.    
  5.    // update the rows matching the specified condition
  6.    Post::model()->updateAll($attributes,$condition,$params);   例子:或者参考上面例子
  7.    $c=new CDbCriteria;
  8.    $c->condition='something=1';
  9.    $c->limit=10;  
  10.    $a=array('name'=>'NewName');  
  11.    Post::model()->updateAll($a, $c);
  12.    
  13.    // update the rows matching the specified condition and primary key(s)
  14.    Post::model()->updateByPk($pk,$attributes,$condition,$params);   例子
  15.    $profile = profile::model()->updateByPk(
  16.    Yii::app()->user->user_id,
  17.    $attributes = array('pass' => md5($_POST['password']), 'role' => 1));
  18.     
  19.    // update counter columns in the rows satisfying the specified conditions
  20.    Post::model()->updateCounters($counters,$condition,$params);

4、删除(DELETE)
   例子:

  1. $post=Post::model()->findByPk(10); // assuming there is a post whose ID is 10
  2.    $post->delete(); // delete the row from the database table
  3.    // delete the rows matching the specified condition
  4.    Post::model()->deleteAll($condition,$params);
  5.    // delete the rows matching the specified condition and primary key(s)
  6.    Post::model()->deleteByPk($pk,$condition,$params);

5、比较(COMPARE)
  目前可以取出的

  1.     1. $allquestion=field::model()->findAllBySql("select label from field where step_id = :time1 ", array(':time1' =>1));
  2.    
  3.     2. 
  4.       $criteria=new CDbCriteria;
  5.       $criteria->select='label,options';
  6.       $criteria->condition='step_id=:postID';
  7.       $criteria->params=array(':postID'=>1);
  8.       $allquestion=field::model()->findAll($criteria);
  9.      $allquestion=field::model()->find("",array("label"));

可以与在models文件夹中的 库连接文件relations()函数合用,这样可以联合查询

  1. $criteria=new CDbCriteria;
  2.     $criteria->condition='field.step_id=1';
  3.     $this->_post=field::model()->with('step')->findAll($criteria);

这样出来的数组里面包含step表中的值,且这个值的条件为 step.id=field.step_id

  1. public function relations()
  2.         {
  3.                   return array(
  4.                                             'step'=>array(self::BELONGS_TO, 'step', 'step_id'),
  5.                                        );
  6.        }

UserIdentity.php

  1. class UserIdentity extends CUserIdentity{}


进行对数据库的校验密码且复制给$this->_id=$user->id; 表示用户状态为登陆
注: 任何登陆的编程都要继承此文件,单独创建文件即使继承的类都一样,但yii是不认可的

  1.       $identity=new UserIdentity($forms->email,'ethos');
  2.     $identity->authenticate();
  3.     Yii::app()->user->login($identity);


LoginForm.php

这些在models下用来定义文本框符合各种条件

  1.   class LoginForm extends CFormModel{
  2.      rules() attributeLabels() authenticate()
  3.   }
  4.     function rules(){
  5.       array('username', 'email'),//调用js认证
  6.    array('password', 'authenticate'),//调用下一个函数
  7.   }


login.php

1.  

  1. //这样给form增加其他属性
  2. <?php echo CHtml::beginForm('',$method='post',array("id"=>"signupForm")); ?>  
  3. //给其他文本组件增加属性触发js函数
  4. <?php echo CHtml::activeTextField($form,'username',array("class"=>"required","minlength"=>"3")) ?> 
  5. <?php echo CHtml::submitButton('Login',array ("onclick"=>"testok()")); ?>   //testok() 为js函数
  6. <?php echo CHtml::submitButton('Login',array ("onclick"=>"alert(\"sam\");return false;")); ?>
  7.   <?php echo CHtml::activeLabel($post,$post->label); ?>
  8. <?php echo CHtml::activeTextField($post,'label',array('size'=>65,'maxlength'=>128)); ?>
  9. <?php echo CHtml::activeTextField($post,'content',array('rows'=>20, 'cols'=>50)); ?> label或者 content是当前表的列名字这个很重要相当于显示数据对象中的某个属性 可以输出数据库的值
  10. <?php foreach($post as $n=>$model): ?>
  11. <?php echo CHtml::activeLabel($model,'label'); ?>
  12. <?php echo CHtml::textField('firstname','',array("class"=>"required","minlength"=>"3")) ?>
  13. <?php endforeach; ?>


注:若需要从数据库传值到input组件需要用CHtml::textField
    仅仅是需要录入信息,且后台取得用这个就行

  1.  CHtml::textField('username','',array("class"=>"required","minlength"=>"3"));


2.  关于用JQuery验证文本框的改写说明
   用jquery的validate插件控制文本框输入格式

  1. http://bassistance.de/jquery-plugins/jquery-plugin-validation/)

  js中要写
  signupForm 为表单id

  1.   $().ready(function() {
  2.    // validate the comment form when it is submitted
  3.    $("#commentForm").validate();
  4.   
  5.    // validate signup form on keyup and submit
  6.    $("#signupForm").validate({ 
  7.   
  8.    });
  9.   });


  php中要添加 要求此字段的输入要求
 

  1.  <?php echo CHtml::activeTextField($form,'username',array("class"=>"required","minlength"=>"3")) ?>
  2.   
  3.   注:jquery.validate.js中
  4.   defaults: {
  5.     messages: {},
  6.     groups: {},
  7.     rules: {},
  8.     errorClass: "errorjs",  原来是error现在时errorjs 不然与yii的错误提示冲突


用rule 存数据库
当 数据库的php

  1. public function rules()
  2. {
  3.   return array(
  4.    array('email','length','max'=>40),
  5.    array('pass','length','max'=>255),
  6.    array('role', 'required'),
  7.    array('role, overall_percent, overall_time', 'numerical', 'integerOnly'=>true),
  8.   );}


在controller时候需要
在rule的required的时候 都需要赋值。 overall_percent,overall_time遵循 role的原则
    

  1.     $profile = new profile;
  2.     $profile->email=$_POST['email'];
  3.     $profile->firstname=$_POST['firstname'];
  4.     $profile->role=0;
  5.     $profile->overall_time=0;
  6.     $profile->overall_percent=0;
  7.     $zipcode = $this->zipPlace($_POST['zipcode']);
  8.     echo $zipcode->state;
  9.     var_dump($profile->save());


注 当一个表存储4次的时候,需要创建4个handle new4次
在登陆验证时候增加额外项给Yii::app()->user->lastTime
在UserIdentity.php中

  1. class UserIdentity extends CUserIdentity
  2. {
  3.     $this->setState('lastTime',$user->lastTime);
  4. }


前台就可以调用Yii::app()->user->lastTime
只有这样添加的新值,才能在程序中这样任意重复赋值。默认的值不可,比如Yii::app()->user->username
    Yii::app()->user->lastTime='1';

$form->validate()如何起作用的说明
1. StartForm.php中 我们定义了各个文本框的 rules()
2. 需要在controller中调用, 先声明这个文本框

  1.     $forms=new StartForm;
  2.     // 要把回传函数这些属性给$forms这个对象
  3.   $forms->firstname=$_POST['firstname'];
  4.   $forms->firstname=$_POST['email'];
  5.   $forms->firstname=$_POST['zipcode'];
  6.   $forms->firstname=$_POST['perstatus'];
  7.     //调用php端的文本校验
  8.     if($forms->validate()){
  9.        XXXXXX
  10.     }


3.  同理为LoginForm

  1.       $form=new LoginForm;
  2.        if(isset($_POST['LoginForm']))
  3.      {
  4.       $form->attributes=$_POST['LoginForm'];//回传函数这些属性给form
  5.        if($form->validate()){
  6.        }
  7.       }


4.   当进入到validate的时候我们仍然需要增加逻辑来确认每个文本框需要认证的属性
yii的session可以这样设置
  1. 程序中可以这样调用  Yii::app()->session[$var]=$value;
  2. 若main.php         
     定义后

  1.  'session' => array(
  2.             'class' => 'system.web.CDbHttpSession',
  3.             'connectionID' => 'db', ),


    当运行第一次网站时候系统会建立yiisession的表,session自动存储在库的yiisession表内
  3. 而库连接可以这样

  1.         'db'=>array(
  2.       // 'connectionString'=>'Your DSN',
  3.       'connectionString'=>'mysql:host=localhost;dbname=testnewtax',
  4.       'username'=>'root',
  5.       'password'=>'adminzhao',
  6.       ),


4. 在main.php中 增加参数文件 params.php (这个文件是与main.php平行结构 放到文件夹中)
    

  1.  'params'=>require(dirname(__FILE__).'/params.php'),

在程序里可以这样引用

yii 返回的地址也可以这样写

  1. 1.   Yii::app()->user->returnUrl = Yii::app()->getBaseUrl()."/step/show/id/1";
  2.      $this->redirect(Yii::app()->user->returnUrl);
  3. 2.   $this->redirect(array('step/show','id'=>1));
  4. 3.   $this->render('index',array('post'=>$questions));
  5. 4.   $this->renderPartial('field_show',array('field'=>$field,'key'=>++$key,));


注意:有的时候$this->render、$this->redirect在同一个action中应用,程序会报错原因如下
      1.当我们创建新的form的时候 我们应用2中方法,
        1》FillForm.php class FillForm extends CFormModel  这样可以把这个表单中每个项目用php进行核查是否符合规则,在FillForm.php  public function rules()中创建规则
        2》直接在继承数据库表时候创建表单的核查规则  Post.php (post是库中的表)class Post extends CActiveRecord 在Post.php 中 public function rules() 中创建规则
       
      2. 在继承CFormModel类后同一个action中就不能同时出现$this->render、$this->redirect,否则会报错
         变通办法如下在controller中创建2个action对应一个form
        

  1.    public function actionFill()
  2.        {
  3.         $form=new FillForm;
  4.        $this->render('fill',array('form'=>$form));
  5.        }
  6.       public function actionUpdatePass()
  7.        {
  8.        if(isset($_POST['password']))
  9.        {
  10.           //XXX
  11.          $this->redirect(array('step/show','id'=>1));
  12.         }
  13.                  else
  14.                      $this->refresh();
  15.        }
  16.        }


在tpl中设置 <?php echo CHtml::beginForm('UpdatePass',$method='post',array("id"=>"fillForm")); ?>
    
弹出窗口  目前有个问题就是弹出的窗口路径是相对于现在的controller的无法调到另外路径下
1.  在ptl文件中 输入 <?php echo CHtml::linkButton('popup',array ("onclick"=>"startAlert()")); ?>
2.  js文件 function startAlert(){ window.open('fillpass'); }
3.  sitecontroller.php  public function actionFillpass(){ $this->render('fillpass'); }
4.  创建fillpass的tpl themes/views/site/fillpass.php

删除按钮 带确认项

1. 在tpl中

  1.    <?php 
  2.     echo CHtml::Button('cancel', array (
  3.           'submit' => 'DeleteUser',
  4.           'params' => '',
  5.           'confirm'=>'Are you sure?'
  6.     ))
  7.    ?>
  1. //这样写就可以传送参数用get方法接收
  2. $this->redirect(array('category/show',array('id'=>1,'rule_id'=>'1'))); 2.  原始代码
  3. <?php echo CHtml::linkButton('Logout',array(
  4.        'submit'=>'',
  5.        'params'=>array('command'=>'logout'),
  6.    )); ?>
  7. <?php echo CHtml::Button('Delete', array (
  8.        'submit' => $this->createUrl('post/delete',$this->getReturnParams()),
  9.        'params' => array('id'=>123),
  10.        'confirm'=>'Are you sure?'
  11.      )) 
  12. ?>


代码可以先取出用户已经选的选项,再赋值到前台页面中

  1. <?php foreach($options = $tempradio as $key => $value): ?>
  2. <?php
  3. if ($field->value == $key)
  4.   echo "<span class='radio'>",CHtml::radioButton($field->id, true, array("class" => "noborder", "value" => $key)),$value,"</span>";
  5. else
  6.   echo "<span class='radio'>",CHtml::radioButton($field->id, false, array("class" => "noborder", "value" => $key)),$value,"</span>";
  7. ?>
  8. <?php endforeach; ?>


tpl调用jquery的AJAX

1.tpl中 调用js中的函数startAlert()

  1.      <?php echo CHtml::Button('Flag', array("id"  => "cb_btn_$field->id", "name"  => "cb_btn_$field->id", "onclick" => "startAlert('$field->id')"));?>

2.js中

  1.    function startAlert(id){
  2.     $.ajax({
  3.       type: "POST",
  4.       url: "http://www.cnblogs.com/Change",
  5.       data: "id="+id+"&location=Boston",
  6.       success: function(msg){
  7.         //alert( "Data Saved: " + msg );
  8.         document.getElementById('cb_'+id).innerHTML=msg;
  9.       }
  10.     });
  11.    }

  注意:data传递参数是post且格式如下"id="+id+"&location=Boston" 可以传递N个变量 url :填写路径是有技巧的
             1. 当URL路径 trunk/bo/index.php/category/show/id/1  意义为 在categorycontroller下的 actionshow中 id是参数名 1 为参数值这样时候 AJAX需要
             2. 当URL路径 trunk/bo/index.php/category/fill       意义为 在categorycontroller下的 actionfill中这样时候 AJAX需要写"Change"   不需要递归

main.php 里面的内容包括

1》 params 文件的应用
  1.protected/config/main.php 中进入这个文件

  1. 'params' => include(dirname(__FILE__) . '/params.php')

    相当于引入了一些全局静态变量到系统中
  2. 实际的操作方法为。在tpl文件中可以引用  Yii::app()->params['TEXT_TYPE']

2》 设置网页上的URL 把带问号的参数?r=site/login,变成/组成的URL

  1. opentax/trunk/bo/index.php?r=site/login  ====》 opentax/trunk/bo/site/login
  1.     1. 'components' => array(这里增加一个数组
  2.         'urlManager' => array(
  3.          'urlFormat' => 'path',
  4.          'showScriptName' => 'false',
  5.          'urlSuffix' => '.html', //传递参数后会自动添加此后缀名,用于欺骗作用的下标。id/1  ===> id/1.html
  6.         ),
  7.        )


3》设置新主题 theme 相当于整个网站的新tpl风格

  1.     'theme' => 'opentax', components数组平行
  2.     Yii::app()->theme->baseUrl . '/images/FileName.gif'  需要调用theme中的图片时候,可以用此地址

4》  在components中设置,可以用来输出特出的值

  1.      'log' => array(
  2.      'class' => 'CLogRouter',
  3.      'routes' => array(
  4.       array(
  5.        'class' => 'CFileLogRoute',
  6.        'levels' => 'error, warning',
  7.        'class'=>'CWebLogRoute', //当加上这两句话时候,程序就显示一个关于执行过程的表格易于开发,但是发布时候需要去除,不然影响程序速度(http://www.yiiframework.com/forum/index.php/topic,2004.0.html)
  8.               'levels'=>'trace', //当加上这两句话时候,程序就显示一个关于执行过程的表格易于开发,但是发布时候需要去除,不然影响程序速度
  9.       ),
  10.      ),
  11.     ),

5》 增加数据库的连接文件

  1.         'db'=>array(
  2.             'class'=>'CDbConnection',
  3.             'connectionString'=>'mysql:host=localhost;dbname=ox',
  4.             'username'=>'root',
  5.             'password'=>'',
  6.         ),


6》模版引擎
    在components中添加

  1.     'viewRenderer'=>array(
  2.             'class'=>'CPradoViewRenderer',
  3.      ),

7》安全性
    1.CSRF 保护。在form中添加一个cookie,当提交时候服务器会认证这个值,若相同表示为可信任的表单及其传的值
       components中加入

  1.         'request'=>array(
  2.              'enableCsrfValidation'=>true,
  3.          ),

     且建立表单时候一定用CHtml::form。这种格式,其他格式都不能被保护
    
   2.XSS 保护

  1.       <?php $this->beginWidget('CHtmlPurifier'); ?>
  2.     ...display user-entered content here...
  3.     <?php $this->endWidget(); ?>

  3.Cookie 保护

  1.       components中加入
  2.       'request'=>array(
  3.             'enableCookieValidation'=>true,
  4.         ),
  5.         用时候这样调用和赋值
  6.         $cookie=Yii::app()->request->cookies[$name];
  7.     $value=$cookie->value;
  8.     // send a cookie
  9.     $cookie=new CHttpCookie($name,$value);
  10.     Yii::app()->request->cookies[$name]=$cookie;

8》提高性能
    1.应用php的APC(Alternative PHP Cache)。

  1.     return array(
  2.        'components'=>array(
  3.           'cache'=>array('class'=>'CDbCache'),
  4.           'cache2'=>array('class'=>'CMemCache'),
  5.        ),
  6.     );

   然后通过Yii::app()->cache和Yii::app()->cache2来访问。
    2.关闭YII_DEBUG 设置为false
    3. Active Record用这个调用库文件也可以应用到缓存技术
    4. 可以用$cs=Yii::app()->clientScript;来合并许多的js文件
    5. 可以引用google的jquery来代替自身的echo CGoogleApi::bootstrap(); CGoogleApi::load


当用yii自带的BUTTON调用自己的JQuery.yii.js时候会与Jquery.validate.js冲突
1.  这样调用Button 就yii自己生成了 JQuery.yii.js,会产生冲突。文本框验证不了

  1. <?php echo CHtml::Button('cancel', array (
  2.     'submit' => Yii::app()->request->baseUrl . '/category/DeleteUser',
  3.     'params' => '',
  4.     'confirm' => 'Are you sure?'
  5. )) ?>


2.  解决:
   需要避开带参数的button

  1. <?php echo CHtml::Button('cancel',array("onclick"=>"deleteuser('".Yii::app()->request->baseUrl . '/category/DeleteUser'."')"));?>

   让它去调用js函数deleteuser()且把相对路径传给他。让js去提交表单和询问
 
   js如下:

  1.    function deleteuser(url)
  2.   {
  3.     if(confirm('are you sure?'))
  4.     {
  5.      document.getElementById('fillForm').action=url;
  6.      document.getElementById('fillForm').submit();
  7.     }
  8.   }


yii controller中需要load某些文件的操作方法
1.

  1.  /protected/config/main.php  是纵览哪些文件是可以load进来的
  2.     // autoloading model and component classes
  3.   'import' => array(
  4.    'application.models.*',
  5.    'application.components.*',
  6.      'application.classes.*',
  7.   ),

2. controller之间的action不能相互调用且controller之间也不能相互引用
   需要公共的函数可以写到这些文件中只要建立一个class就可以
   解决方法在公共函数中进行回传一个变量或者全局变量,用变量进行判断

YII 的 JQUERY 的json 运用方法
1. php中建立数组

  1.   $chage['fieldid'] = $fieldid;
  2.   $chage['butflag'] = 0;
  3.   echo CJSON::encode($chage);

2.  JS文件中输出

  1.      var Jsonstr = $.json.decode(msg);

这样就可以取值Jsonstr['fieldid']


YII  不用自带的php validate验证功能,自己可以模仿输出
1.  在php中
    先用数据库查询用户是否存在
   

  1.  if($this->checkEmail($_POST['email']))
  2.    {
  3.     $error[0] = 'email already exists';
  4.                 $er = true;
  5.    }
  6.     if($er) // 如果存在返回到首页
  7.       {
  8.           $questions = $this->loadQuest();
  9.           $this->render('index', array(
  10.                               'post' => $questions,
  11.                               'error_msg_email' => $error[0],
  12.                               'error_msg_zip' => $error[1],
  13.                               'firstname' => $_POST['firstname'],
  14.                               'email' => $_POST['email'],
  15.                               'zipcode' => $_POST['zipcode'],
  16.                               'perstatus' => $_POST['perstatus'],
  17.                               ));
  18.       }


2. tpl中 index.tpl
   

  1.  if($textname == "email")
  2.      {
  3.       echo CHtml::textField($textname, $value = $$textname, array("class" => "required email", "minlength" => "3"));
  4.       //用css的控制,决定错误提示是否输出及输出的位置
  5.         echo '<label class="errorjs" for="email" generated="true" style="',($error_msg_email == '')?'display:none':'','">',$error_msg_email,'</label>';
  6.       echo CHtml::hiddenField($textname . "hiden", $model->id);
  7.      }


类的不同调用
1. 当定义类中函数有静态属性时候。加static 的是静态成员,不能用实例化。
   在你运行的时候他自己在内存中开辟了块空间,不用再一次new, 有点像全局变量

  1. class Uti
  2. {
  3.   public static function teOptions($text){}
  4. }


2. 外面函数调用时候,用 Uti::teOptions() 这样就可以。但引用变量时候需self:a,这样的方式
3. 若类中定义为 先实例化(new)一下才能用

  1.   class Uti
  2. {
  3.   public function texOptions($text){}
  4. }


4. 外部调用如下:  类中变量可以$this->a方式使用

  1.     $component = new Uti;
  2.    $tmpflag = $component -> texOptions();


解释models文件夹中读取数据库中表的文件。relationship的应用
1.  表结构如下

  1.     category       (pk) id , name
  2.     postcategory   (pk,fk1) postID,(pk,fk2)categoryID
  3.     post           (pk) id ,  title,content,createTime,(fk1)authorID
  4.     user           (pk) id , username,password email
  5.     profile        (pk,fk1) ownerID,photo,website


2.  relation结构如下

  1.     'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...additional options)
  2.      // author 为自己命名的标志,在查询时候应用
  3.      // user和post的关系是一对多,post belongs to user
  4.      // 外键是 authorID
  5.      // categories 为自己命名的标志,在查询时候应用
  6.      // category和post的关系是多对多,只不过用了一个中间表让之形成一对多,多对一这样的关系。post many_many category
  7.      // 外键是 postcategory 这个表,它里面有两个字段
  8.     class Post extends CActiveRecord { public function relations() { return array( 'author'=>array(self::BELONGS_TO, 'User', 'authorID'), 'categories'=>array(self::MANY_MANY, 'Category', 'PostCategory(postID, categoryID)'), ); } }
  9.      // posts 为自己命名的标志,在查询时候应用
  10.      // post和user的关系是多对一,user has many post
  11.      // 外键是 authorID
  12.      // profile 为自己命名的标志,在查询时候应用
  13.      // user和Profile的关系是多对一,user has one Profile 是 has many的变种
  14.      // 外键是 ownerID
  15.     class User extends CActiveRecord { public function relations() { return array( 'posts'=>array(self::HAS_MANY, 'Post', 'authorID'), 'profile'=>array(self::HAS_ONE, 'Profile', 'ownerID'), ); } }


3.  sql程序调用时候

  1.     //因为没有调用之前定义的author,categories,查询结果不启用关联查询,不会消耗性能
  2.     $post=Post::model()->findByPk(10);
  3.     //当用到with()这个函数时候,它关联了author 所以查询结果中增加user表中的结果
  4.     $posts=Post::model()->with('author')->findAll();
  5.     //用到了三个命名标志,所以它关联三个表 user ,Category, PostCategory
  6.     $posts=Post::model()->with('author','categories')->findAll();
  7.     //因为有关联到user中的profile 所以目前关联的是 post ,user, category, postcategory,profile
  8.     $posts=Post::model()->with(array( 'author'=>array( 'profile', 'posts'), 'categories'))->findAll();
  9.    
  10.     注意:当不设置relation的时候但仍然要操作left join 之类的操作。方法如下
  11.       $sql = "select * from date left join post on post.id = date.id";
  12.     $temp=Date::model()->dbConnection->createCommand($sql)->queryAll();
  13.      YiiAR时候不设置relation时候不能操作
  14.     这样是错误的。他调用了Yii CActiveRecord类中的populateRecords方法,它会根据relation中的表字段重新排列一下,所以左连接的内容不会被显示
  15.     Date::model()->findBySql("select * from date left join post on post.id = date.id");


View 的应用
1. 可以用render用来传值到view层

  1.    $this->render('edit', array(
  2.        'var1'=>$value1,
  3.        'var2'=>$value2,
  4.    ));


     当用这种形式时候
     通过调用 renderPartial() 可以不依赖布局而渲染视图.

2.  主文件的tpl在这里protected/views/layouts/main.php
    可以用这样的形式来定义头和尾文件

  1.     ......header here......
  2.   <?php echo $content; ?>
  3.   ......footer here......


3. 应用组件CWidget

  1.    <?php $this->beginWidget('path.to.WidgetClass'); ?>
  2.   ...body content that may be captured by the widget...
  3.   <?php $this->endWidget(); ?>

 
  或者不需要body的组件

  1.   <?php $this->widget('path.to.WidgetClass'); ?>

 
  也可以通过传递值到组件中

  1.   <?php
  2.   $this->widget('CMaskedTextField',array(
  3.       'mask'=>'99/99/9999'
  4.   ));
  5.   ?>


4.  系统视图
    当出现404这样的错误时候 protected/views/system 在这里的模版可以列出显示错误页面

Path Alias and Namespace   路径假名
1.  应用YiiBase::getPathOfAlias() 会把system.web.CController 变成真正的物理路径 yii/framework/web/CController
  

  1.  导入文件的方法,这样比includerequire高效
  2.     Yii::import('system.web.CController');
  3.     这样可以导入一个目录的文件
  4.     Yii::import('system.web.*');


2. import基于spl_autoload_extensions创建新对象

  1.   ClassA.php
  2.   <?php class ClassA { var $val = 'Hello from class "ClassA"'; } ?>
  3.   ClassB.php
  4.   <?php class ClassB { var $val = 'Hello from class "ClassB"'; } ?>
  5.   ClassC.php
  6.   <?php class ClassC { var $val = 'Hello from class "ClassC"'; } ?>
  7.   ClassD.php
  8.   <?php class ClassD { var $val = 'Hello from class "ClassD"'; } ?>
  9.   ClassE.php
  10.   <?php class ClassE { var $val = 'Hello from class "ClassE"'; } ?>


   1》spl_autoload_extensions('.php,.inc');

  1.    // new priority: .php .inc
  2.    for($n=65; $n<70; $n++) {
  3.        $className = 'Class'.chr($n);
  4.        spl_autoload($className);
  5.        $ins = new $className;
  6.        echo $ins->val.'<br>';
  7.       //1.4 miliseconds
  8.    }


  2》 Simple:

  1.    <?php
  2.    // default priority: .inc .php
  3.    for($n=65; $n<70; $n++) {
  4.        $className = 'Class'.chr($n);
  5.        spl_autoload($className);
  6.        $ins = new $className;
  7.        echo $ins->val.'<br>';
  8.    }
  9.    // 4.2 miliseconds
  10.    ?>


3. 用Yii::import 方法还可以嵌入第三方程序
   1》我们嵌入zend的Zend_Search_Lucene模块方法如下
       首先,假设protected是网站的主目录,我们提取Zend Framework的发布文件到protected/vendors目录。确认protected/vendors/Zend/Search/Lucene.php文件存在
      
   2》在一个controller类文件的开始写入如下语句

  1.        Yii::import('application.vendors.*');
  2.        require_once('Zend/Search/Lucene.php');
  3.        在任何action中可以这样引用了
  4.        $lucene=new Zend_Search_Lucene($pathOfIndex);
  5.        $hits=$lucene->find(strtolower($keyword));


Conventions 相关协定
1.  URL
    传统GET传输参数

  1. http://hostname/index.php?r=ControllerID/ActionID

    当用到CUrlManager这个组件时候(相关参考protected/config/main.php),url变成

  1. http://hostname/ControllerID/ActionID.html


在controller文件中 设定默认显示的action
1.  public $defaultAction='login';  这样就可以显示默认的第一个action了
2.  action 也可以自由定义 跟controller一样
    定义如下:

  1.   class UpdateAction extends CAction
  2.   {
  3.       public function run()
  4.       {
  5.           // place the action logic here
  6.       }
  7.    }

  当在controller中调用此action时候。action类文件为protected/controllers/post/UpdateAction.php

  1.   class PostController extends CController
  2.   {
  3.       public function actions()
  4.       {
  5.           return array(
  6.               'edit'=>'application.controllers.post.UpdateAction',
  7.           );
  8.       }
  9.   }

 
3.  public function actions() 单独的这个函数表名执行controller时候需要前期执行某些函数
    Filters preprocess/postprocess  都有可能被用到

可以用YII的errorhandler

  1.    if($this->_category === null)
  2.    throw new CHttpException(500, 'The requested category does not exist.');