Active Record (AR) 类及实现

Active Record (AR) 是一个流行的 对象-关系映射 (ORM) 技术。 每一个 AR 类表明一个数据表(或视图),数据表(或视图)的列在 AR 类中体现为类的属性,一个 AR 实例则表示表中的一行。 常见的 CRUD 操做做为 AR 的方法实现。所以,咱们能够以一种更加面向对象的方式访问数据。 例如,咱们可使用如下代码向 tbl_post 表中插入一个新行。php

yii 表单验证规则html

<?php
classContactFormextendsCFormModel
{
    public$_id;
    public$contact;//联系人
    public$tel;//电话
    public$fax;//传真
    public$zipcode;//邮编
    public$addr;//地址
    public$mobile;//手机
    public$email;//邮箱
    public$website;//网址
    public$qq;//QQ
    public$msn;//MSN
    publicfunctionrules()
    {
        returnarray(
            array('contact','required','on'=>'edit','message'=>'联系人必须填写.'),
            array('contact','length','on'=>'edit','min'=>2,'max'=>10,'tooShort'=>'联系人长度请控制在2-10个字符.','tooLong'=>'联系人长度请控制在2-10个字符.'),
             
            array('tel','match','pattern'=>'/^(\d{3}-|\d{4}-)(\d{8}|\d{7})?$/','message'=>'请输入正确的电话号码.'),
            array('fax','match','pattern'=>'/^(\d{3}-|\d{4}-)(\d{8}|\d{7})?$/','message'=>'请输入正确的传真号码.'),
            array('mobile','match','pattern'=>'/^13[0-9]{1}[0-9]{8}$|15[0189]{1}[0-9]{8}$|189[0-9]{8}$/','message'=>'请输入正确的手机号码.'),
 
            array('email','email','on'=>'edit','message'=>'邮箱输入有误.'),
             
            array('zipcode','required','on'=>'edit','message'=>'邮编必须填写.'),
            array('zipcode','numerical','on'=>'edit','message'=>'邮编是6位数字.'),
            array('zipcode','length','on'=>'edit','min'=>6,'max'=>6,'tooShort'=>'邮编长度为6位数.','tooLong'=>'邮编长度为6位数.'),
             
            array('website','url','on'=>'edit','message'=>'网址输入有误.'),
            array('qq','match','pattern'=>'/^[1-9]{1}[0-9]{4,11}$/','message'=>'请输入正确的QQ号码.'),
            array('msn','email','on'=>'edit','message'=>'MSN输入有误.'),
        );
    }
 
}


$post=Post::model()->find(array(
    'select'=>'title',
    'condition'=>'postID=:postID',
    'params'=>array(':postID'=>10),
));
// 查找 postID=10 的那一行
$post=Post::model()->find('postID=:postID', array(':postID'=>10));
$criteria = new CDbCriteria();
$criteria->select = 'table_name,model_id,sum(amount) total';
$criteria->group = 'table_name,model_id';
$criteria->addCondition("$nIdcId=4");//也能够$criteria->condition = "$nIdcId=4";
$aResult = accessory_info::model()->findAll($criteria);


$c = new CDbCriteria();
$c->select = 't.id, t.created_at, t.outsource_id, t.user_id, t.operate, t.content';
$c->join = 'LEFT JOIN outsource ON outsource.id=t.outsource_id';
$c->condition = 'outsource.idc_id IN(' . implode(',', $idc_ids)  . ')';

if($last_log_id) {
$c->condition .= " AND t.id > $last_log_id";
}

$c->limit = 20;
$c->order = 't.id DESC';

$logs = OutsourceProcessLog::model()->findAll($c);

array(
'header'=>'支付渠道',
'name'=>'buy_method_id',
'value'=>'$data->buyMethod->title',
'filter'=>CHtml::listData(CoinBuyMethod::model()->findAll(), 'id', 'title'),//filter过滤筛选
),
array(
'name' => 'admin.username',
'filter' => CHtml::activeDropDownList($model, 'admin_id', CHtml::listData(Admin::model()->findAll(), 'id', 'username'), array('empty' => '-所有管理员-')),
),


