本文实例汇总了Yii编程开发常见调用技巧。分享给大家供大家参考,具体如下:

本文汇总了Yii使用技巧。分享给大家供大家参考,具体如下:

复制代码 代码如下:

本文实例讲述了Yii框架常见缓存应用。分享给大家供大家参考,具体如下:

不是固若金汤,随着PHP的广泛运用,一些黑客们也在无时不想找PHP的麻烦,通过PHP程序漏洞进行攻击就是其中一种。在节,我们将从全局变量,远程文件,文件上载,库文件,Session文件,数据类型和容易出错的函数这几个方面分析了PHP的安全性。

1. 设置cookie:

一、从yii权威指中学到的

config(“dns=aaa;uid=sa;pwd=sa;dbname=test”); //3.选择数据库 $dbname =
$db->select_db; //4.设置允许调试 $db->debug = true;
//5.执行一条不返回结果的SQL语句 $db->execute(“insert into test01
values; //$db->exec; //6.执行一条返回结果的SQL语句 $rs =
$db->query(“select * from test01”); //7.以row方式显示结果 echo “
以row方式显示结果集
“; while($r = $db->fetch_row{ echo $r[0].”:”.$r[1].”
“; } //8.以array方式显示结果 $rs2 = $db->query(“select * from
test01”); echo “
以array方式显示结果集
“; while($r = $db->fetch_array{ echo $r[“id”] . “:” . $r[“name”]
. “
“; } //X.释放 $db->db_close(); ?>

1 首先,你需要安装apc or memcache or redis 。 安装完后。 以redis 为例。
至于如何安装,多找度娘。

如何通过全局变量进行攻击?

$cookie = new CHttpCookie('mycookie','this is my cookie');$cookie->expire = time()+60*60*24*30; //有限期30天Yii::app()->request->cookies['mycookie']=$cookie;

db组件 ‘schemaCachingDuration’=>3600, 为什么不起做用?

在配置文件中components 添加如下。

PHP中的变量不需要事先声明,它们会在第一次使用时自动创建,它们的类型根据上下文环境自动确定。从程序员的角度来看,这无疑是一种极其方便的处理方法。一旦一个变量被创建了,就可以在程序中的任何地方使用。这个特点导致的结果就是程序员很少初始化变量。

2. 读取cookie:

如何在页面下边显示sql的查询时间

'cache'=>array( 'class'=>'core.extensions.redis.Predis', 'class'=>'core.extensions.redis.CRedisCache', 'servers'=>array( array( 'host'=>'192.168.1.xx', 'port'=>6379, ), ), ),

很显然,基于PHP的应用程序的主函数一般都是接受用户的输入,然后对输入数据进行处理,然后把结果返回到客户端浏览器。为了使PHP代码访问用户的输入尽可能容易,实际上PHP是把这些输入数据看作全局变量来处理的。

$cookie = Yii::app()->request->getCookies();echo $cookie['mycookie']->value;

在log组件的routes中加入

2 最简单的例子。 set get.

例如:复制代码 代码如下:

3. 销毁cookie:

array('class'=>'CProfileLogRoute','levels'=>'error, warning',)
Yii::app()->cache->set('id', date; //设置有效时间为5.echo Yii::app."
";sleep->cache->get; //缓存有效期内 会输出数据sleep->cache->get; //缓存失效,输出为空

//3.1 最简单的数据库缓存。$sql = 'select * from {{settings}}';$cmd = Yii::app()->db->cache->createCommand;$rows = $cmd->queryAll();//3.2 加一个缓存依赖的概念。$dp_sql = "SELECT MAX FROM plat2_settings ";$dependency = new CDbCacheDependency;$sql = "SELECT * FROM `plat2_settings`";$rows = Yii::app()->db->cache->createCommand;

这会显示一个文本框和提交按钮。当用户点击提交按钮时,”test.php”会处理用户的输入,当”test.php”运行时,”$hello”会包含用户在文本框输入的数据。从这里我们应该看出,攻击者可以按照自己的意愿创建任意的全局变量。如果攻击者不是通过表单输入来调用”test.php”,而是直接在浏览器地址栏输入

$cookie = Yii::app()->request->getCookies();unset;

同时在db组件中加入复制代码
代码如下:’enableProfiling’=>true,同时在这种情况下,可以用CDbConnection::getStats()
查看执行了多少个语句,用了多少时间

上面的代码意思是查询对应的数据的时候,会先判断依赖查询 SELECT MAX FROM
plat2_settings 的结果数据是否有更新,

下面的用户认证代码暴露了PHP的全局变量所导致的安全问题:PHP代码复制代码 代码如下:

4. 获取更新的数据 id

如何知道某一个程序段运行需要的时间

如果有更新,则重新查询数据,如依赖未更新则直接调缓存数据。 过1000
秒后,会重新查询。

上面的代码首先检查用户的密码是否为”hello”,如果匹配的话,设置”$auth”为”1″,即通过认证。之后如果”$suth”为”1″的话,就会显示一些重要信息。

$post->save();$id = $post->attributes['id'];

配置好CProfileLogRoute后,在需要测试的地方加上

if($this->beginCache{ echo "test cache "; $this->endCache();}//beginCache 会存在第二个参数,意思是选用指定的缓存器。如果需要使用不同的缓存时,可以定制。

public function filters(){ return array( array( 'COutputCache+index+admin', 'duration' => 120, 'varyByParam'=>array;}

这段代码假定”$auth”在没有设置值的时候是空的,但是攻击者可以创建任何全局变量并赋值,通过类似”

5. 获取插入的数据 id

Yii::beginProfile;//程序段Yii::endProfile;

使用控制器,直接对指定的action 进行缓存处理 。

因此,为了提高PHP程序的安全性,我们不能相信任何没有明确定义的变量。如果程序中的变量很多的话,这可是一项非常艰巨的任务。

$id = Yii::app()->db->getLastInsertID();

‘enableParamLogging’=>true,的作用是?

还有varyBySession 可以选配。

一种常用的保护方式就是检查数组HTTP_GET[]或POST_VARS[]中的变量,这依赖于我们的提交方式。当PHP配置为打开”track_vars”选项的话,用户提交的变量就可以在全局变量和上面提到的数组中获得。

6. 获取get,post过来的数据

在日志的bind的参数后边跟数的值

更多关于Yii相关内容感兴趣的读者可查看本站专题:《Yii框架入门及常用技巧总结》、《php优秀开发框架总结》、《smarty模板入门基础教程》、《php面向对象程序设计入门教程》、《php字符串用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

但是值得说明的是,PHP有四个不同的数组变量用来处理用户的输入。HTTP_GET_VARS数组用来处理GET方式提交的变量,HTTP_POST_VARS数组用于处理POST方式提交的变量;HTTP_COOKIE_VARS数组用于处理作为cookie头提交的变量,而对于HTTP_POST_FILES数组,则完全是用户用来提交变量的一种可选方式。用户的一个请求可以很容易的把变量存在这四个数组中,因此一个安全的PHP程序应该检查这四个数组。

Yii::app()->request->getParam;

如何在页面底部显示所有的db相关的日志

希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。

如何通过远程文件进行攻击?

7. 获取ip地址

同上,配置log组件的routes中加入

PHP是一种具有丰富特性的语言,提供了大量的函数,使编程者很容易实现特定功能。但是从安全的角度来看,功能越多,要保证它的安全性就越难,远程文件就佐证这个问题的一个很好例子:复制代码 代码如下:

Yii::app()->request->userHostAddress;
array('class'=>'CWebLogRoute','levels'=>'trace, info, error, warning','categories' => 'system.db.*',//'showInFireBug' => true, 将在firebug中显示日志),

array('class'=>'CDbLogRoute','logTableName'=>'applog','connectionID'=>'db',),

上面的脚本试图打开文件”$filename”,如果失败就显示错误信息。很明显,如果我们能够指定”$filename”的话,就能利用这个脚本浏览系统中的任何文件。但是,这个脚本还存在一个不太明显的特性,那就是它可以从任何其它WEB或FTP站点读取文件。实际上,PHP的大多数文件处理函数对远程文件的处理是透明的。

8. 获得上一页的url以返回

运行时表applog会自动生成,如果不能生成,参照api自已建立

例如:如果指定”$filename”为
“”

Yii::app()->request->urlReferrer;

如何记录$_GET,$_SESSION等信息,在以上的routes中各个配置中加上复制代码
代码如下:’filter’=>’CLogFilter’,log配置中的level设置不对,可能会得不到日志信息

则上面的代码实际上是利用主机target上的unicode漏洞,执行了dir命令。这使得支持远程文件的
include,include_once在上下文环境中变得更有趣。这些函数主要功能是包含指定文件的内容,并且把它们按照PHP代码解释,主要是用在库文件上。

9. 得到当前url :

另外level,category的值可以随便写,

例如:复制代码 代码如下:

Yii::app()->request->url;

只要在用yii::Log(“”,”自定义level”,”自定义的category”)时对应起来即可

上例中”$libdir”一般是一个在执行代码前已经设置好的路径,如果攻击者能够使得”$libdir”没有被设置的话,那么他就可以改变这个路径。但是攻击者并不能做任何事情,因为他们只能在他们指定的路径中访问文件languages.php(perl中的”Poisonnull
byte”攻击对PHP没有作用)。但是由于有了对远程文件的支持,攻击者就可以做任何事情。例如,攻击者可以在某台服务器上放一个文件
languages.php,包含如下内容:复制代码
代码如下:

10. 得到当前home url :

如何记录更详细的信息,能记录stack,在入口文件中加上复制代码
代码如下:define;数字越大,记当的越详细,结果如下[15:31:57.226][trace][system.db.CDbCommand]
Querying SQL: SHOW COLUMNS FROM `Bangdan` in
E:APMServ5.2.6wwwhtdocsdayouhui.comprotectedmodelsBangdan.php in
E:APMServ5.2.6wwwhtdocsdayouhui.comprotectedcomponentsHotBangdan.php in
E:APMServ5.2.6

然后把”$libdir”设置为”

Yii::app()->homeUrl;

如果在调试时,终止程序运行且看到日志,不能用die及exit;

需要注意的是,攻击代码是不会在自身所在的服务器上执行执行自身PHP程序的,否则,攻击代码会攻击自身所在的服务器,而不是在目标服务器执行。

11. 得到当前return url :

用application::end,即Yii::app,其会触发onEndRequest事件,日志就是在这个事件中记录的

如何通过文件上载进行攻击?

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

activeRecord几个占位方法重写的注意点

PHP自动支持基于RFC 1867的文件上载,我们看下面的例子:复制代码 代码如下:

12. 项目路径 :

必须带boolean返回值

上面的代码让用户从本地机器选择一个文件,当点击提交后,文件就会被上载到服务器。这显然是很有用的功能,但是PHP的响应方式将使这项功能变得不安全。当PHP第一次接到这种请求,甚至在它开始解析被调用的PHP代码之前,它会先接受远程用户的文件,检查文件的长度是否超过”$MAX_FILE_SIZE
variable”定义的值,如果通过这些测试的话,文件就会被存在本地的一个临时目录中。因此,攻击者可以发送任意文件给运行PHP的主机,在PHP程序还没有决定是否接受文件上载时,文件已经被存在服务器上了。

dirname;

如何发布一个资源文件并引用

让我们考虑一下处理文件上载的PHP程序,正如我们上面说的,文件被接收并且是存在服务器上,扩展名一般是随机的,类似”phpxXuoXG”的形式。PHP程序需要上载文件的信息以便处理它,这可以通过两种方式,一种方式是在PHP3中已经使用的,另一种是在我们对以前的方法提出安全公告后引入的。

13. 项目目录 :

$css=Yii::app->publish."/aa.css");yii::app()->clientScript->registerCssFIle;

大多数PHP程序还是使用老的方式来处理上载文件。PHP设置了四个全局变量来描述上载文件,比如说上面的例子:

Yii::app()->request->baseUrl;

如果改变activelable中默认的标题

复制代码 代码如下:$hello = Filename on
local machine $hello_size = Size in bytes of file $hello_name = The
original name of the file on the remote system
(e.g”c:\\temp\\hello.txt”) $hello_type = Mime type of uploaded file

14. 在view中得到当前controller的ID方法:

重写方法attributeLabels

然后,PHP程序开始处理根据”$hello”指定的文件。问题在于”$hello”不一定是一个PHP设置的变量,任何远程用户都可以指定它。如果我们使用下面的方式:

Yii::app()->request->baseUrl;

过滤不良代码:

15. 在view中得到当前action的ID方法 :

$purifier=new CHtmlPurifier;$purifier->options=array("HTML.Allowed"=>"div");$content=$purifier->purify;

beginWidget; ?>...display user-entered content here...endWidget(); ?>

就导致了下面的PHP全局变量(当然POST方式也可以:复制代码 代码如下:$hello = “/etc/passwd”
$hello_size = 10240 $hello_type = “text/plain” $hello_name =
“hello.txt”

Yii::app->getAction()->id;

如何防止重复提交?

上面的表单数据正好满足了PHP程序所期望的变量,但是这时PHP程序不再处理本应在上载者本机上的上载文件,而是处理服务器上”/etc/passwd”文件。这种攻击可以用于暴露任何敏感文件的内容。

16. yii判断提交方式 :

提交后复制代码
代码如下:Ccontroler->refresh();如何在成功后显示一个提示,用户刷新页时去掉提示

新版本的PHP使用HTTP_POST_FILES[]来决定上载文件,同时也提供了很多函数来解决这个问题,例如有一个函数用来判断某个文件是不是实际上载的文件。但是实际上肯定有很多PHP程序仍然使用旧的方法,所以也很容易受到这种攻击。

Yii::app()->request->isPostRequest;
Cwebuser->setFlash;

作为文件上载的攻击方法的一个变种,我们看一下下面的一段代码:复制代码 代码如下:

17. 得到当前域名:

如何防止重复提交, 并在提交成功后给出提示?

如果攻击者可以控制”$theme”的话,很显然它可以利用”$theme”来读取远程系统上的任何文件。攻击者的最终目标是在远程服务器上执行任意指令,但是他无法使用远程文件,因此,他必须得在远程服务器上创建一个PHP文件。这乍看起来好象是不可能的,但是文件上载帮了我们这个忙,如果攻击者先在本地机器上创建一个包含PHP代码的文件,然后创建一个包含名为”theme”的文件域的表单,最后用这个表单通过文件上载把创建的包含PHP代码的文件提交给上面的代码,PHP就会把攻击者提交的文件保存起来,并把”$theme”的值设置为攻击者提交的文件,这样file_exists()函数会检查通过,攻击者的代码也将执行。获得执行任意指令的能力之后,攻击者显然想提升权限或者是扩大战果,而这又需要一些服务器上没有的工具集,而文件上载又一次帮了攻击者的忙。攻击者可以使用文件上载功能上载工具,把她们存在服务器上,然后利用他们执行指令的能力,使用chmod()改变文件的权限,然后执行。例如:攻击者可以绕过防火墙或IDS上载一个本地root攻击程序,然后执行,这样就获得了root权限。

Yii::app()->request->hostInfo;
Yii::app()->user->setFlash;$this->refresh();

if->user->hasFlash{echo Yii::app()->user->getFlash;}

如何通过库文件进行攻击?

18. 得到proteced目录的物理路径:

一般我们是跳转到列表页,或用redirect跳到编辑页,就不需要了,如果还是要显示当前页

正如我们前面讨论的那样,include主要是为了支持代码库,因为我们一般是把一些经常使用的函数放到一个独立的文件中,这个独立的文件就是代码库,当需要使用其中的函数时,我们只要把这个代码库包含到当前的文件中就可以了。

YII::app()->basePath;

以上就有用了,比如在当前时显示,编辑或添加新的记录

最初,人们开发和发布PHP程序的时候,为了区别代码库和主程序代码,一般是为代码库文件设置一个”.inc”的扩展名,但是他们很快发现这是一个错误,因为这样的文件无法被PHP解释器正确解析为PHP代码。如果我们直接请求服务器上的这种文件时,我们就会得到该文件的源代码,这是因为当把PHP作为
Apache的模块使用时,PHP解释器是根据文件的扩展名来决定是否解析为PHP代码的。扩展名是站点管理员指定的,一般是”.php”,
“.php3″和”.php4″。如果重要的配置数据被包含在没有合适的扩展名的PHP文件中,那么远程攻击者很容易得到这些信息。

更多关于Yii相关内容感兴趣的读者可查看本站专题:《Yii框架入门及常用技巧总结》、《php优秀开发框架总结》、《smarty模板入门基础教程》、《php面向对象程序设计入门教程》、《php字符串用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

如何分页

最简单的解决方法就是:给每个文件都指定一个PHP文件的扩展名,这样可以很好的防止泄露源代码的问题,但是又产生了新的问题,通过请求这个文件,攻击者可能使本该在上下文环境中运行的代码独立运行,这可能导致前面讨论的全部攻击。

希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。

itemCount总记录条数CPagination代表分页信息,有多少页,每页几条记录等CLinkPager生成分页的代码,自定义css可以给属性cssFile一个值

下面是一个很明显的例子:复制代码
代码如下:In main.php:

$criteria=new CDbCriteria();$pages=new CPagination;$pages->pageSize=2;$pages->applyLimit;//给$criteria->limit offset等符值$posts=Post::model;$this->widget('CLinkPager',array;

$criteria=new CDbCriteria();$sort = new CSort;$sort->defaultOrder=" status asc";$sort->applyOrder;$posts=Post::model;

In libdir/loadlanguage.php:

应用时用:复制代码
代码如下:$sort->link实际是生成一个带参数的url,然后在在applyOrder时应用这些参数修改$criteria,得到相应的查寻结果

当”libdir/loadlanguage.php”被”main.php”调用时是相当安全的,但是因为”libdir
/loadlanguage”具有”.php”的扩展名,因此远程攻击者可以直接请求这个文件,并且可以任意指定”$langDir”
和”$userLang”的值。

如何生成并验证验证码:

如何通过Session文件进行攻击?

基本用法复制代码 代码如下:widget;
?>具体参数查手册原理CCaptcha这个widget会在run时调用当前控制器的$captchaAction=’captcha’方法,这个方法指到一个类CCaptchaAction

PHP
4或更新的版本提供了对sessions的支持,它的主要作用是在PHP程序中保存页与页之间的状态信息。例如,当一个用户登陆进入网站,他登陆了的这个事实以及谁登陆进入这个网站的相关信息都将被保存在session中,当他在网站中到处浏览时,所有的PHP代码都可以获得这些状态信息。

其会生成验证码图象,并记入到session中

事实上,当一个session启动时(实际上是在配置文件中设置为在第一次请求时自动启动),就会生成一个随机的”session
id”,如果远程浏览器总是在发送请求时提交这个”session
id”的话,session就会一直保持。这通过Cookie很容易实现,也可以通过在每页提交一个表单变量来实现。PHP程序可以用session注册一个特殊的变量,它的值会在每个PHP脚本结束后存在session文件中,也会在每个PHP脚本开始前加载到变量中。下面是一个简单的例子:

如何显示静态页

复制代码 代码如下:

'help'=>array('class'=>'CViewAction','basePath'=>'help', //指定目录名'defaultView'=>'default','viewParam'=>'help' //get参数),

新版本的PHP都会自动把”$session_auth”的值设置为”shaun”,如果它们被修改的话,以后的脚本都会自动接受修改后的值,这对无状态的Web来说的确是种很不错的工具,但是我们也应该小心。

假定当前控制器是post

一个很明显的问题就是确保变量的确来自session,例如,给定上面的代码,如果后续的脚本是下面这样的话:复制代码 代码如下:

那么可以能过/post/help/help/content访问help目录下的content.php

上面的代码假定如果”$session_auth”被赋值的话,就是从session,而不是从用户输入来赋值的,如果攻击者通过表单输入来赋值的话,他就可以获得对站点的访问权。注意攻击者必须在session注册该变量之前使用这种攻击方法,一旦变量被放进了session,就会覆盖任何表单输入。

可以建立子目录比如help/reigterhelp/content.那可以通过/post/help/help/registerhelp.content来访问

Session数据一般是保存在文件中,文件名一般是类似”sess_”的形式,这个文件包含变量名称,变量类型,变量值和一些其它的数据。在多主机系统中,因为文件是以运行Web服务器的用户身份保存的,因此恶意的站点拥有者就可以通过创建一个session文件来获得对其它站点的访问,甚至可以检查session文件中的敏感信息。

用CViewAction的好处时,可以与其它的view共享layout

Session机制也为攻击者把自己的输入保存在远程系统的文件中提供了另一个方便。对于上面的例子来说,攻击者需要在远程系统放置一个包含PHP代码的文件,如果不能利用文件上载做到的话,他通常会利用session为一个变量按照自己的意愿赋一个值,然后猜测session文件的位置,而他知道文件名是”php”,所以只需猜测目录,而目录一般就是”/tmp”。

关于没有权限访问跳转的url相关

另外,攻击者可以任意指定”session id”,然后用这个”session
id”创建一个session文件,但是”session id”只能是字母和数字组合。

当没有权限时调用CAccessControlFilter类中的accessDenied,其调用CwebUser中的loginRequired(),记录当前的returnurl后跳转到CWebUser配置中的loginurl,在此处登陆后,可以通过redirect跳转到复制代码
代码如下:returnurl->request->redirect->user->returnUrl);)当强制显示登陆表单,比如判断用户是guest就一直列出登陆表单,不会调用loginRequired,
就得不到returnurl,这时候想跳回去,参见cookbook上相关贴子

如何通过数据类型进行攻击?

registerCoreScript

PHP
具有比较松散的数据类型,变量的类型依赖于它们所处的上下文环境。例如:”$hello”开始是字符串变量,值为””,但是在求值时,就变成了整形变量”0″,这有时可能会导致一些意想不到的结果。如果”$hello”的值为”000″还是为”0″是不同的,empty()返回的结果也不会为真。

在framework/web/js/package.php中列出的才是多对多关联条件

PHP中的数组是关联数组,也就是说,数组的索引是字符串型的。这意味着”$hello[“000”]”和”$hello[0]”也是不同的。

$criteria->addInCondition;$criteria->addSearchCondition;$shops=Shop::model()->with(array("categorys"=>array->findAll;

开发程序的时候应该仔细地考虑上面的问题,例如,我们不应该在一个地方测试某个变量是否为”0″,而在另外的地方使用empty()来验证。

同时要在Shop模型中加入alias=”categorys”
,另外together=true放在模型的关联中也可

如何通过容易出错的函数进行攻击?下面是一份比较详细的容易出错的函数列表:

YII中的RBAC权限,用数据库存item,

复制代码 代码如下:1. 2.
require():读取指定文件的内容并且作为PHP代码解释 3.
include:把给定的字符串作为PHP代码执行 5.
preg_replace():当与”/e”开关一起使用时,替换字符串将被解释为PHP代码 6.

在system/web/auth下找到相应的sql导放到数据库中

    1. exec():执行指定的命令,返回执行结果的最后一行 9.
      passthru():执行指定命令,返回所有结果到客户浏览器 10.
      “:执行指定命令,返回所有结果到一个数组 11.
      system,但是不处理二进制数据 12.
      popen():执行指定的命令,把输入或输出连接到PHP文件描述符 13. 14. 15.
      fopen():打开文件,并对应一个PHP文件描述符 16.
      readfile():读取文件的内容,然后输出到客户浏览器 17.
      file():把整个文件内容读到一个数组中
'authManager' => array('class' => 'CDbAuthManager','connectionID' => 'db',),

如何增强PHP的安全性?

如果在sql中导入的三个表的表名不是默认的,需要在这上边的配置中配置,具体的看api

我们在上面介绍的所有攻击对于缺省安装的PHP4都可以很好的实现,但是PHP的配置非常灵活,通过配置一些PHP选项,我们完全可能抵抗其中的一些攻击。下面我们按照实现的难度对一些配置进行了分类:复制代码
代码如下:*低难度**中低难度***中高难度****高难度如果你使用了PHP提供的所有选项的话,那么你的PHP将是很安全的,即使是第三方的代码也是如此,因为其中很多功能已经不能使用。

$auth=Yii::app()->authManager;//$auth->createOperation;//$auth->createTask;$auth->createRole;auth->assign;if->user->checkAccess{echo "yes";else{echo "no";}

**** 设置”register_globals”为”off”

这种情况下三者是一样的

这个选项会禁止PHP为用户输入创建全局变量,也就是说,如果用户提交表单变量”hello”,PHP不会创建”$
hello”,而只会创建”HTTP_GET/POST_VARS[‘hello’]”。这是PHP中一个极其重要的选项,关闭这个选项,会给编程带来很大的不便。

如何获得上一页的url以返回复制代码
代码如下:Yii::app()->request->urlReferrer;accessControl
是Ccontroller中内置的过滤方法,其它的还有ajaxOnly
postOnlyCMaskedTextField此组件用于限制用户的输入,对应的jquery插件

*** 设置”safe_mode”为”on”

在一对多,多对多查询时,the eager loading
联合所有的表生成一条语句,如果主表有limit的查询选项,那么他将单独执行,然后再执行与关联表有关的语句,返回相关表的数据对象,这就是为什么在做大优惠时,以中间表为查询条件出错的原因,

打开这个选项,会增加如下限制:

with()返回 CActiveFinder对象,其方法together(),既使主表中有LIMIT/OFFSET
也是返回一条sql;

1. 限制哪个命令可以被执行2. 限制哪个函数可以被使用3.
基于脚本所有权和目标文件所有权的文件访问限制4. 禁止文件上载功能

多对多查询时,分页有时候页中显示的条数不正确,因为有重复的项,加上复制代码 代码如下:$criteria->group =
true即可模型的rules中,验证某个字段不能重复,array(‘name’,
‘unique’,’message’ => ‘有重复的名子’),

这对于ISP来说是一个”伟大”的选项,同时它也能极大地改进PHP的安全性。

CStatePersister是yii的核心组件,提供了基于文件的数据保存方式,可以不在同的请求中使用

** 设置”open_basedir”

COutputCache
即是一个组件,又是一个filter,前者的时候用于在view中缓存内容,后者的时候用于在controller中缓存

这个选项可以禁止指定目录之外的文件操作,有效地消除了本地文件或者是远程文件被include()的攻击,但是仍需要注意文件上载和session文件的攻击。

就是说片段缓存,是把COutputCache当一个widget来用,页面缓存把COutputCache当作一个filter来用动态缓存,用CController的一个方法
renderDynamic;

** 设置”display_errors”为”off”,设置”log_errors”为”on”

COutputCache几个属性,duration,dependency

这个选项禁止把错误信息显示在网页中,而是记录到日志文件中,这可以有效的抵制攻击者对目标脚本中函数的探测。

另外还有几个,可以通称为Variation, 有什么作用呢?

* 设置”allow_url_fopen”为”off”

在beginCache是需要手工指定一个id,Variation的作有就是自动给生成这个id在布署模式的时候,有错误不会有stack样的提示,会显示一个errorxxx的错误

这个选项可以禁止远程文件功能。复制代码
代码如下://这里allow_url_fopen 注意下,在jnc blog上看到,可以用

如何在程序有错的时候跳到指定的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,'pagination'=>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灵活

Yii::app()->clientScript->registerMetaTag;Yii::app()->clientScript->registerMetaTag;

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,根据二级域名缓存

array('COutputCache + search','duration' => 120,'varyByParam' => array,'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,需要做以下几步

'widgetFactory'=>array,

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中

'request'=>array('enableCookieValidation'=>true,),

同时生成与得到cookie是要用 CHttpCookie

如何让表单验证不通过的提示为中文

在main.php的配置中加上复制代码
代码如下:’language’ => ‘zh_CN’,如何实现仿google的自动完成功能

widget('CAutoComplete', array('name'=>'xxx','url'=>array,'multiple'=>false,'htmlOptions'=>array;?>

然后在url指定的地址中的方法中如下输出,即可

echo “anbnc”//CGridView详解

这东西在后台比较有用,能加速开发的速度,值得一看

CGridView用表格的方式显示数据项

每一行代表一个数据项,一列通常代表数据项的一个属性CGridView支持排序和分页,可以用ajax或普通的方式CgridView必序和data
provider一起使用

$dataprovider = new CActiveDataProvider;$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,'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

2.3:如果复制代码
代码如下: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'), ),

array('class'=>'CButtonColumn','updateButtonUrl'=>'Yii::app()->createUrl("post/edit",array,

修改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;if$model->attributes=$_GET['Post'];$this->render('admin',array;}

4、在view中用CGridView显示

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模板来显示每一条数据

array;$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;if && $_POST['ajax']==='post'){echo CActiveForm::validate->end();}if){$post->attributes = $_POST['Post'];if{echo '存成功了';}}$this->render('form',array;}

beginWidget('CActiveForm',array('id'=>'post',//这里与Controller中的ajax对应'enableAjaxValidation'=>true,));?>labelEx;?>textField?>error; ?>

error一定要写上,要不不会触发ajax验证

labelEx;?>textField?>isNewRecord ? 'Create' : 'Save'); ?>endWidget(); ?>//CBreadcrumbs常用代码widget('zii.widgets.CBreadcrumbs', array('links'=>$this->breadcrumbs,'homeLink'=>'shouye','separator'=>'>>>')); ?>

其中breadcrumbs中Controller中的一个属性,如果要出现导航,就要在view中给此属性附值

shouye>>>Managde Posts>>>b>>>c

所以如果网站用到导航的时候,美工最好把导航代码定义如上

//CDetailView 用在仅仅是为了查看数据时,还是比较有用的,比如用在后台

如何在提交后显示一段提示

if){Yii::app()->user->setFlash('success','you are success');$this->refresh();}

if ->user->hasFlash{echo 're is'.Yii::app()->user->getFlash;}else{echo 'no';}

如何得到当前域名:复制代码
代码如下:app()->request->hostInfoactiveDropDownList,给出提示,并有值

array('empty'=>array

验证码如何生成及验证:

Controller中:

public function actions(){return array('captcha'=>array('class'=>'CCaptchaAction','backColor'=>0xFFFFFF,'maxLength'=>4,'minLength'=>4,),);}

widget('CCaptcha',array('captchaAction' => '/site/captcha','showRefreshButton' => false,'clickableImage' => true,'imageOptions' => array('align'=>'top', 'title'=>'重新获取'),));?>

array('verifyCode', 'captcha', 'captchaAction'=>'site/captcha', 'message' => '输入的验证码不正确'),set_time_limit;//禁止角本超时

如何想把手工的东西记录的数据库

main.php中配置log

array('class'=>'CDbLogRoute','levels'=>'info','logTableName'=>'Log','connectionID'=>'db',),

应用时复制代码
代码如下:Yii::log;deleteAllByAttributes(array直接接受一个数组,可以删除数组中符合条件的记录

YII_BLOG STUDY重新看了一遍yii blog,有些记录会与上边的重复

YII:Trace()
在debug模式是才记录信息,同时在main.php中的Log中的配置中的levels中要有trace,至于记录多少

栈由index.php中的YII_TRACE_LEVEL决定

'modules'=>array('gii'=>array('class'=>'system.gii.GiiModule','password'=>'123',),),

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/中的视图是可以继承的复制代码
代码如下:beginContent; ?>然后在中间出现$content即可复制代码 代码如下:endContent();
?>create,update最好是分开放在两个action中,共用一个form,中间可以加一层view,以在头尾显示不同的东西

成段的完成一个功能的代码尽量拿出来放到一个方法中

$this->beginWidget('CMarkdown', array);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;得到module bbs的路径

关于CUrlManager

复制代码
代码如下:’模式’=>’route’matchValue是指,对于一个url规则,正常情况下是只看参数的名子是否一样就应用规则

如果matchValue=true,则也要看值

'index-/'=>array("book/index",'matchValue'=>false),$this->createUrl('book/index', array;

如果规则中的matchValue=true,则就不能应用了

XSS又叫CSS ,跨站脚本攻击。

它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行

renderPartial

后者会把需要的js,css等嵌入

前者可以通过把最后一个参数设置成true完成一样的功能

addInCondition 不用考虑数组是空的情况yii会自动处理

如何得到当前url?复制代码
代码如下:Yii::app()->request->url;ctype_开始的几个函数,用于检查字任串是不是符合要求,代替了简单的正则表达式CController中的setPageState可以保存同一页中的POST的表单状态

如何通过BEhavior修改CActiveRecord?

class LLog extends CActiveRecordBehavior{public function beforeDelete{$model = get_class;//做要做的事,比如日志或修改模型字段内容}}

public function behaviors(){return array(// Classname => path to Class'LLog'=>'application.behavior.LLog',);}

如何在应用程序处理请求之前执行一段操作?

在main.php中配置复制代码
代码如下:’onBeginRequest’ => ‘function’当然这个function方法要存在

也可以写在放口文件index.php中,代码改成如下

$app = Yii::createWebApplication;$app->onbeginRequest = 'begin';$app->run{echo 'yyyyydddyyyyyy';}

为什么在CActiveRecordBehavior中用

beforesave就可以代表了事件onBeforeSave

注意基为中最上边的events方法中返回的对应关系复制代码
代码如下:’onBeforeSave’=>’beforeSave’在调用attacth的时候,复制代码
代码如下:$owner->attachEventHandler($event,array;就指定了事件onBeforeSave的处理函数是用本类中的beforeSaveYII中的CComponent,CEvent与Behavior及CActiveRecordBehavior个人理解

这一块教程少,今天个人理解了下,写了个小例子,有助于理解

完成如下功能,一个JTool类,继承CComponent,当其长度改变时,调用事件,输出”change
me”.

JTool.php在protected/components 下

_width ? $this->_width : 1; }public function setWidth{if($this->hasEventHandler{$this->onChange;}$this->_width = $width;}public function onChange{$this->raiseEvent;}}

OK,功能已经实现了,找个控制器,执行

$j = new JTool();$j->onChange = "showChange"; //给事件绑定handle showChange$j->width = 100; //调用setWidth,解发绑定的事件showChangefunction 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,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定义了事件和对应的事件处理方法

事件是是Compents定义的,即JTool中的onChange

处理方法同由Behavior类定义的,即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->publish(Yii::getPathOfAlias('application.components.homeuserlived'));cs()->registerCoreScript->registerScriptFile($url.'/location.js' ,CClientScript::POS_HEAD);cs()->registerScriptFile($url.'/YLChinaArea.js' ,CClientScript::POS_HEAD);cs()->registerCssFile;

如何写application component, 即在main.php可配置复制代码 代码如下:”my”=>array->my来访问?

继承CApplicationComponent即可,并可以自带Behavior等

yii中读写session的两种方法

$session = Yii::app()->session;$session['terry'] = 30;var_dump;Yii::app()->user->setState;var_dump->user->getState;

soap非yii教程,意思是不用yii框架的时候要对象提供webservice的写法

分两种WSDL模式,和非WSDL模式,先看后者

这个也比较简单,服务器端server.php:

".$name."";$xml .= "".$age."";return $xml;} }$soapS = new SoapServer(null,array('uri' => 'http://www.dayouhui.com'));$soapS->setClass;$soapS->handle();?>

客户端client.php:

"http://localhost/mysoap/index.php",'uri'=>'inadex.php'));echo $soap->getInfo;

yii,Componnts那快,忘了,写了个小例子回忆了下是写一个可以写在main.php中的Components并绑定行为,事件

class ExtWindow extends CApplicationComponent{private $title = 'title';public $oldtitle;public function getTitle(){return $this->title ? $this->title : 'old title
';}public function setTitle{echo '=='.$this->oldtitle.'==';$this->oldtitle = $this->title;$this->title = $title;if($this->hasEventHandler{$event =new CEvent;$this->raiseEvent('onTitleChange', $event);}}//必须有这么个方法,其和raiseEent中的事件一样,具体看代码public function onTitleChange{}}

'titleChange',));}public function titleChange{echo $event->sender->title;echo 'event TitleChange is handled in Behavior
';echo $this->owner->title;}public function titleOld(){echo '
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
loadingtogether的作用是 要不要形成一个语句

当是一个sql语句是记录会有重复,这时候分页分出现相同的记录,加上group=>true即可,

只要弄明白了,你生成的sql是一条还是多条sql就明白在多对多查询时的结果了

两个表不是用主键关联复制代码
代码如下:’user’ => array(self::BELONGS_TO, ‘OaskUser’,
”,’on’=>’name=userName’,
‘select’=>’TrueName’),表带talbeprefix是,多对关联,键的写法复制代码
代码如下:’categories’=>array(self::MANY_MANY,’Category’,'{{post_category}}’),

希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图