1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/**
* 重写findALL方法
* @params $condition 查询条件,$params 参数,$return_array 是否返回数组
*
* return 根据条件返回结果类型
*/
public
function
findAll(
$condition
=
''
,
$params
=
array
(),
$return_array
=false)
{
$result
= CActiveRecord::findAll(
$condition
,
$params
);
if
(
$return_array
)
{
$result
=
array_map
(create_function(
'$record'
,
'return $record->attributes;'
),
$this
->findAll(
$condition
,
$params
));
}
return
$result
;
}
|
6..
YII框架中可以使用foreach遍历对象以及可以使用数组形式直接访问对象的原因
在YII框架的使用过程中,我们可以使用foreach直接遍历findAll等方法返回的对象的属性
为什么呢?其实这与CModel实现的接口相关,接下来我们看下其实现的整个过程
对于一个我们定义的model,它会继承虚类CActiveRecord,CActiveRecord类继承于CModel,如下所示:
1 2 3 4
class special extends CActiveRecord { } abstract class CActiveRecord extends CModel{ }
最关键的地方是CModel类实现了IteratorAggregate接口。
而在CModel类中实现的getIterator方法返回的是这个model的所有属性,使用的迭代器是Yii框架实现的CMapIterator,而CMapIterator实现了Iterator接口
1 2 3 4 5 6 7 8 9 10
public function getIterator() { $attributes=$this->getAttributes(); return new CMapIterator($attributes); }
这些就使得我们可以使用foreach直接遍历findAll等方法返回的对象
关于此迭代器可以参看之前写的关于迭代器的文章:
PHP源码阅读笔记二十四 :iterator实现中当值为flase时无法完成迭代的原因分析
关于IteratorAggregate接口请移步
http://cn.php.net/manual/en/class.iteratoraggregate.php
关于Iterator接口请移步
http://cn.php.net/manual/en/class.iterator.php
同样的道理,
因为CModel实现了ArrayAccess接口,所以可以直接访问以数组的方式访问
关于ArrayAccess接口请移步
http://cn.php.net/manual/en/class.arrayaccess.php
在YII框架的使用过程中,我们可以使用foreach直接遍历findAll等方法返回的对象的属性
为什么呢?其实这与CModel实现的接口相关,接下来我们看下其实现的整个过程
对于一个我们定义的model,它会继承虚类CActiveRecord,CActiveRecord类继承于CModel,如下所示:
1 2 3 4
class special extends CActiveRecord { } abstract class CActiveRecord extends CModel{ }
最关键的地方是CModel类实现了IteratorAggregate接口。
而在CModel类中实现的getIterator方法返回的是这个model的所有属性,使用的迭代器是Yii框架实现的CMapIterator,而CMapIterator实现了Iterator接口
1 2 3 4 5 6 7 8 9 10
public function getIterator() { $attributes=$this->getAttributes(); return new CMapIterator($attributes); }
这些就使得我们可以使用foreach直接遍历findAll等方法返回的对象
关于此迭代器可以参看之前写的关于迭代器的文章:
PHP源码阅读笔记二十四 :iterator实现中当值为flase时无法完成迭代的原因分析
关于IteratorAggregate接口请移步
http://cn.php.net/manual/en/class.iteratoraggregate.php
关于Iterator接口请移步
http://cn.php.net/manual/en/class.iterator.php
同样的道理,
因为CModel实现了ArrayAccess接口,所以可以直接访问以数组的方式访问
关于ArrayAccess接口请移步
http://cn.php.net/manual/en/class.arrayaccess.php
7..
关于Yii框架中不能直接给模型的attributes赋值的解决办法
May 10th, 2013 by wangLeave a reply »先看一下源代码:
01 | $menuId = isset( $_GET [ 'mId' ]) ? $_GET [ 'mId' ] : 0; |
02 | if ( $menuId ) { |
03 | $menu = MenuTree::model()->findByPk( $menuId ); |
04 | if (isset( $_POST [ 'MenuTree' ])){ |
05 | var_dump( $menu ->attributes); //在这里跟踪输出的数据正常,跟表单中填写的一致 |
06 | $menu ->attributes = $_POST [ 'MenuTree' ]; //对attributes进行赋值 |
07 | var_dump( $menu ->attributes); //输出$menu模型中的attributes,不正常,结果并不是POST接收到的值,而是数据库原有的值 |
08 | if ( $menu ->save()){ |
09 | Yii::app()->user->setFlash( 'success' , "恭喜您,修改成功,请继续!" ); |
10 | $this ->redirect(Yii::app()->createUrl( 'menu/contentEdit' , array ( 'mId' => $menuId ))); |
11 | } else { |
12 | throw new CException( "修改失败!" ); |
13 | } |
14 | } |
15 | $this ->render( "contentEdit" , array ( 'menu' => $menu )); |
16 | } else { |
17 | throw new CHttpException( '404' ); |
18 | } |
1 | 这是一个页面的action代码,看代码中的注释可以看到出现的错误,死活不接受POST的赋值,试过使用setAttributes函数也一样不接受,输出的还是原数据库的值,但是用updateByPk操作就可以,跟踪了一下setAttributes函数,发现函数定义如下: |
01 | <pre> public function setAttributes( $values , $safeOnly =true) |
02 | { |
03 | if (! is_array ( $values )) |
04 | return ; |
05 | $attributes = array_flip ( $safeOnly ? $this ->getSafeAttributeNames() : $this ->attributeNames()); |
06 | foreach ( $values as $name => $value ) |
07 | { |
08 | if (isset( $attributes [ $name ])) |
09 | $this -> $name = $value ; |
10 | else if ( $safeOnly ) |
11 | $this ->onUnsafeAttribute( $name , $value ); |
12 | } |
13 | }</pre> |
14 | <pre></pre> |
15 | <pre>分析setAttributes函数代码可以看到,在对attributes赋值时进行的安全检查,所以想到原因可能出现模型的rules没有对那几个表单中修改的字段设置为安全,找到原因,解决方案就出来了,在model的rules中,把想要修改的字段的属性置为安全即可。</pre> |
16 | <pre></pre> |
17 | <pre><pre class = "brush:php" > public function rules() |
18 | { |
19 | // NOTE: you should only define rules for those attributes that |
20 | // will receive user inputs. |
21 | return array ( |
22 | // more code... |
23 | array ( 'field1 , field2 ,field3' , 'safe' ), //Modify the fields in here |
24 | // more code... |
25 | ); |
26 | }</pre> |
27 | </pre> |
http://www.wangyinneng.com/%E5%85%B3%E4%BA%8Eyii%E6%A1%86%E6%9E%B6%E4%B8%AD%E4%B8%8D%E8%83%BD%E7%9B%B4%E6%8E%A5%E7%BB%99%E6%A8%A1%E5%9E%8B%E7%9A%84attributes%E8%B5%8B%E5%80%BC%E7%9A%84%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95/