$post=new Post;
$post->title='sample post';
$post->content='post body content';
$post->save();

$User = User::model();
$User->setIsNewRecord(true);
$User->name='wangliweid';
$User->sex=1;
$User->insert(); 

$User = new User;
$User->name='wangdsdfliweid';
$User->insert(); 

$User = User::model()->findByPk(1);
$User->name='wangliwei';
$User->sex=1;
$User->save();

public function tableName()
{
    return '{{post}}'; //使用表前缀功能
}

$post=Post::model()->findByPk(10); // 假设有一个帖子,其 ID 为 10
$post->delete(); // 从数据表中删除此行

AR 依靠表中良好定义的主键。若是一个表没有主键,则必须在相应的 AR 类中经过以下方式覆盖 primaryKey() 方法指定哪一列或哪几列做为主键。

public function primaryKey()
{
    return 'id';
    // 对于复合主键,要返回一个相似以下的数组
    // return array('pk1', 'pk2');
}

3. 建立记录 
要向数据表中插入新行,咱们要建立一个相应 AR 类的实例,设置其与表的列相关的属性,而后调用 save() 方法完成插入:

$post=new Post;
$post->title='sample post';
$post->content='content for the sample post';
$post->create_time=time();
$post->save();


记录在保存(插入或更新)到数据库以前,其属性能够赋值为 CDbExpression 类型。 例如,为保存一个由 MySQL 的 NOW() 函数返回的时间戳,咱们可使用以下代码:

$post=new Post;
$post->create_time=new CDbExpression('NOW()');
// $post->create_time='NOW()'; 不会起做用,由于
// 'NOW()' 将会被做为一个字符串处理。
$post->save();
提示: 因为 AR 容许咱们无需写一大堆 SQL 语句就能执行数据库操做, 咱们常常会想知道 AR 在背后到底执行了什么 SQL 语句。这能够经过开启 Yii 的 日志功能 实现。例如,咱们在应用配置中开启了 CWebLogRoute ,咱们将会在每一个网页的最后看到执行过的 SQL 语句。

4. 读取记录 
要读取数据表中的数据,咱们能够经过以下方式调用 find 系列方法中的一种:

// 查找知足指定条件的结果中的第一行
$post=Post::model()->find($condition,$params);
// 查找具备指定主键值的那一行
$post=Post::model()->findByPk($postID,$condition,$params);
// 查找具备指定属性值的行
$post=Post::model()->findByAttributes($attributes,$condition,$params);
// 经过指定的 SQL 语句查找结果中的第一行
$post=Post::model()->findBySql($sql,$params);


$criteria=new CDbCriteria;
$criteria->select='title';  // 只选择 'title' 列
$criteria->condition='postID=:postID';
$criteria->params=array(':postID'=>10);
$post=Post::model()->find($criteria); // $params 不须要了
注意,当使用 CDbCriteria 做为查询条件时,$params 参数再也不须要了,由于它能够在 CDbCriteria 中指定,就像上面那样。

一种替代 CDbCriteria 的方法是给 find 方法传递一个数组。 数组的键和值各自对应标准(criterion)的属性名和值,上面的例子能够重写为以下:

$post=Post::model()->find(array(
    'select'=>'title',
    'condition'=>'postID=:postID',
    'params'=>array(':postID'=>10),
));



// 获取知足指定条件的行数
$n=Post::model()->count($condition,$params);
// 经过指定的 SQL 获取结果行数
$n=Post::model()->countBySql($sql,$params);
// 检查是否至少有一行复合指定的条件
$exists=Post::model()->exists($condition,$params);

直接更新数据表中的一行或多行而不首先载入也是可行的。 AR 提供了以下方便的类级别方法实现此目的:

