yii 笔记
Yii1.1: $_GET 可以表示为 Yii::app()->request->getQuery() $_POST 可以表示为 Yii::app()->request->post();
控制器:
路由:
控制器 ID 是一种 'path/to/xyz' 的格式,对应相应的控制器类文件protected/controllers/path/to/XyzController.php
, 其中的标志 xyz
应被替换为实际的名字 (例如 post
对应protected/controllers/PostController.php
). 动作 ID 是除去 action
前缀的动作方法名。例如,如果一个控制器类含有一个名为actionEdit
的方法,则相应的动作 ID 为 edit
。
动作:
路径别名 application.controllers.post.UpdateAction
指定动作类文件为protected/controllers/post/UpdateAction.php
.
组件事件:
public function OnClicked($event) { $this->raiseEvent('OnClicked',$event); } $component->OnClicked = $callback; $callback 指向一个有效的PHP回调 事件句柄也可以是一个PHP 5.3以后支持的匿名函数 $component->OnClicked = function($event) { ...... }
组件行为:
$component->attachBehaviour($name,$behaviour); $component->test(); $behaviour = $component->tree; $behaviour = $component->ase('tree'); $component->disableBehavior($name); // 下面的代码将抛出一个异常 $component->test(); $component->enableBehavior($name); // 现在就可以使用了 $component->test();
Best MVC Practices
The central idea behind MVC is code reusability and separation of concerns.
Model represent the underlying data strcture of a Web application.Models are often shared among different sub-applicatons of a Web application.
View are responsible of presenting models in the format that end users desire.
Controller are the glue that binds models,views and other components together into a runnable application.Controllers are responsible for dealing directly with end user requests.
In a well-designed MVC application,controller are often very thin,containing probably only a few dozen lines of code ;while models are very fat,containing most of the code responsible for representing and manipulating the data. This is because the data structure and business logic represented by models is typically very specific to the particular application,and needs to be heavily customized to meet the specific application requirements;while controller logic often follows a similar pattern across applications and therefore may well be simplified by the underlying framework or the base classes.
安全的特性赋值
$model = new LoginForm; if(isset ($_POST['LoginForm'])) $model->attributes = $_POST['LoginForm']; 相当于: foreach($_POST['LoginForm'] as $name => $value) { if($name is authenticate ) $model -> $name = $value; } --------------------华丽的分割线------------------------------ array('username, password', 'required', 'on'=>'login, register'), array('email', 'required', 'on'=>'register'), 如上所示, username 和 password 特性在 login 场景中是必填项。 而 username, password 和 email 特性在 register 场景中是必填项。 于是,如果我们在 login 场景中执行块赋值,就只有 username 和 password 会被块赋值。 因为只有它们出现在 login 的验证规则中。 另一方面,如果场景是 register ,这三个特性就都可以被块赋值。 // 在登录场景中 $model = new User('login'); if(isset($_POST['User'])) $model -> attributes = $_POST['User']; //在注册场景中 $model = new User('register'); if(isset($_POST['User'])) $model-> attributes = $_POST['User'];
触发验证
//在注册场景中创建一个User模型 ,等价于: //$model = new User; //$model -> scenario = 'regkster'; $model = new User('register'); // 将输入的值填充到模型 $model -> attributes = $_POST['User']; //执行验证 if($model->validate()) // if input are validate .... ... else ... ----------------------------------------------------- public function rules() { return array( array('username, password', 'required'), array('password_repeat', 'required', 'on'=>'register'), array('password', 'compare', 'on'=>'register'), ); }
创建模型:
class LoginForm extends CFormModel { public $username; public $password; public $rememberMe; private $_identity; public function rules() { return array( array('username,password' ,'required'), array('rememberMe','boolean'), array('password','authenticate'), ); } public function authenticate($attribute , $params) { $this-> _identity = new UserIdentity($this-> username ,$this -> password); if(!$this-> _identity -> authenticate()) $this-> addError('password','错误的用户名或密码'); } } //rules() 返回的每个规则必须是以下格式: array('AttributeList', 'Validator', 'on'=>'ScenarioList', ...附加选项);
创建动作 :
//登录表单的例子 public function actionLogin() { $model = new LoginForm; if(isset($_POST['LoginForm'])) { //收集用户输入数据 $model->attributes = $_POST['LoginForm']; //验证用户输入,并在判断输入正确后重定向前一页 if($model - > validate ()) $this-> redirect (Yii::app()-> user -> returnURL); } //显示登录表单 $this-> render('login',array('model'=> $model)); } --------------------------------------------------------------------- $model->attributes = $_POST['LoginForm']; 等同于: $model-> username = $_POST['LoginForm']['username']; $model-> password = $_POST['LoginForm']['password']; $model-> rememberMe = $_POST['LoginForm']['rememberMe']; $_POST['LoginForm'] 传递过来的是一个数组
创建表单 :
<div class = "form"> <?php echo CHtml::beginForm(); ?> <?php echo CHtml::errorSummary($model); ?> <div class = "row"> <?php echo CHtml::activeLabel($model,'username'); ?> <?php echo CHtml::activeTextField($model,'username'); ?> </div> <div class = "row "> <?php echo CHtml::activeLabel($model,'password'); ?> <?php echo CHtml::activeTextField($model,'password')?> </div> <div class = "row"> <?php echo CHtml::activeLabel($model,'rememberMe'); ?> <?php echo CHtml::activeTextField($model,'rememberMe')?> </div> <div class = "row submit"> <?php echo CHtml::submitButton('Login'); ?> </div> <?php echo CHtml::endForm(); ?> </div> <!--form End--> 使用 [CActiveForm], 上面的代码可重写为: <div class = "form"> <?php $form = $this -> beginWidget('CActiveForm'); ?> <?php echo $form -> errorSummy($model) ;?> <div class = "row" > <?php echo $form -> label($model,'username'); ?> <?php echo $form -> textField($model,'username')?> </div> <div class = "row"> <?php echo $form-> label($model,"password")?> <?php echo $form->textField($model,"password")?> </div> <div class = "row"> <?php echo $form->label($model ,'rememberMe')?> <?php echo $form->textField($model,'rememberMe')?> </div> <div class = "row submit"> <?php echo CHtml::submitButton('Login')?> </div> <?php $this-> endWidget();?> </div> <!--form -->
收集表格输入:
public function actionBatchUpdate() { //假设每一项(item)是一个'Item' 的实例 //提取要通过批量模式更新的项 $items = $this->getItemToUpdate(); if(isset($_POST['Item'])) { $valid = true; foreach($items as $i=> item) { if(isset($_POST[''Item]['$i'])) $item->attributes = $_POST['Item'][$i]; $valid = $valid && $item -> validate(); } if($valid) //如果所有项目有效 ... //则在此处做一些操作 } $this->render('batchUpdate',array('items'=> $items)); } -------------------------------------------------------------- // batchUpdate 视图的工作以在一个 HTML 表格中显示输入项 <div class = "form"> <?php echo CHtml::beginForm();?> <table> <tr><th>Name</th><th>Price</th><th>Count</th><th>Description</th></tr> <?php foreach($items as $i=>$item): ?> <td><?php echo CHtml::activeTextField($item,"[$i]name"); ?></td> <td><?php echo CHtml::activeTextField($item,"[$i]price"); ?></td> <td><?php echo CHtml::activeTextField($item,"[$i]count"); ?></td> <td><?php echo CHtml::activeTextArea($item,"[$i]description"); ?></td> </tr> <?php endforeach ;?> </table> <?php echo CHtml::submitButton("Save"); ?> <?php echo CHtml::endForm();?> </div>
使用表单生成器
//编写登录 action 代码 public function actionLogin() { $model = new LoginForm(); $form = new CForm('application.views.site.loginForm',$model); if($form->submitted('login') && $form->validate()) { $this-> redirect(array('site/index')); } else { $this->render('login',array('form'=> $form)); } } //login 的视图 <h1>Login</h1> <div class = "form"> <?php echo $form ?> </div> ----------------------------------------- 'gender' =>array( 'type'=> 'dropdownlist', 'item'=>User::model()->getGenderOptions(), 'prompt'=> 'Please select:', ), ... class User extends CActiveRecord { public function getGenderOptions { return array( 0=> 'Male', 1=> 'Female', ); } } //访问表单元素 $username = $form -> element['username']; $email = $form -> elements['user']-> elements['email']; //上面的代码可以简化为: $username = $form['username']; $email = $form['user']['email'];
创建一个嵌套的表单
public function actionRegister() { $form = new CForm('application.views.user.registerForm'); $form['user'] -> model = new User; $form['profile'] -> model = new Profile; if($form -> submitted('register') && $form -> validate()) { $user = $form['user'] -> model; $profile = $form['profile']->model; if($form -> save(false)) { $profile->userID = $user->id; $profile->save(false); $this->redirect(array('site/index')); } } $this->render('register',array('form'=>$form)); } //register 视图脚本 <h1>Register</h1> <div class = "form"> <?php echo $form ; ?> </div>
定制表单显示
class MyForm extends CForm { public function render() { $output = $this-> renderBegin(); foreach($this-> getElement() as $element) $output .= $element-> render(); $output .= $this-> renderEnd(); return $output; } } //视图脚本 _form <div class = "form"> $this-> renderPartial('_form',array('form'=>$form)); </div> //通用的表单 some complex UI elements here <?php echo $form['username']?> some complex UI elements here <?php echo $form['password']?> some complex UI elements here
数据访问对象
建立数据库连接
$connection = new CDbConnection($dsn,$username,$password); //建立连接, 你可以使用 try...catch 捕获可能抛出的异常 $connection-> active = true; ... $connection -> active = false; // 关闭连接 --------------华丽的分割线------------------------------- SQLite: sqlite:/path/to/dbfile MySQL: mysql:host=localhost;dbname=testdb PostgreSQL: pgsql:host=localhost;port=5432;dbname=testdb SQL Server: mssql:host=localhost;dbname=testdb Oracle: oci:dbname=//localhost:1521/testdb ---------------------------------------------------------- 配置 array( ..... 'components'=> array( ..... 'db' => array( 'class' => 'CDbConnection', 'connectionString'=>'mysql:host= localhost;dbname=testdb', 'username'=>'root', 'password'=>'password', 'emulatePrepare'=>true, // needed by some MySQL installations ) ) )
执行 SQL 语句
$connection= Yii::app()->db; //假设你已经建立了一个'db'连接 //如果没有,就可能需要显示建立一个连接 //$connection = new CDbConnection($dsn,$username,$password); $command = $connection -> createCommand($sql); //可以通过下面语句修改 //$command -> text = $newSQL; ------------------------------------------------------------ $rowCount = $command -> execute(); // 执行无查询SQL $dataReader = $command-> query(); //执行一个SQL查询 $rows = $command-> queryAll(); //查询并返回结果中的所有行 $row = $command -> queryRow(); //查询并返回结果中的第一行 $column = $command -> queryColumn(); //查询并返回结果中的第一列 $value = $command -> queryScalar(); //查询并返回结果中的第一行的第一个字段
获取查询结果
$data Reader = $command -> query(); //重复调用read()知道它返回false while(($row = $dataReader -> read())!= false) { ... } //使用foreach遍历数据中的每一列 foreach($dataReader as $row ) { ... } //一次性提取所有行到一个数组 $rows = $dataReader -> readAll();
使用事物
$transaction = $connection-> beginTransaction(); try { $connection -> createCommand($sql1)-> execute(); $connection -> createCommand($sql2)-> execute(); //....other SQL executions $transaction-> commit(); } catch(Exception $e) { $transaction-> rollBack(); //回滚 echo $e; }
绑定参数 (占位符)
//一条带有两个占位符":username"和 ":email"的SQL $sql = "INSERT INTO tbl_user(username,email) VALUES(:username,:email)"; $command = $connection -> createCommand($sql); //用实际的用户名替代占位符":usermame" $command -> bindParam(":username",$username,PDO::PARAM_STR); //用实际的EMAIL替代占位符":email" $command -> bindParam(":email",$email,PDO::PARAM_STR); $command -> execute(); // 使用新的参数集插入另一行 $command -> bindParam(":username", $username2,PDO::PARAM_STR); $command -> bindParam(":email",$email2,PDO::PARAM_STR); $command -> execute();
绑定列
$sql = "SELECT username , email FROM tbl_user"; $dataReader = $connection ->createCommand($sql) -> query(); //使用$username 变量绑定第一列(username) $dataReader -> bindColumn(1,$username); //使用$email变量绑定第二列(email) $dataReader -> bindColumn(2,email); while($dataReader -> read() != false) { //$username 和 $email 含有当前中的username和email ... }
使用表前缀
$sql = "SELECT * FORM {{user}}"; $users = $connection -> createCommand ($sql) ->queryAll();
Query Builder
$usre = 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(); // attaction : the following code will not work $command = Yii::app()-> db-> createCommand('Select * From tbl_user'); //the following line will not append where clause to the above SQL $command -> where ('id = :id' , array(':id' => $id)); ------------------------------------------------------- select() function select($columns = '*') select() select('id,username') select('tbl_user.id, username as name') select(array('id' , 'username')) select(array('id' , 'count(*) as num')) -------------------------------------- selectDistinct() function selectDistinct($columns) SELEC DISTINCT `id` ,`username` -------------------------------------- from() function from($tables) from('tbl_user') from('tbl_user u,public.tbl_profile p') from(array('tbl_user' , 'tbl_profile')) from(array('tbl_user','(select * from tbl_profile) p')) ------------------------------------------- where() function where($conditions,$params = array()) array(oeprator,operand1,operand2,...) where operator can be any of the following : and: or: in: not in: like: not like: or like: or not like: examples of using where: where('id = 1 or id = 2') where('id = :id1 or id = :id2',array(':id1' =>1,':id2' => 2)) where(array('or','id=1','id=2')) where(array('and' ,'id=1',array('or', 'type=2','type=3'))) where(array('in','id',array(1,2))) where(array('not in ' ,'id',array((1,2))) where(array('like','name','%Qiang%')) where(array('like','name',array(%Qiang% , %Xue%))) where(array('or like' , 'name',array('%Qiang%' , '%Xue%'))) where(array('not like ','name','%Qiang%')) where(array('or not like' ,'name' , array('%Qiang%' , '%Xue%'))) $keyword = $_GET['q']; //escape % and _ characters $keyword = strtr($keyword , array('%'=> '\%' , '_'=>'\_')); $command-> where(array('like' , 'title' , '%'.$keyword.'%')); --------------------------------------- anyWhere() function andWhere($conditions ,$params = array()) ------------------------------------- orWhere() function orWhere($conditions,$params = array()) ------------------------------------- order() function order($columns) order('name ,id desc') order(array('tbl_profile.name', 'id desc')) ---------------------------------------- limit() and offset() function limit($limit, $offset = null) function offset($offset) limit(10) limit(10,20) offset(20) -------------------------------------- join() function join($table,$conditions ,$params = array()) fucntion leftJoin($table,$conditions,$params = array()) function rightJoin($table,$conditions,$params = array()) function crossJoin($table) function naturalJoin($table) join('tbl_profile','user_id = id') leftjoin('pub.tbl_profile p','p.user_id = id AND type = :type',array(':type'=>1) --------------------------------------- group() function group($columns) group('name , id') group(array('tbl_profile.name' , 'id')) ---------------------------------------- having() function having($conditions , $params = array()) having('id=1 or id=2 ') having (array('or' , 'id=1' , 'id=2')) --------------------------- union() function union($sql) union('select * from tbl_profile')
Executing Queries
$user = Yii::app()->db->createCommand() ->select('*') ->from('tbl_user') ->queryAll();
Retrieving SQLs
$sql = Yii::app()->db->createCommand() ->selec('*') ->from('tbl_user') ->text;
Alternative Syntax of Building Queries
$command -> select(array('id' , 'username')); $command -> select = array('id' , 'username'); $row = Yii::app()-> db->createCommand(array( 'select' => array('id' , 'username'), 'from' => 'tbl_user', 'where' => 'id= :id', 'params' => array(':id'=>1) ))->queryRow();
Building Multiple Queries
$command = Yii::app()-> db-> createCommand(); $user = $command -> select('*')-> from('tbl_users')->queryAll(); $command-> reset(); // clean up the previous query $posts = $command -> select('*')->from('tbl_posts')->queryAll();
Buliding Data Manipulation Queries
insert() function insert($table,$columns) //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() function update($table,$columns , $conditions ='',$params = array()) //build and execute the following SQL: //UPDATE `tbl_user` SET `name` = :name WHERE id= :id $commond -> update('tbl_user',array( 'name' => 'Tester', ), 'id = :id' , array(':id' => 1)); ----------------------------------------------- delete() function delete($table,$conditions='',$params = array()) //build and execute the following SQL: //DELETE FROM `tbl_user` WHERE id = :id $commond -> delete('tbl_user' , 'id=:id' , array(':id ' => 1)); Building Schema Manipulation Queries createTable() function createTable($table,$columns,$options = null) //CREATE TABLE `tbl_user`( // `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, // `username` varchar(255) NOT NULL, // `location` point // )ENGINE=InnoDB createTable('tbl_user' , array( 'id' => 'pk', 'username' => 'string NOT NULL', 'location' => 'point', ),'ENGINE = InnoDB') ------------------------------------ renameTable() function renameTable($table,$newName) //RENAME TABLE `tbl_users` TO `tbl_user` renameTable('tbl_users' ,'tbl_user'); -------------------------------------- dropTable() function dropTable($table) dropTable('tbl_user') ----------------------------------- truncateTable() function truncateTable($table) truncateTable('tbl_user') --------------------------------- addColumn() function addColumn($table,$column,$type) //ALTER TABLE `tbl_user` ADD `email` varchar(255) NOT NULL addColumn('tbl_user', 'email','string NOT NULL') ------------------------------------------- dropColumn() function dropColumn($table,$column) //ALTER TABLE `tbl_user` DROP COLUMN `location` dropColumn('tbl_user' ,'location') -------------------------------------------- renameColumn() function renameColumn($table,$name,$newName) //ALTER TABLE `tbl_user` CHANGE `name` `username` varchar(255) NOT NULL renameColumn('tbl_user','name','username') --------------------------------------------- alterColumn() function alterColumn($table ,$column,$type) //ALTER TABLE `tbl_user` CHANGE `username` `username` varchar(255)NOT NULL alterColumn('tbl_user','username','string NOT NULL') ------------------------------------------------ addForeignKey() function addForeignKey($name ,$table,$columns ,$refTable, $refColumns,$delete = null , $update = null) //ALTER TABLE `tbl_profile` ADD CONSTRANT `fk_profile_user_id` //FOREIGN KEY ('user_id') REFERENCES `tbl_user`(`id`) //ON DELETE CASCADE ON UPDATE CASCADE addForeignKey('fk_profile_user_id' ,'tbl_profile' , 'user_id','tbl_user','id','CASCADE' ,'CASCADE') --------------------------------------------------- dropForeignKey() function dropForeignKey($name,$table) //ALTER TABLE `tbl_profile` DROP FOREIGN KEY `fk_profile_user_id` dropForeignKey('fk_profile_user_id' , 'tbl_profile') ------------------------------------------ createIndex() function createIndex($name,$table,$column,$unique = false) //CREATE INDEX `idx_username` ON `tbl_user` (`username`) createIndex('idx_username','tbl_user','username') --------------------------------------------- dropIndex() function dropIndex($name , $table) //DROP INDEX `idx_username` ON `tbl_user` dropIndex('idx_username' , 'tbl_user') Active Record [php] $post = new Post; $post -> title = 'sample post'; $post -> content = 'post body content'; $post -> save(); [sql] CREATE TABLE tbl_post ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, title VARCHAR(128) NOT NULL, content TEXT NOT NULL, creae_time INTEGER NOT NULL );
建立数据库连接
return array( 'components' => array( 'db' => array( 'class' => 'system.db.CDbConnection', 'connectionString'=>'sqlite:path/to/dbfile', //开启表结构缓存(schema caching )提高性能 //'schemaCachingDuration' => 3600, ), ), );
定义AR类
class Post extends CActiveRecord { public static function model($className = __CLASS__) { return parent::model($className); } public function tableName() { return 'tbl_post'; } } ------------------------- 表前缀功能 public function tableName() { return '{{post}}'; } -------------------------------- 设置title列属性 $post = new Post; $post -> title = 'a sample post'; ------------------------------------- 定义主键 public function primaryKey() { return 'id'; //对于复合主键 ,要返回一个类似如下的数组 //return array('pk1' , 'pk2'); }
创建记录
$post = new Post; $post -> title = 'sample post'; $post -> content = 'content for the sample post'; $post -> create_time = time(); $post -> save(); ---------------------------------class Post extends CActiveRecord { public $title = 'please enter a title'; ....} $post = new Post;echo $post-> title; //这显示: please enter a title $post ->create_time = new CDbExpression('NOW()');//$post->create_time = 'NOW()'; 不起作用$post->save();
读取记录
$post= Post::model()-> find($condition,$params);$post = Post::model()->findByPk($postID,$condition,$params);$post = Post::model()->findByAttributes($attributes,$condition,$params);$post = Post::model()->findBySql($sql,$params); //查找postID = 10 的那一行$post = Post::model()-> find('postID = :postID',array(':postID' => 10)); $criteria = new CDbCriteria;$criteria -> select = 'title';$criteria -> condition = 'postID = :postID';$criteria -> params = array(':postID'=>10);$post = Post::model() -> find($criteria) ; //$params不需要了//可重写为$post = Post::model()->find(array( 'select' => 'title', 'condition'=> 'postID = :postID', 'params' => array(':postID' => 10),)); $posts = Post::model()->findAll($conditions ,$params);$posts = Post::model()->findAllByPk($postIDs,$condition,$params);$posts = Post::model()->findAllByAttributes($attributes,$condition,$params);$posts = Post::model()->findAllBySql($sql,$params); $n = Post::model()-> count($condition,$params);$n = Post::model()->countBySql ($sql ,$params);$exists = Post::model()->exists($condition,$params);
更新记录
$post = Post::model() -> findByPk(10);$post-> title = 'new post title';$post -> save(); Post::model()->updateAl($attribute,$condition,$params);Post::model()->updateByPk($pk,$attribute,$condition,$params);Post::model()->updateCounters($counters,$condition,$params);
删除记录
$post = Post::model()-> findByPk(10);//假设有一个帖子,其ID为10$post->delete(); //从数据表中删除此行 //删除符合指定条件的行Post::model()->deleteAll($condition,$params);//删除符合指定条件和主键的行Post::model()->deleteByPk($pk,$condition,$params);
数据验证
if($post -> save()){ //数据有效且成功插入/更新}else{ //数据无效,调用 getError()提取错误信息} $post-> title = $_POST['title'];$post-> content = $_POST['content'];$post-> save(); //假设$_POST['Post'] 是一个以列名索引值为值的数组$post -> attributes = $_POST['Post'];$post -> save();
使用AR处理事物
$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();}
命名范围
class Post extends CActiveRecord { ... public function scopes() { return array( 'published' => array( 'condition' =>'status = 1' ), 'recently' => array( 'order'=> 'create_time DESC', 'limit' => 5, ), ); }} $posts = Post::model()->published()->recently()->findAll(); Post::model()->published()->recently()->delete();
参数化的命名范围
public function recently($limit = 5){ $this->getDbCriteria()->mergeWith(array( 'order' => 'create_time DESC', 'limit' => $limit, )); return $this;} $posts = Post::model()->published()->recently()->findAll();
默认的命名范围
class Contenr extends CActiveRecord{ public function defaultScope() { return array( 'condition' => "language='".Yii::app()->language."'", ); }} //如果下面的方法被调用,将会自动使用上面定义的查询规则:$contents = Content::model()->findAll();
关系型Active Record
声明关系
class Post extends CActiveRecord{ ... public function relations () { return array( 'author' => array(self::BELONGS_TO,'User','author_id'), 'categories' => array(self::MANY_MANY , 'Category' , 'tbl_post_category(post_id,category_id)'), ); }} class User extends CActiveRecord{ ... public function relations() { return array( 'posts' => array(self::HAS_MANY ,'Post','author_id'), 'profile' => array(self::HAS_ONE,'Profile','owner_id'), ); }}
执行关联查询
//获取ID为10的帖子$post = Post::model()->findByPk(10);//获取帖子的作者(author): 此处将执行一个关联查询$author = $post->author; $posts = Post::model()->with('author') -> findAll();$posts = Post::model()->with('author','categories') -> findAll(); $post = Post::model()->with( 'author.profile', 'author.posts', 'categories')->findAll(); $criteria = new CDbCriteria;$criteria -> with = array( 'author.profile', 'author.posts', 'categories',);$posts = Post::model()->findAll($criteria);或者 $posts = Post::model()->findAll(array( 'with' => array( 'author.profile', 'author.posts', 'categories', )));
关系型查询选项
class User extends CActiveRecord{ public function relations() { return array( 'posts'=>array(self::HAS_MANY,'Post','author_id', 'order'=>'posts.create_time DESC', 'with' => 'categories'), 'profile' => array(self::HAS_ONE ,'profile' ,'owner_id'), ); } }
Disambiguating Column Names
$posts = Post::model()->with('comments')->findAll(); $posts = Post::model()->with('comments')->findAll(array( 'order'=> 't.create_time , comments.create_time'));
Dynamic Relational Query Options
User::model()->with(array( 'posts' =>array('order' => 'post.create_time ASC'), 'profile',))->findAll(); $user = User::model()->findByPk(1);$posts = $user -> posts(array('conditon' => 'status =1'));
Relational Query Performance
public function relations(){ return array( 'comments' => array(self::HAS_MANY , 'Comment' ,'post_id','together'=>false), );} $posts = Post::model()->with(array('comments' => array('together' => false)))->findAll(); $posts = Post::model()->with( 'author.profile', 'author.posts', 'categories')->together()->findAll();
Statistical Query
class Post extends CActiveRecord { public function relations() { return array( 'commentCount' =>array(self::STAT,'Comment','post_id'), 'categoryCount' => array(self::STAT , 'Category', 'post_category(post_id,category_id)'), ); }} $posts = Post::model()->with('commentCount' , 'categoryCount') -> findAll();
Relational Query With Named Scopes
$posts = Post::model()->published()->recently()->with('comments')->findAll(); $posts = Post::model()->with('comments: recently:approved') ->findAll(); class User extends CActiveRecord{ public function relations() { return array( 'posts' => array(self::HAS_MANY , 'Post' , 'author_id', 'with'=> 'comments:approved'), ); }}
数据缓存
Yii::app()->cache()->set($id,$value,30);//保留30秒 -------------------------------------------------$value = Yii::app()->cache->get($id);if($value === false){ //缓存中没有找到$value,重新生成 //并将它存入缓存以备以后使用 //Yii::app()->cache()->set($id,$value);} // 此值将在30秒后失效 // 也可能因依赖的文件发生了变化而更快失效Yii::app()->cache()->set($id,$value,30,new CFileCacheDependency('FileName'));
片段缓存
...别的 HTML内容..<?php if($this->beginCache($id)){?>..被缓存的内容..<?php $this -> endCache(); }?>..别的HTML内容.. --------------------------------------------...其他HTML内容... <?php if($this->beginCache($id, array('duration'=>3600))) { ?> ...被缓存的内容... <?php $this->endCache(); } ?> ...其他HTML内容...//如果不设置期限 ,默认是60秒
嵌套缓存
...其他HTML内容..<?php if($this->beginCache($id1)) {?>...外部被缓存内容... <?php if($this->beginCacahe($id2)) {?> ...内部被缓存的内容 <?php $this -> endCache();?>
...外部被缓存内容...<?php $this->endCache();}?>..其他HTML内容...
页面缓存
public function fileters(){ return array( array( 'COutputCache', 'duration'=>100, 'varyByParam'=> array('id'), ), );}
动态内容
...别的HTML内容...<?php if($this->beginCache($id)){ ?>..被缓存的片段内容... <?php $this->renderDynamic($callback); ?> //$callback是回调函数 ..被缓存的内容..<?php $this->endCache(); ?>..别的HTMl内容...
yii 笔记的更多相关文章
- Yii笔记:打印sql、Form表单、时间插件、Mysql的 FIND_IN_SET函数使用、是否是post/ajax请求
语句部分: yii1版本打印最后一条执行的SQL: $this->getDbConnection()->createCommand()->select()->from()-&g ...
- Yii笔记---redirect重定向
Yii的redirect方法在CControler与CHttpRequest之中都有被定义,CController中的redirect调用了CHttpRequest中的redirect方法.我们平常调 ...
- Yii框架学习笔记(二)将html前端模板整合到框架中
选择Yii 2.0版本框架的7个理由 http://blog.chedushi.com/archives/8988 刚接触Yii谈一下对Yii框架的看法和感受 http://bbs.csdn.net/ ...
- yii的学习笔记 基本结构 自用
Yii 学习笔记 W:YII是什么? Q:Yii 是一个基于组件的高性能 PHP 框架,用于快速开发大型 Web 应用.它使Web开发中的 可复用度最大化,可以显著提高你的Web应用开发速度.Yii ...
- YII报错笔记:<pre>PHP Notice 'yii\base\ErrorException' with message 'Uninitialized string offset: 0' in /my/test/project/iot/vendor/yiisoft/yii2/base/Model.php:778
YII常见报错笔记 报错返回的代码如下: <pre>PHP Notice 'yii\base\ErrorException' with message 'Uninitialized str ...
- PHP工作笔记:使用yii migrate管理、生成数据库
第一步:进入yii migrate 通过dos(我是win7系统,其他系统类似,就是进入字符界面)打开网站目录 phpStudy/WWW/local/ddc_dlss 输入 ./yii migrate ...
- Yii源码阅读笔记(三十五)
Container,用于动态地创建.注入依赖单元,映射依赖关系等功能,减少了许多代码量,降低代码耦合程度,提高项目的可维护性. namespace yii\di; use ReflectionClas ...
- Yii源码阅读笔记(三十四)
Instance类, 表示依赖注入容器或服务定位器中对某一个对象的引用 namespace yii\di; use Yii; use yii\base\InvalidConfigException; ...
- Yii源码阅读笔记(三十三)
ServiceLocator,服务定位类,用于yii2中的依赖注入,通过以ID为索引的方式缓存服务或则组件的实例来定位服务或者组件: namespace yii\di; use Yii; use Cl ...
随机推荐
- [CSAPP笔记][第九章虚拟存储器][吐血1500行]
9.虚拟存储器 为了更加有效地管理存储器且少出错,现代系统提供了对主存的抽象概念,叫做虚拟存储器(VM). 虚拟存储器是硬件异常,硬件地址翻译,主存,磁盘文件和内核软件的完美交互. 为每个进程提供一个 ...
- sass笔记-3|Sass基础语法之样式复用和保持简洁
上一篇详述了Sass如何嵌套.导入和注释这3个基本方式来保持条理性和可读性,这一篇更进一步地阐述sass保持样式复用和简洁的方式--混合器和选择器继承--这两种方式都能复用样式,使用它们也不难,但一定 ...
- ubuntu安装kvm流程
1. 查看CPU的虚拟化支持~ egrep 'svm|vmx' /proc/cpuinfo #查看是否有内容输出 2. 更新源~ sudo apt-get update 安装KVM及virt管理软件~ ...
- bzoj 3043 (差分序列运用)
维护差分序列 显然要使差分序列的后n-1位为0 对于原来的区间操作 只需要单点修改或者两个点修改 就转化成了 对于差分序列但以一个数+ 或 - 或者一个+1同时一个- ans1=max(sum1,su ...
- Linux命令之 文件归档管理
1.文件相关知识 Linux怎样保存文件 数据 -这里数据就是文件的内容 元数据 -在linux系统中,所有与某个文件相关的额外信息都保存在一个叫做i-节点(inode)的节构中 文件名 -文件名保存 ...
- canvas在手机qq浏览器显示错乱
做大转盘的时候,使用html5 canvas 生成转盘,但在手机qq浏览器中显示错乱. 原本想在后台生成大转盘图片,后来想一想既然用图片来实现, 还不如直接由canvas 导出 toDataURL 在 ...
- 让 IE 支持HTML5 placeholder
HTML5 新增的placeholder属性已经得到现代浏览器的支持,旨在提供简单的API可以为文本输入框设置 描述输入字段预期值的提示信息(hint). 这是W3C在标准化的过程中对用户体验的更多考 ...
- JavaScript--Json对象
JSON(JavaScript Object Notation)一种简单的数据格式,比xml更轻巧.JSON是JavaScript原生格式,这意味着在JavaScript中处理JSON数据不需要任何 ...
- Qt5-控件-QRadioButton-单选按钮-用于从多个选项中选取一个-单选神器
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QRadioButton> ...
- Mysql中存储方式的区别
MySQL的表属性有:MyISAM 和 InnoDB 2种存储方式: MyISAM 不支持事务回滚 InnoDB 支持事务回滚 可以用 show create table tablename 命令看表 ...