Home >Backend Development >PHP Tutorial >A summary of Yii usage tips, a summary of Yii usage tips_PHP tutorial
This article summarizes Yii usage tips. Share it with everyone for your reference, the details are as follows:
1. What I learned from yii’s authoritative guide
db component 'schemaCachingDuration'=>3600, why doesn't it work?
Need to enable caching
How to display the SQL query time at the bottom of the page
Add
to the routes of the log componentarray( 'class'=>'CProfileLogRoute', 'levels'=>'error, warning', )
Also add
to the db component
Copy code The code is as follows: 'enableProfiling'=>true,
At the same time, in this case, you can use CDbConnection::getStats() to check how many statements were executed and how much time it took
How to know the time required to run a certain program segment
After configuring CProfileLogRoute, add
where you need to testYii::beginProfile('blockID'); //程序段 Yii::endProfile('blockID');
'enableParamLogging'=>true, what does it do?
The bind parameter of the log is followed by the value of the number
How to display all db related logs at the bottom of the page
Same as above, add
to the routes that configure the log componentarray( 'class'=>'CWebLogRoute', 'levels'=>'trace, info, error, warning', 'categories' => 'system.db.*', //'showInFireBug' => true, 将在firebug中显示日志 ),
Record logs to database
array( 'class'=>'CDbLogRoute', 'logTableName'=>'applog', 'connectionID'=>'db', ),
The runtime table applog will be automatically generated. If it cannot be generated, refer to the API to create it yourself
How to record $_GET, $_SESSION and other information, add
to each configuration in the routes above
Copy code The code is as follows: 'filter'=>'CLogFilter',
If the level setting in the log configuration is incorrect, you may not get log information
In addition, the values of level and category can be written casually,
As long as you use yii::Log("","custom level","custom category") to correspond
How to record more detailed information and stack, add
to the entry file
Copy code The code is as follows: define('YII_TRACE_LEVEL',10); The larger the number, the more detailed the record, the result is as follows
[15:31:57.226][trace][system.db.CDbCommand] Querying SQL: SHOW COLUMNS FROM `Bangdan` in E:APMServ5.2.6wwwhtdocsdayouhui.comprotectedmodelsBangdan.php (21)
in E:APMServ5.2.6wwwhtdocsdayouhui.comprotectedcomponentsHotBangdan.php (21) in E:APMServ5.2.6
If you terminate the program and see logs during debugging, you cannot use die and exit;
Use application::end, that is, Yii::app()->end(), which will trigger the onEndRequest event, and the log is recorded in this event
Notes on rewriting several placeholder methods of activeRecord
Must bring boolean return value
How to publish a resource file and quote
$css=Yii::app()->getAssetManager()->publish(dirname(__FILE__)."/aa.css"); yii::app()->clientScript->registerCssFIle($css);
If you change the default title in activelable
Override method attributeLabels
Filter bad code:
$purifier=new CHtmlPurifier; $purifier->options=array("HTML.Allowed"=>"div"); $content=$purifier->purify($content);
or
<?php $this->beginWidget('CHtmlPurifier'); ?> ...display user-entered content here... <?php $this->endWidget(); ?>
How to prevent duplicate submissions?
After submission
Copy code The code is as follows: Ccontroler->refresh();
How to display a prompt after success and remove the prompt when the user refreshes the page
Cwebuser->setFlash(); getFlash();
How to prevent repeated submissions and give a prompt after a successful submission?
In controller:
Yii::app()->user->setFlash('submit','thanks'); $this->refresh();
In view:
if(Yii::app()->user->hasFlash('submit')){ echo Yii::app()->user->getFlash('submit'); }
Usually we jump to the list page or use redirect to jump to the edit page. This is not necessary. If we still want to display the current page
The above is useful, such as displaying, editing or adding new records in the current tense
How to paginate
itemCount total number of records
CPagination represents paging information, how many pages there are, how many records per page, etc.
CLinkPager generates paging code. Custom css can give the attribute cssFile a value
$criteria=new CDbCriteria(); $pages=new CPagination("数据库中的总记录数"); $pages->pageSize=2; $pages->applyLimit($criteria);//给$criteria->limit offset等符值 $posts=Post::model()->findAll($criteria); $this->widget('CLinkPager',array('pages'=>$pages));
How to sort the list
$criteria=new CDbCriteria(); $sort = new CSort('Post'); $sort->defaultOrder=" status asc"; $sort->applyOrder($criteria); $posts=Post::model()->findAll($criteria);
When applying:
Copy code The code is as follows: $sort->link('field name')
It actually generates a url with parameters, and then applies these parameters to modify $criteria when applyingOrder to get the corresponding search results
How to generate and verify verification code:
Basic usage
Copy the code The code is as follows:26a80da47b56f4831cdf7ae7bb070476widget('CCaptcha'); ?>Check the manual for specific parameters
Principle: The CCaptcha widget will call the $captchaAction='captcha' method of the current controller when running. This method points to a class CCaptchaAction
It will generate a verification code image and record it into the session
How to display a static page
Rewrite actions:
'help'=>array( 'class'=>'CViewAction', 'basePath'=>'help', //指定目录名 'defaultView'=>'default', 'viewParam'=>'help' //get参数 ),
Assume the current controller is post
Then you can access content.php in the help directory via /post/help/help/content
You can create a subdirectory such as help/reigterhelp/content. It can be accessed through /post/help/help/registerhelp.content
When using the benefits of CViewAction, you can share layout with other views
About the url that does not have permission to access the jump
当没有权限时调用CAccessControlFilter类中的accessDenied,其调用CwebUser中的loginRequired(),记录当前的returnurl后跳转到
CWebUser配置中的loginurl,在此处登陆后,可以通过redirect跳转到复制代码 代码如下:returnurl(Yii::app()->request->redirect(Yii::app()->user->returnUrl);)
当强制显示登陆表单,比如判断用户是guest就一直列出登陆表单,不会调用loginRequired, 就得不到returnurl,这时候想跳回去,参见cookbook上相关贴子
registerCoreScript
在framework/web/js/package.php中列出的才是多对多关联条件
$criteria->addInCondition("categorys.id",$in); $criteria->addSearchCondition('Shop.name',$keyword); $shops=Shop::model()->with(array("categorys"=>array('together'=>true)))->findAll($criteria);
同时要在Shop模型中加入alias="categorys" ,另外together=true放在模型的关联中也可
YII中的RBAC权限,用数据库存item,
在system/web/auth下找到相应的sql导放到数据库中
配置
'authManager' => array( 'class' => 'CDbAuthManager', 'connectionID' => 'db', ),
如果在sql中导入的三个表的表名不是默认的,需要在这上边的配置中配置,具体的看api
$auth=Yii::app()->authManager; //$auth->createOperation("post",'postpost'); //$auth->createTask("post","posts"); $auth->createRole("post","post"); auth->assign("post",'demo'); if(Yii::app()->user->checkAccess("post")){ echo "yes"; else{ echo "no"; }
这种情况下三者是一样的
如何获得上一页的url以返回
复制代码 代码如下:Yii::app()->request->urlReferrer;
accessControl 是Ccontroller中内置的过滤方法,其它的还有ajaxOnly postOnly
CMaskedTextField此组件用于限制用户的输入,对应的jquery插件http://digitalbush.com/projects/masked-input-plugin/
在一对多,多对多查询时,the eager loading 联合所有的表生成一条语句,如果主表有limit的查询选项,那么他将单独执行,然后再执行与关联表有关的语句,返回相关表的数据对象,这就是为什么在做大优惠时,以中间表为查询条件出错的原因,
解决办法
with()返回 CActiveFinder对象,其方法together(),既使主表中有LIMIT/OFFSET 也是返回一条sql;
多对多查询时,分页有时候页中显示的条数不正确,因为有重复的项,加上复制代码 代码如下:$criteria->group = true即可
模型的rules中,验证某个字段不能重复,array('name', 'unique','message' => '有重复的名子'),
CStatePersister是yii的核心组件,提供了基于文件的数据保存方式,可以不在同的请求中使用
COutputCache 即是一个组件,又是一个filter,前者的时候用于在view中缓存内容,后者的时候用于在controller中缓存
就是说片段缓存,是把COutputCache当一个widget来用,页面缓存把COutputCache当作一个filter来用动态缓存,用CController的一个方法 renderDynamic($callback);
COutputCache几个属性,duration,dependency
另外还有几个,可以通称为Variation, 有什么作用呢?
在beginCache是需要手工指定一个id,Variation的作有就是自动给生成这个id
在布署模式的时候,有错误不会有stack样的提示,会显示一个errorxxx的错误
如何在程序有错的时候跳到指定的action
在components中设置
'errorHandler'=>array( 'errorAction'=>'site/error', ),
在此action中可以能过复制代码 代码如下:Yii::app()->errorHandler->error获得错误信息
把字符串分解成数组,并去掉空值
复制代码 代码如下:preg_split('/s*,s*/','this , is , , a test',-1,PREG_SPLIT_NO_EMPTY )
CActiveRecord::exits();判断有没有这样的记录,一般用于添加时,判断某字段有没有重复
CActiveDataProvider 一个基于ActiveRecord的数据提供源
常用的用法
$dataProvider=new CActiveDataProvider('Post', array( 'criteria'=>array(), 'pagination'=>array(), 'sort'=>array(), ));
上如
'sort'=>array( 'defaultOrder'=>'status, update_time DESC', ),
ClistView同上结合使用,其中的_view中可以用一个$data的变量,代表当前的model数据
如果dataProvider中的pagination,sort设为false,则CliveView中对应的部分也无法使用
$this->widget('zii.widgets.ClistView',array( 'dataProvider' => $dataprovider, 'itemView' => '_view', 'template' => '{items}{sorter}{pager}', 'sortableAttributes' => array( ), ));
CGridView的使用也结合$dataprovider,
用的时候主要是对columns的配置,主要有
CDataColumn, CLinkColumn, CButtonColumn and CCheckBoxColumn.具体用法看api
总的说来CgridView没有ClistView灵活
插入meta信息
Yii::app()->clientScript->registerMetaTag('keywords','关键字'); Yii::app()->clientScript->registerMetaTag('description','一些描述');
CMap::mergeArray() 比array_merge更智能的合并数组,yii中配置的合并用这个
CClipWidget 通过ob_start ob_getconent生成一段不显示的内容,可以能过CController::clips访问,如
复制代码 代码如下:$this->beginWidget('CClipWidget',array('id'=>'name','renderClip'=>true));
可以通过$this->clips['name']来显示,其中的renderClip如果为false,则在当前位置不显示内容
如果在Model一次验证多个属于,显示不同的内容?如下 [后来发现这个不起作有]
return array( array('title, content', 'required', 'message'=>'Please enter a value for {attribute}.'), // ... other rules );
获得服务器时间
复制代码 代码如下:$_SERVER['REQUEST_TIME']
维护程序时,这样子所有的请求转发到一个地方
复制代码 代码如下:'catchAllRequest'=>array('site/all'),
根据二级域名缓存
array( 'COutputCache + search', 'duration' => 120, 'varyByParam' => array('q','page'), 'varyByExpression' => "app()->request->hostInfo", ),
有多个分站时,同步登陆,基于cookie
'user'=>array( 'identityCookie'=>array('domain'=>'.dayouhui.com'), 'allowAutoLogin' => true, )
如果是基本于session
'session' => array( 'cookieParams' => array('domain' => '.dayouhui', 'lifetime' => 0), 'timeout' => 3600, ),
如何使用theme
在main.php中配置
复制代码 代码如下:'theme'=>'classic',
如何得到当前使用的主题
复制代码 代码如下:Yii::app()->theme
得到名子
复制代码 代码如下:Yii::app()->theme->name;
themes文件夹和protected是同级的,其下边某个theme的目录结果同protected/views下一样
关于skin
用theme改变view的外观,skin是用来改变widgets的外观的
skin是健值对用于初始化一个widget的属性
要对widget使用skin,需要做以下几步
1:配置
'widgetFactory'=>array( 'enableSkin'=>true, ),
2:在views下建立skins目录
3:在skins目录下建立与Widget名子一样的php文件,返回数组,即能用于widget的初始配置
4:在php文件中,如果有defautl的配置,会先找这个skin
5:如果应用了theme,程序会先去对应的theme目录下的skins中找配置文件
6:如果只是想给widget统一一个skin,建议用Customizing Widgets Globally
如果防止post跨站攻击
'request'=>array( 'enableCsrfValidation'=>true, ),
这时候生成的表单要用CHtml::form(),其会写一段代码在cookie中
防止Cookie攻击
'request'=>array( 'enableCookieValidation'=>true, ),
同时生成与得到cookie是要用 CHttpCookie
如何让表单验证不通过的提示为中文
在main.php的配置中加上
复制代码 代码如下:'language' => 'zh_CN',
如何实现仿google的自动完成功能
<?php $this->widget('CAutoComplete', array( 'name'=>'xxx', 'url'=>array('suggestTags'), 'multiple'=>false, 'htmlOptions'=>array('size'=>50), )); ?>
然后在url指定的地址中的方法中如下输出,即可
echo "anbnc"
//CGridView详解
这东西在后台比较有用,能加速开发的速度,值得一看
CGridView用表格的方式显示数据项
每一行代表一个数据项,一列通常代表数据项的一个属性
CGridView支持排序和分页,可以用ajax或普通的方式
CgridView必序和data provider一起使用
最简单的用法
$dataprovider = new CActiveDataProvider('Post'); $this->widget('zii.widgets.grid.CGridView',array( 'dataProvider'=>$dataprovider, ));
这会用表格的方式显示每一条数据项,每一列是Post的一个属性
在显示中带了分页和排序
我们可以自定义CgridView::columns属性,以自定义表格列的显示方式
这个cloumns如何配置呢?
其是一个数组,每一个数组元素对应着一列的配置,可以是字符串或数组
1、如果是字符串,格式是name:type:header 后两者是可选的,根据这三个值,创建一个CdatColumn实例
其中type参见CFormatter
2、如果是数组,其可以实例化CDdataColumn、ClinkColumn,CButtonColumn,CCheckBoxColumn实例,具体实例化哪个由数组中的class指定,默认是CDataColumn
2.1,如果复制代码 代码如下:class=>'CDataCloumn'
则可以指定name或者value,如果指定以value优先
用CDataColumn时如何以关联表的数据序列?
代码如下:表示可以post关联的author中的username排序列
$dataprovider = new CActiveDataProvider('Post',array( 'criteria'=>array( 'with'=>'author', ), 'sort'=>array( 'attributes'=>array( 'title','create_time', 'author_id'=>array('asc'=>'author.username asc','desc'=>'author.username desc','label'=>'作者') ) ), )); $this->widget('zii.widgets.grid.CGridView',array( 'dataProvider'=>$dataprovider, 'columns'=>array( 'title', 'create_time', array('name'=>'author_id','value'=>'$data->author->username'), ), ));
另外CDataColumn还有一个filter属性,如果是空,那么生成一个textfield,如果是数组(键值),则生成一个dropDownlist在当前列的上部,供搜索
2.2:如果class=>"CLinkColumn"
复制代码 代码如下:array('class'=>'CLinkColumn','label'=>'查看用户','url'=>Yii::app()->createURL('user/edit'))
则生成一个连接
2.3:如果class="CCheckBoxColumn"
复制代码 代码如下:array('class'=>'CCheckBoxColumn','name'=>'title','id'=>'select'),
可以生成一个checkbox供选择,且只能选一个
可以配置CGridView::selectableRows 如果是0,则不能选,如果 1,只选一个如果是2或其它值,则可以选多个
代码如下:
$this->widget('zii.widgets.grid.CGridView',array( 'dataProvider'=>$dataprovider, 'selectableRows'=>2, 'columns'=>array( array('class'=>'CCheckBoxColumn','name'=>'title','id'=>'select'), ),
2.3:如果class="CButtonColumn"
array( 'class'=>'CButtonColumn', 'updateButtonUrl'=>'Yii::app()->createUrl("post/edit",array("id"=>$data->id));', ),
修改updateButtonUrl为编辑贴子
如何用gridview生成一个代搜索的管理列表
1、在Model的rules 设定可以搜索的属性
复制代码 代码如下:array('title, status, create_time', 'safe', 'on'=>'search'),
2、在Model中,添加搜索时的方法
public function search() { $criteria=new CDbCriteria; $criteria->compare('title',$this->title,true); $criteria->compare('status',$this->status); $criteria->compare('create_time',$this->create_time); return new CActiveDataProvider('Post', array( 'criteria'=>$criteria, 'sort'=>array( 'defaultOrder'=>'status, update_time DESC', ), )); }
3、在Controler中,写接受搜索用到的表单的值的方法
public function actionAdmin() { $model=new Post('search'); if(isset($_GET['Post'])) $model->attributes=$_GET['Post']; $this->render('admin',array( 'model'=>$model, )); }
4、在view中用CGridView显示
设置好
<?php $this->widget('zii.widgets.grid.CGridView', array( 'dataProvider'=>$model->search(), 'filter'=>$model, 'columns'=>array( ), )); ?>
以上代码大部分是yii自动生成的,只要做少量修改即可
有时候会出现,搜索后页面为空的清况,原因可能是
layout/main.php中
echo $content外层无div,就是说main.php中必须有一个div包含$content
其用列表的形式显示数据,不象CGridView一样,用表格显示数据,CListView用一个 view模板来显示每一条数据
其支持排序与分页
常用的代码如下
<?php $dataProvider = new CActiveDataProvider('Post',array( 'pagination'=>array( 'pageSize'=>2 ), )); $this->widget('zii.widgets.CListView',array( 'dataProvider'=>$dataProvider, 'itemView'=>'_view', 'template'=>' {summary} {items} {pager}{sorter}', 'sortableAttributes'=>array( 'title', 'create_time'=>'Post Time', ), ));
快速生成表单,支持ajax验证,对于比较复杂的验下最好是自己生成表单,写验证方法
常用代码,在Controller中
public function actionForm() { $post = new Post(); if(isset($_POST['ajax']) && $_POST['ajax']==='post'){ echo CActiveForm::validate($post); Yii::app()->end(); } if(isset($_POST['Post'])){ $post->attributes = $_POST['Post']; if($post->save()){ echo '存成功了'; } } $this->render('form',array('post'=>$post)); }
在view中
<?php $form = $this->beginWidget('CActiveForm',array( 'id'=>'post',//这里与Controller中的ajax对应 'enableAjaxValidation'=>true, )); ?> <?php echo CHtml::errorSummary($post); ?> <?php echo $form->labelEx($post,'title');?> <?php echo $form->textField($post,'title')?> <?php echo $form->error($post,'title'); ?>
error一定要写上,要不不会触发ajax验证
<?php echo $form->labelEx($post,'content');?> <?php echo $form->textField($post,'content')?> <?php echo CHtml::submitButton($post->isNewRecord ? 'Create' : 'Save'); ?> <?php $this->endWidget(); ?> //CBreadcrumbs常用代码 <?php $this->widget('zii.widgets.CBreadcrumbs', array( 'links'=>$this->breadcrumbs, 'homeLink'=>'<span><a href="http://abc.com">shouye</a></span>', 'separator'=>'>>>' )); ?>
其中breadcrumbs中Controller中的一个属性,如果要出现导航,就要在view中给此属性附值
生成的html如下
<div class="breadcrumbs"> <span><a href="http://abc.com">shouye</a> </span>>>><span>Managde Posts</span>>>> <span>b</span>>>><span>c</span></div>
所以如果网站用到导航的时候,美工最好把导航代码定义如上
//CDetailView 用在仅仅是为了查看数据时,还是比较有用的,比如用在后台
如何在提交后显示一段提示
在控制器中
if(isset($_POST['name'])){ Yii::app()->user->setFlash('success','you are success'); $this->refresh(); }
在view中
if (Yii::app()->user->hasFlash('success')){ echo 're is'.Yii::app()->user->getFlash('success'); }else{ echo 'no'; }
如何得到当前域名:
复制代码 代码如下:app()->request->hostInfo
activeDropDownList,给出提示,并有值
array('empty'=>array(0=>'选择分组') <input type="submit" class="btn" value="提交" />
验证码如何生成及验证:
Controller中:
public function actions() { return array( 'captcha'=>array( 'class'=>'CCaptchaAction', 'backColor'=>0xFFFFFF, 'maxLength'=>4, 'minLength'=>4, ), ); }
View中
<?php echo CHtml::activeTextField($user, 'verifyCode');?> <?php $this->widget('CCaptcha',array( 'captchaAction' => '/site/captcha', 'showRefreshButton' => false, 'clickableImage' => true, 'imageOptions' => array('align'=>'top', 'title'=>'重新获取'), )); ?>
Model中
array('verifyCode', 'captcha', 'captchaAction'=>'site/captcha', 'message' => '输入的验证码不正确'), set_time_limit(0);//禁止角本超时
如何想把手工的东西记录的数据库
main.php中配置log
array( 'class'=>'CDbLogRoute', 'levels'=>'info', 'logTableName'=>'Log', 'connectionID'=>'db', ),
应用时
复制代码 代码如下:Yii::log('信息','info');
deleteAllByAttributes(array("phone"=>$phones)直接接受一个数组,可以删除数组中符合条件的记录
YII_BLOG STUDY重新看了一遍yii blog,有些记录会与上边的重复
YII:Trace() 在debug模式是才记录信息,同时在main.php中的Log中的配置中的levels中要有trace,至于记录多少
栈由index.php中的YII_TRACE_LEVEL决定
配置Gii
'modules'=>array( 'gii'=>array( 'class'=>'system.gii.GiiModule', 'password'=>'123', ), ),
获得客户端IP
if($_SERVER['HTTP_CLIENT_IP']){ $ip = $_SERVER['HTTP_CLIENT_IP']; }elseif($_SERVER['HTTP_X_FORWARDED_FOR']){ $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; }else{ $ip = $_SERVER['REMOTE_ADDR']; }
CActiveForm还是比较强大的,建议在以后的项目中form都用这个来实现
layout/中的视图是可以继承的
复制代码 代码如下:bead0c01d72484362dad3d97d7ac2310beginContent('/layouts/main'); ?>
然后在中间出现$content即可
复制代码 代码如下:bead0c01d72484362dad3d97d7ac2310endContent(); ?>
create,update最好是分开放在两个action中,共用一个form,中间可以加一层view,以在头尾显示不同的东西
成段的完成一个功能的代码尽量拿出来放到一个方法中
$this->beginWidget('CMarkdown', array('purifyOutput'=>true)); echo $data->content; $this->endWidget();
linkButton,在删除时需要用js提示,可以看下这此组件中的comfirm
而且他们的提交方式都是post,是因为在jquery.yii.js写死了
具体的以在源文件中低部找到那段js中的ajaxsubmit,所在的js看下
filter是在执行action之前或之后执行的一段代码,要应用filters必须得写
CController::filters()方法
为什么在filters方法写上
return array( 'accessControl', // perform access control for CRUD operations );
能进行crud验证呢?
accessController是CContronller内置的filter,其调用
accessRules,得到验证规定,所以也要重写对应的accessRules,返回一个验证规则的数组成部分
if the application uses modules,
a root alias is also predefined for each module ID and refers to the base path of the corresponding module
如:echo YiiBase::getPathOfAlias('bbs');得到module bbs的路径
关于CUrlManager
复制代码 代码如下:'模式'=>'route'
matchValue是指,对于一个url规则,正常情况下是只看参数的名子是否一样就应用规则
如果matchValue=true,则也要看值
如,规则
'index-/<id:d+>'=>array("book/index",'matchValue'=>false), $this->createUrl('book/index', array('id'=>'abcd'));
可以应用以上规则的,
如果规则中的matchValue=true,则就不能应用了
XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。
它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,
嵌入其中Web里面的html代码会被执行
renderPartial()
render()
后者会把需要的js,css等嵌入
前者可以通过把最后一个参数设置成true完成一样的功能
addInCondition 不用考虑数组是空的情况yii会自动处理
如何得到当前url?
复制代码 代码如下:Yii::app()->request->url;
ctype_开始的几个函数,用于检查字任串是不是符合要求,代替了简单的正则表达式
CController中的setPageState可以保存同一页中的POST的表单状态
如何通过BEhavior修改CActiveRecord?
写类文件继承自
class LLog extends CActiveRecordBehavior{ public function beforeDelete($event){ $model = get_class($this->Owner); //做要做的事,比如日志或修改模型字段内容 } }
然后修改模型文件
public function behaviors() { return array( // Classname => path to Class 'LLog'=>'application.behavior.LLog', ); }
如何在应用程序处理请求之前执行一段操作?
在main.php中配置
复制代码 代码如下:'onBeginRequest' => 'function'
当然这个function方法要存在
也可以写在放口文件index.php中,代码改成如下
$app = Yii::createWebApplication($config); $app->onbeginRequest = 'begin'; $app->run(); function begin(){ echo 'yyyyydddyyyyyy'; }
为什么在CActiveRecordBehavior中用
beforesave就可以代表了事件onBeforeSave
注意基为中最上边的events方法中返回的对应关系
复制代码 代码如下:'onBeforeSave'=>'beforeSave'
在调用attacth(CBehavior中)的时候,
复制代码 代码如下:$owner->attachEventHandler($event,array($this,$handler));
就指定了事件onBeforeSave的处理函数是用本类中的beforeSave
YII中的CComponent,CEvent与Behavior及CActiveRecordBehavior个人理解
这一块教程少,今天个人理解了下,写了个小例子,有助于理解
完成如下功能,一个JTool类,继承CComponent,当其长度改变时,调用事件,输出"change me".
JTool.php在protected/components 下
<?php class JTool extends CComponent{ private $_width; public function getWidth(){ return $this->_width ? $this->_width : 1; } public function setWidth($width){ if($this->hasEventHandler('onChange')){ $this->onChange(new CEvent()); } $this->_width = $width; } public function onChange($event){ $this->raiseEvent('onChange', $event); } }
OK,功能已经实现了,找个控制器,执行
$j = new JTool(); $j->onChange = "showChange"; //给事件绑定handle showChange $j->width = 100; //调用setWidth,解发绑定的事件showChange function showChange(){ echo 'changed me'; }
现在我们想给JTool添加一个功能,返回长度的100倍,我们可以继承JTool.php写一个方法
class JToolSub extends JTool{ public function get100width(){ return $this->width*100; } }
OK,功能实现了,这个执行就简单了new JToolSub调用方法即可
上边的这两种办法,就是仅完成功能,下边演示Behavior及events来实现
如何用Behavior来实现上边的增加一个方法,返回长度的100倍的功能呢?
写类JBe
JBe.php在protected/behavior 下
class JBe extends CBehavior{ public function get100width(){ return $this->Owner->width*100; } }
OK,功能已经实现了,找个控制器,执行
$j = new JTool(); $j->attachBehavior('JBe', 'application.behavior.JBe'); echo $j->get100width();
如何用Behavior实现JTool中的长度改变时,调用一个事件的功能呢?
写类JBe
class JBe extends CBehavior{ public function events(){ return array_merge(parent::events(),array( 'onChange'=>'change', )); } public function change(){ echo 'changed'; } public function get100width(){ return $this->Owner->width*100; } }
OK,功能实现随便找个控制器,执行
$j = new JTool(); $j->attachBehavior('JBe', 'application.behavior.JBe'); $j->width = 100;
这里的要点是events方法
返回的数组array('onChange'=>'change')定义了事件(event)和对应的事件处理方法(event hander)
事件是是Compents(JTool中)定义的,即JTool中的onChange
处理方法同由Behavior(JBe中)类定义的,即JBe中的change
这样子再看CActiveRecordBehavior,其是绑定给CActiveRecord 这个组件的,绑定方法重写behaviors()
CActiveRecordBehavior中的events() 方法返回事件及事处理函数的对应,如:
复制代码 代码如下:'onBeforeSave'=>'beforeSave'
即组件CActiveRecord中的onBeforeSave这个事件对应的处理函数是CActiveRecordBehavior中的beforeSave方法
这样子CActiveRecord在调用save()时,触发事件onBeforeSave,调用CActiveRecordBehavior对应的处理函数beforeSave
我们只要写一个CActiveRecordBehavior的子类,重写其中的beforeSave,执行一些操作,然后给CActiveRecord绑定即可
如果你自己有个目录下有些类或文件常用,可以在main.php的最上边定义一个路径别名
复制代码 代码如下:Yii::setPathOfAlias('local','path/to/local-folder');
如果是多个可以在main.php中的array中加一个配置
'aliases'=>array( 'local'=>'path/to/local/' ),
如何得到proteced目录的物理路径?
复制代码 代码如下:YII::app()->basePath;
widget是发布资源
$url = Yii::app()->getAssetManager()->publish(Yii::getPathOfAlias('application.components.homeuserlived')); cs()->registerCoreScript('jquery'); cs()->registerScriptFile($url.'/location.js' ,CClientScript::POS_HEAD); cs()->registerScriptFile($url.'/YLChinaArea.js' ,CClientScript::POS_HEAD); cs()->registerCssFile($url.'/style.css');
如何写application component, 即在main.php可配置
复制代码 代码如下:"my"=>array('')
可以通过Yii::app()->my来访问?
继承CApplicationComponent即可,并可以自带Behavior等
yii中读写session的两种方法
$session = Yii::app()->session; $session['terry'] = 30; var_dump($session['key']); Yii::app()->user->setState('tom', '40'); var_dump(Yii::app()->user->getState('key', 'default'));
soap非yii教程,意思是不用yii框架的时候要对象提供webservice的写法
分两种WSDL模式,和非WSDL模式,先看后者
这个也比较简单,服务器端server.php:
<?php ini_set('soap.wsdl_cache_enabled',0); class Student { public function getInfo($name,$age){ if($age == 20){ throw new SoapFault(-1, 'Cannot divide by zero!'); } $xml = "<root><name>".$name."</name>"; $xml .= "<age>".$age."</age></root>"; return $xml; } } $soapS = new SoapServer(null,array('uri' => 'http://www.dayouhui.com')); $soapS->setClass('Student'); $soapS->handle(); ?>
客户端client.php:
<?php $soap = new SoapClient(null,array('location'=>"http://localhost/mysoap/index.php",'uri'=>'inadex.php')); echo $soap->getInfo('a','b');
这样子即可
yii,Componnts那快,忘了,写了个小例子回忆了下
是写一个可以写在main.php中的Components并绑定行为,事件
class ExtWindow extends CApplicationComponent{ private $title = 'title'; public $oldtitle; public function getTitle(){ return $this->title ? $this->title : 'old title<br />'; } public function setTitle($title){ echo '=='.$this->oldtitle.'=='; $this->oldtitle = $this->title; $this->title = $title; if($this->hasEventHandler('onTitleChange')){ $event =new CEvent($this); $this->raiseEvent('onTitleChange', $event); } } //必须有这么个方法,其和raiseEent中的事件一样,具体看代码 public function onTitleChange($event){ } }
<?php class Window extends CBehavior{ public function events(){ return array_merge(parent::events(),array( 'onTitleChange'=>'titleChange', )); } public function titleChange($event){ echo $event->sender->title; echo 'event TitleChange is handled in Behavior<br />'; echo $this->owner->title; } public function titleOld(){ echo '<br />old title is is '.$this->owner->oldtitle; } }
main.php中的写法
'ExtWin'=>array( 'class' => 'ExtWindow', 'oldtitle'=>'我是旧的', 'behaviors'=>array('win'=>'application..behavior.Window')
一对多,多对多的关联时最后的参数 together说明
如果为false,分开查多个语句
如果为true,强制生成一个语句
如果没有设置,分页页生成多个语句,不分页时生成一个语句
),
多对多时,查询时,中间表的名子叫 (关联名_关联名)
with选项的作用是eager loading
together的作用是 要不要形成一个语句
当是一个sql语句是记录会有重复,这时候分页分出现相同的记录,加上group=>true即可,
只要弄明白了,你生成的sql是一条还是多条sql就明白在多对多查询时的结果了
The two tables are not related by primary key
Copy code The code is as follows: 'user' => array(self::BELONGS_TO, 'OaskUser', '','on'=>'name=userName', ' select'=>'TrueName'),
The strap talbeprefix is a multi-pair association, the key is written
Copy code The code is as follows: 'categories'=>array(self::MANY_MANY,'Category','{{post_category}}(post_id,category_id)'),
I hope this article will be helpful to everyone’s PHP program design based on the Yii framework.