// 更新符合指定条件的行
Post::model()->updateAll($attributes,$condition,$params);
// 更新符合指定条件和主键的行
Post::model()->updateByPk($pk,$attributes,$condition,$params);
// 更新知足指定条件的行的计数列
Post::model()->updateCounters($counters,$condition,$params);
在上面的代码中, $attributes 是一个含有以 列名做索引的列值的数组; $counters 是一个由列名索引的可增长的值的数组;$condition 和 $params 在前面的段落中已有描述。

若是一个 AR 实例被一行数据填充,咱们也能够删除此行数据。

$post=Post::model()->findByPk(10); // 假设有一个帖子,其 ID 为 10
$post->delete(); // 从数据表中删除此行
注意,删除以后, AR 实例仍然不变,但数据表中相应的行已经没了。

使用下面的类级别代码,能够无需首先加载行就能够删除它。

// 删除符合指定条件的行
Post::model()->deleteAll($condition,$params);
// 删除符合指定条件和主键的行
Post::model()->deleteByPk($pk,$condition,$params);



当调用 save() 时, AR 会自动执行数据验证。 验证是基于在 AR 类的 rules() 方法中指定的规则进行的。 关于验证规则的更多详情,请参考 声明验证规则 一节。 下面是保存记录时所需的典型的工做流。

if($post->save())
{
    // 数据有效且成功插入/更新
}
else
{
    // 数据无效,调用  getErrors() 提取错误信息
}
当要插入或更新的数据由最终用户在一个 HTML 表单中提交时,咱们须要将其赋给相应的 AR 属性。 咱们能够经过相似以下的方式实现:

$post->title=$_POST['title'];
$post->content=$_POST['content'];
$post->save();

若是有不少列,咱们能够看到一个用于这种复制的很长的列表。 这能够经过使用以下所示的 attributes 属性简化操做。 更多信息能够在 安全的特性赋值 一节和 建立动做 一节找到。

// 假设 $_POST['Post'] 是一个以列名索引列值为值的数组
$post->attributes=$_POST['Post'];
$post->save();


CActiveRecord 提供了几个占位符方法,它们能够在子类中被覆盖以自定义其工做流。

beforeValidate 和
beforeSave 和 afterSave: 这两个将在保存 AR 实例以前和以后被调用。
beforeDelete 和 afterDelete: 这两个将在一个 AR 实例被删除以前和以后被调用。
afterConstruct: 这个将在每一个使用 new 操做符建立 AR 实例后被调用。
beforeFind: 这个将在一个 AR 查找器被用于执行查询(例如 find(), findAll())以前被调用。 1.0.9 版本开始可用。
afterFind: 这个将在每一个 AR 实例做为一个查询结果建立时被调用。

10. 使用 AR 处理事务 
每一个 AR 实例都含有一个属性名叫 dbConnection ,是一个 CDbConnection 的实例,这样咱们能够在须要时配合 AR 使用由 Yii DAO 提供的 事务 功能:

$model=Post::model();
$transaction=$model->dbConnection->beginTransaction();
try
{
    // 查找和保存是可能由另外一个请求干预的两个步骤
    // 这样咱们使用一个事务以确保其一致性和完整性
    $post=$model->findByPk(10);
    $post->title='new post title';
    $post->save();
    $transaction->commit();
}
catch(Exception $e)
{
    $transaction->rollBack();
}

$url=$this->createUrl($route,$params);
$this指的是控制器实例; $route指定请求的route 的要求;$params 列出了附加在网址中的GET参数。

默认状况下,URL以get格式使用createUrl 建立。例如,提供$route='post/read'和$params=array('id'=>100) ,咱们将得到如下网址:

/index.php?r=post/read&id=100

$user = Yii::app()->db->createCommand()->select('id, username, profile')->from('tbl_user u')->join('tbl_profile p', 'u.id=p.user_id')->where('id=:id', array(':id'=>$id))->queryRow();

$command = Yii::app()->db->createCommand('SELECT * FROM tbl_user');
$user = $command->queryRow();

$command = Yii::app()->db->createCommand();
$users = $command->select('*')->from('tbl_users')->queryAll();
$command->reset();  // clean up the previous query
$posts = $command->select('*')->from('tbl_posts')->queryAll();

// build and execute the following SQL:
// INSERT INTO `tbl_user` (`name`, `email`) VALUES (:name, :email)
$command->insert('tbl_user', array(
    'name'=>'Tester',
    'email'=>'tester@example.com',
));

// UPDATE `tbl_user` SET `name`=:name WHERE id=:id
$command->update('tbl_user', array(
    'name'=>'Tester',
), 'id=:id', array(':id'=>1));

4. Building Schema Manipulation Queries 
Besides normal data retrieval and manipulation queries, the query builder also offers a set of methods for building and executing SQL queries that can manipulate the schema of a database. In particular, it supports the following queries:

createTable(): creates a table
renameTable(): renames a table
dropTable(): drops a table
truncateTable(): truncates a table
addColumn(): adds a table column
renameColumn(): renames a table column
alterColumn(): alters a table column
dropColumn(): drops a table column
createIndex(): creates an index
dropIndex(): drops an index

若是浏览器重定位到登陆页面,并且登陆成功,咱们将重定位浏览器到引发验证失败的页面。咱们怎么知道这个值呢?咱们能够经过用户部件的returnUrl 属性得到。咱们所以能够用以下执行重定向:

Yii::app()->request->redirect(Yii::app()->user->returnUrl);




$this->preinit();
$this->init();

self::$classMap 能够在这里定义类的路径,在autoload里调用

//页面缓存控制器入口
可在main.php 中  设置catchAllRequest
$route=$this->catchAllRequest[0];

CModule 重载了 Ccomponent 的__get 方法

Yii::setApplication($this); 将app设置为了application对象

先注册component,这时并无加载他们,只有在getcomponet时才加载。


 var menuId = $("ul.nav").first().attr("id");var request = $.ajax({  url: "script.php",  type: "POST",  data: {id : menuId},  dataType: "html"}); request.done(function(msg) {  $("#log").html( msg );}); request.fail(function(jqXHR, textStatus) {  alert( "Request failed: " + textStatus );}); 

Example: Load and execute a JavaScript file.
 $.ajax({  type: "GET",  url: "test.js",  dataType: "script"}); 

设置cookie
$cookie = new CHttpCookie('mycookie','this is my cookie');
$cookie->expire = time()+60*60*24*30;  //有限期30天
Yii::app()->request->cookies['mycookie']=$cookie;
这里的cookies 继承了CCookieCollection ,他是CMap类型,重写了add等等,在add中设置了cookie.
好比$cookie = Yii::app()->request->cookies;
$cookies['name'] = $cookie;
复制
读取cookie:
$cookie = Yii::app()->request->getCookies();
echo $cookie['mycookie']->value;
复制
销毁cookie:
$cookie = Yii::app()->request->getCookies();
unset($cookie[$name]);

//异步提交
$('#g').click(function(){
$.post('index.php',$('form').serialize());
}); 

//在控制器中都会先执行init 再执行beforeAction

过滤器
public function filterAccessAuth($filterChain) {  
echo 'a';
$filterChain->run();
}

public function filterAbc($filterChain) {  
$filterChain->run();
}
public function filters() {  
        return array(  
            'accessAuth  + session',  
'abc',
        );  
    }

Similar to .empty(), the .remove() method takes elements out of the DOM. Use .remove() when you want to remove the element itself, as well as everything inside it. In addition to the elements themselves, all bound events and jQuery data associated with the elements are removed. To remove the elements without removing data and events, use .detach() instead.

$.ajax({  url: "test.html",  context: document.body}).done(function() {  $(this).addClass("done");});

Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are deprecated as of jQuery 1.8. To prepare your code for their eventual removal, use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.

原生js设置属性
 this.style.color = "blue";
 js原生函数:decodeURIComponent()
最后为了更好的区分attribute和property,基本能够总结为attribute节点都是在HTML代码中可见的,而property只是一个普通的名值对属性。

 Yii中有个场景的概念,咱们用到场景的地方主要是在model中定义rules规则的时候,能够对不一样的场景使用不一样的校验规则,因此,天然而然会认为所谓的场景就是对应的action的名字。其实场景和action的名字是不一样的概念来的,不能混为一谈。scenario则是M的一种属性,理论上,scenario是独立于action概念的,能够在没有action的场合下使用scenario。model的scenario是经过设置它的scenario属性设置的,它和使用model的action没有任何关系。

好比:

$model=new User;
$model->scenario = 'create';


$model=new User('create');

都是设置了执行一个action的时候对model进行校验的场景

public function rules()
{
return array(
array('name','required'),
array('name', 'length', 'max'=>10,'min'=>5,'on'=>'a1 a2','except'=>'c1 c2'), on 用来设置场景,except用来排除场景
array('sex','required myvalitor'),
);
}

当model调用model->validate()时将加载rules中包含的类,每一个涉及到的属性都会被被判断。

public function myvalitor($name,$params){}

$loginType = Yii::app()->controller->module->loginType;
Yii::app()->controller //当前请求的controller对象
Yii::app()->controller->module//当前请求的controller对象所属的module

在main的  'params' => include(dirname(__FILE__) . '/params.php'),里设置一些其余信息。

$this->redirect() //控制器的方法
$this->createUrl() //控制器的方法


public function run()
{
if($this->hasEventHandler('onBeginRequest'))
$this->onBeginRequest(new CEvent($this));
$this->processRequest();
if($this->hasEventHandler('onEndRequest'))
$this->onEndRequest(new CEvent($this));
}

public function run($actionID)
{
if(($action=$this->createAction($actionID))!==null)
{
if(($parent=$this->getModule())===null)
$parent=Yii::app();
if($parent->beforeControllerAction($this,$action))
{
$this->runActionWithFilters($action,$this->filters());
$parent->afterControllerAction($this,$action);
}
}
else
$this->missingAction($actionID);
}


//yii 执行流程
获取控制器,init,filters ,beforeAction,

filter 的循环
filter 链经过调用自身的run($this) 造成一个循环,循环结束条件为filter容器中的全部filter都执行完毕,若是一个filter没有运行run,那么action将不会执行,这样就实现了过滤做用。


public function filter($filterChain)
{
if($this->preFilter($filterChain))
{
$filterChain->run();
$this->postFilter($filterChain);
}
}
从上边能够看出,以类实现的filter,将过滤函数通常写在方法prefilter中

CActiveDataProvider provides data in terms of ActiveRecord objects which are of class modelClass. It uses the AR CActiveRecord::findAll method to retrieve the data from database. The criteria property can be used to specify various query options. 

$dataProvider=new CActiveDataProvider('Post', array(
    'criteria'=>array(
        'condition'=>'status=1',
        'order'=>'create_time DESC',
        'with'=>array('author'),
    ),
    'pagination'=>array(
        'pageSize'=>20,
    ),
));
// $dataProvider->getData() will return a list of Post objects

When data needs to be rendered in multiple pages, we can use CPagination to represent information such as total item count, page size, current page, etc. These information can be passed to pagers to render pagination buttons or links. 

Example: 

Controller action:
function actionIndex(){
    $criteria=new CDbCriteria();
    $count=Article::model()->count($criteria);
    $pages=new CPagination($count);

    // results per page
    $pages->pageSize=10;
    $pages->applyLimit($criteria);
    $models=Article::model()->findAll($criteria);

    $this->render('index', array(
    'models' => $models,
         'pages' => $pages
    ));
}


View:
<?php foreach($models as $model): ?>
    // display a model
<?php endforeach; ?>

// display pagination
<?php $this->widget('CLinkPager', array(
    'pages' => $pages,
)) ?>



/**
* Renders a view.
*
* The named view refers to a PHP script (resolved via {@link getViewFile})
* that is included by this method. If $data is an associative array,
* it will be extracted as PHP variables and made available to the script.
*
* This method differs from {@link render()} in that it does not
* apply a layout to the rendered result. It is thus mostly used
* in rendering a partial view, or an AJAX response.
*
* @param string $view name of the view to be rendered. See {@link getViewFile} for details
* about how the view script is resolved.
* @param array $data data to be extracted into PHP variables and made available to the view script
* @param boolean $return whether the rendering result should be returned instead of being displayed to end users
* @param boolean $processOutput whether the rendering result should be postprocessed using {@link processOutput}.
* @return string the rendering result. Null if the rendering result is not required.
* @throws CException if the view does not exist
* @see getViewFile
* @see processOutput
* @see render
*/
public function renderPartial($view,$data=null,$return=false,$processOutput=false)


/**
* Sends existing file to a browser as a download using x-sendfile.
*
* X-Sendfile is a feature allowing a web application to redirect the request for a file to the webserver
* that in turn processes the request, this way eliminating the need to perform tasks like reading the file
* and sending it to the user. When dealing with a lot of files (or very big files) this can lead to a great
* increase in performance as the web application is allowed to terminate earlier while the webserver is
* handling the request.
*
* The request is sent to the server through a special non-standard HTTP-header.
* When the web server encounters the presence of such header it will discard all output and send the file
* specified by that header using web server internals including all optimizations like caching-headers.
*
* As this header directive is non-standard different directives exists for different web servers applications:
* <ul>
* <li>Apache: {@link http://tn123.org/mod_xsendfile X-Sendfile}</li>
* <li>Lighttpd v1.4: {@link http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file X-LIGHTTPD-send-file}</li>
* <li>Lighttpd v1.5: {@link http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file X-Sendfile}</li>
* <li>Nginx: {@link http://wiki.nginx.org/XSendfile X-Accel-Redirect}</li>
* <li>Cherokee: {@link http://www.cherokee-project.com/doc/other_goodies.html#x-sendfile X-Sendfile and X-Accel-Redirect}</li>
* </ul>
* So for this method to work the X-SENDFILE option/module should be enabled by the web server and
* a proper xHeader should be sent.
*
* <b>Note:</b>
* This option allows to download files that are not under web folders, and even files that are otherwise protected (deny from all) like .htaccess
*
* <b>Side effects</b>:
* If this option is disabled by the web server, when this method is called a download configuration dialog
* will open but the downloaded file will have 0 bytes.
*
* <b>Known issues</b>:
* There is a Bug with Internet Explorer 6, 7 and 8 when X-SENDFILE is used over an SSL connection, it will show
* an error message like this: "Internet Explorer was not able to open this Internet site. The requested site is either unavailable or cannot be found.".
* You can work around this problem by removing the <code>Pragma</code>-header.
//须要加载这个模块
LoadModule xsendfile_module modules/mod_xsendfile.so
XSendFile on
XSendFilePath D:/

* <b>Example</b>:
* <pre>
* <?php
*    Yii::app()->request->xSendFile('/home/user/Pictures/picture1.jpg',array(
*        'saveName'=>'image1.jpg',
*        'mimeType'=>'image/jpeg',
*        'terminate'=>false,
*    ));
* ?>
 

* </pre>
* @param string $filePath file name with full path
* @param array $options additional options:
* <ul>
* <li>saveName: file name shown to the user, if not set real file name will be used</li>
* <li>mimeType: mime type of the file, if not set it will be guessed automatically based on the file name, if set to null no content-type header will be sent.</li>
* <li>xHeader: appropriate x-sendfile header, defaults to "X-Sendfile"</li>
* <li>terminate: whether to terminate the current application after calling this method, defaults to true</li>
* <li>forceDownload: specifies whether the file will be downloaded or shown inline, defaults to true. (Since version 1.1.9.)</li>
* <li>addHeaders: an array of additional http headers in header-value pairs (available since version 1.1.10)</li>
* </ul>
*/
public function xSendFile($filePath, $options=array())



CAction is the base class for all controller action classes. 
CAction provides a way to divide a complex controller into smaller actions in separate class files. 
Derived classes must implement run() which is invoked by controller when the action is requested.

 
CViewAction represents an action that displays a view according to a user-specified parameter.
By default, the view being displayed is specified via the view GET parameter. The name of the GET parameter can be customized via viewParam. If the user doesn't provide the GET parameter, the default view specified by defaultView will be displayed. 
Users specify a view in the format of path.to.view, which translates to the view name BasePath/path/to/view where BasePath is given by basePath. 

CForm represents a form object that contains form input specifications.

The main purpose of introducing the abstraction of form objects is to enhance the reusability of forms. In particular, we can divide a form in two parts: those that specify each individual form inputs, and those that decorate the form inputs. A CForm object represents the former part. It relies on the rendering process to accomplish form input decoration. Reusability is mainly achieved in the rendering process. That is, a rendering process can be reused to render different CForm objects. 

A form can be rendered in different ways. One can call the render method to get a quick form rendering without writing any HTML code; one can also override render to render the form in a different layout; and one can use an external view template to render each form element explicitly. In these ways, the render method can be applied to all kinds of forms and thus achieves maximum reusability; while the external view template keeps maximum flexibility in rendering complex forms. 

Form input specifications are organized in terms of a form element hierarchy. At the root of the hierarchy, it is the root CForm object. The root form object maintains its children in two collections: elements and buttons. The former contains non-button form elements (CFormStringElement, CFormInputElement and CForm); while the latter mainly contains button elements (CFormButtonElement). When a CForm object is embedded in the elements collection, it is called a sub-form which can have its own elements and buttons collections and thus form the whole form hierarchy. 

Sub-forms are mainly used to handle multiple models. For example, in a user registration form, we can have the root form to collect input for the user table while a sub-form to collect input for the profile table. Sub-form is also a good way to partition a lengthy form into shorter ones, even though all inputs may belong to the same model. 


$components=array(
'coreMessages'=>array(
'class'=>'CPhpMessageSource',
'language'=>'en_us',
'basePath'=>YII_PATH.DIRECTORY_SEPARATOR.'messages',
),
'db'=>array(
'class'=>'CDbConnection',
),
'messages'=>array(
'class'=>'CPhpMessageSource',
),
'errorHandler'=>array(
'class'=>'CErrorHandler',
),
'securityManager'=>array(
'class'=>'CSecurityManager',
),
'statePersister'=>array(
'class'=>'CStatePersister',
),
'urlManager'=>array(
'class'=>'CUrlManager',
),
'request'=>array(
'class'=>'CHttpRequest',
),
'format'=>array(
'class'=>'CFormatter',
),
)

$components=array(
'session'=>array(
'class'=>'CHttpSession',
),
'assetManager'=>array( 
'class'=>'CAssetManager',
),
'user'=>array(
'class'=>'CWebUser',
),
'themeManager'=>array(
'class'=>'CThemeManager',
),
'authManager'=>array(
'class'=>'CPhpAuthManager',
),
'clientScript'=>array(
'class'=>'CClientScript',
),
'widgetFactory'=>array(
'class'=>'CWidgetFactory',
),
);

<script>
jQuery.validator.addMethod('username',function(value, element, param) {
return false;
},'ni {0} ming zhi shu cuo le');

jQuery.validator.addMethod('cardNum',function(value,element,param){
return CardNumber.check(value,true);
},'请输入正确的身份证号码');

$('form').validate({
  keyup:false,
        rules: {
username : {
cardNum : true
}
}
})
</script>


jQuery.validator.addMethod('anoy',function(value,element,func){
return func;
});


$('form').validate({
rules:{
pass1 : {
anoy : function(){ console.log(arguments);return false;}
}
}
});

$(element).parentsUntil('table').find('input[name="pass2"]').val();

jQuery.validator.addClassRules('pas', {
        pass1: true 
    });


jQuery.validator.addMethod('username',function(value, element, param) {
return false;
},'ni {0} ming zhi shu cuo le');

jQuery.validator.addMethod('cardNum',function(value,element,param){
return CardNumber.check(value,true);
},'请输入正确的身份证号码');

jQuery.validator.addMethod('pass1',function(value,element,param){
return value == $(element).parentsUntil('table').find('input[name="pass2"]').val();
},'error');

jQuery.validator.addClassRules('pas', {
        pass1: true 
    });
$('form').validate({
rules:{
'pass1' : {
pass1 : true
}
}
});
if($(':input[name="isWrite"][checked]').val() == 1 )

A typical authentication process using CWebUser is as follows:
The user provides information needed for authentication.
An {@link IUserIdentity identity instance} is created with the user-provided information.
Call {@link IUserIdentity::authenticate} to check if the identity is valid.
If valid, call {@link CWebUser::login} to login the user, and Redirect the user browser to {@link returnUrl}.
If not valid, retrieve the error code or message from the identity instance and display it.


Yii::app()->user->setFlash('success', "Data1 saved!");
Yii::app()->user->setFlash('error', "Data2 failed!");
Yii::app()->user->setFlash('notice', "Data3 ignored.");
Display them in your view:

<?php
    foreach(Yii::app()->user->getFlashes() as $key => $message) {
        echo '<div class="flash-' . $key . '">' . $message . "</div>\n";
    }
?>
Setting flash messages 
A flash message is used in order to keep a message in session through one or several requests of the same user. By default, it is removed from session after it has been displayed to the user. Flash messages are usually used in combination with HTTP redirections, because in this case there is no view, so messages can only be displayed in the request that follows redirection.

www.ixuesi.com


CWebUser 和 CUserIdentity 的关系
CUserIdentity 经过用户名和密码验证用户,获取用户id,CWebUser可根据Id获取用户信息,保存在session中。
也可在CUserIdentity中获取信息到stats中,而后传递到CWebUser中

CAccessControlFilter 内部也是经过调用user->checkAccess()来判断权限
user里边经过CauthManager来提供checkAccess()方法。
能够利用filter 和 User->checkAccess()来使用yii的权限系统。固然也能够直接调用AuthManager来使用,这时须要手动传递User了。

能够再model的自定义rule中使用addError($attribute,$value)来添加一个错误,必须使用adderror,返回false是不起做用的。

keepalive="true": To conserve battery power and cpu usage, Paper.js normally stops all animation events when the window is not focused. If you want it to keep playing animations, even if the window is in the background, set keepalive="true" in your canvas tag. And again for validation, data-paper-keepalive="true" works as well.

CController中已经定义了三个filter:filterAccessControl,filterAjaxOnly,filterPostOnly,filterAccessControl须要和accessRules配合使用,
public function filterAccessControl($filterChain)
{
$filter=new CAccessControlFilter;
$filter->setRules($this->accessRules());
$filter->filter($filterChain);
}
public function filters()
    {
        return array(
            'accessControl',
        );
    }
public function accessRules()
    {
        return array(
            array('deny',
                'actions'=>array('create', 'edit'),
                'users'=>array('?'),
            ),
            array('allow',
                'actions'=>array('delete'),
                'roles'=>array('admin'),
            ),
            array('deny',
                'actions'=>array('delete'),
                'users'=>array('*'),
            ),
        );
    }

Yii::import()注册一个类路径

module里的一个函数 
public function init()
{
$this->setImport(array(
'application.modules.user.models.*',
'application.modules.user.components.*',
));
}

public function filters() {  
return array(  
'accessControl', //本地函数一个简单的字符串,外部类要写在数组中
array(
'COutputCache + list',
'duration'=>300,
),
);  
}

##python  
shutil — High-level file operationspython

相关文章
相关标签/搜索