I am a Yii beginner and am running into a bit of a wall and hope someone will be able to help me get back onto track. I think this might be a fairly straight forward question to the seasoned Yii user. So here goes...
In the controller, let's say I run the following call to the model-
$variable = Post::model()->findAll();
All works fine and I pass the variable into the view. Here's where I get pretty stuck. The array that is returned in the above query is far more complex than I anticipated and I'm struggling to make sense of it. Here's a sample-
print_r($variable);
gives-
Array ( [0] => Post Object ( [_md:CActiveRecord:private] => CActiveRecordMetaData Object ( [tableSchema] => CMysqlTableSchema Object ( [schemaName] => [name] => tbl_post [rawName] => `tbl_post` [primaryKey] => id [sequenceName] => [foreignKeys] => Array ( ) [columns] => Array ( [id] => CMysqlColumnSchema Object ( [name] => id [rawName] => `id` [allowNull] => [dbType] => int(11) [type] => integer [defaultValue] => [size] => 11 [precision] => 11 [scale] => [isPrimaryKey] => 1 [isForeignKey] => [autoIncrement] => 1 [_e:CComponent:private] => [_m:CComponent:private] => ) [post] => CMysqlColumnSchema Object ( [name] => post [rawName] => `post` [allowNull] => [dbType] => text [type] => string [defaultValue] => [size] => [precision] => [scale] => [isPrimaryKey] => [isForeignKey] => [autoIncrement] => [_e:CComponent:private] => [_m:CComponent:private] => ) ) [_e:CComponent:private] => [_m:CComponent:private] => ) [columns] => Array ( [id] => CMysqlColumnSchema Object ( [name] => id [rawName] => `id` [allowNull] => [dbType] => int(11) [type] => integer [defaultValue] => [size] => 11 [precision] => 11 [scale] => [isPrimaryKey] => 1 [isForeignKey] => [autoIncrement] => 1 [_e:CComponent:private] => [_m:CComponent:private] => ) [post] => CMysqlColumnSchema Object ( [name] => post [rawName] => `post` [allowNull] => [dbType] => text [type] => string [defaultValue] => [size] => [precision] => [scale] => [isPrimaryKey] => [isForeignKey] => [autoIncrement] => [_e:CComponent:private] => [_m:CComponent:private] => ) ) [relations] => Array ( [responses] => CHasManyRelation Object ( [limit] => -1 [offset] => -1 [index] => [through] => [joinType] => LEFT OUTER JOIN [on] => [alias] => [with] => Array ( ) [together] => [scopes] => [name] => responses [className] => Response [foreignKey] => post_id [select] => * [condition] => [params] => Array ( ) [group] => [join] => [having] => [order] => [_e:CComponent:private] => [_m:CComponent:private] => ) ) [attributeDefaults] => Array ( ) [_model:CActiveRecordMetaData:private] => Post Object ( [_md:CActiveRecord:private] => CActiveRecordMetaData Object *RECURSION* [_new:CActiveRecord:private] => [_attributes:CActiveRecord:private] => Array ( ) [_related:CActiveRecord:private] => Array ( ) [_c:CActiveRecord:private] => [_pk:CActiveRecord:private] => [_alias:CActiveRecord:private] => t [_errors:CModel:private] => Array ( ) [_validators:CModel:private] => [_scenario:CModel:private] => [_e:CComponent:private] => [_m:CComponent:private] => ) ) [_new:CActiveRecord:private] => [_attributes:CActiveRecord:private] => Array ( [id] => 1 [post] => User Post ) [_related:CActiveRecord:private] => Array ( ) [_c:CActiveRecord:private] => [_pk:CActiveRecord:private] => 1 [_alias:CActiveRecord:private] => t [_errors:CModel:private] => Array ( ) [_validators:CModel:private] => [_scenario:CModel:private] => update [_e:CComponent:private] => [_m:CComponent:private] => ) )
[sorry if there's an easier way to show this array, I'm not aware of it]
Can anyone explain to me why the model returns such a complex array? It doesn't seem to matter what tables or columns or relations are used in your application, they all seem to me to return this format.
Also, can someone explain the structure to me so that I can isolate the variables that I want to recover?
Many thanks in advance,
Nick
To get a better print_r
output in yii, you can use the CVarDumper class' dump()
or dumpAsString()
methods. They also provide a parameter $highlight
which will help you make sense of the output, by properly formatting the output, and adding indentation to it. Example:
CVarDumper::dump($variables,10,true);
// 10 is the default depth, and passing true will enable highlighting
As already mentioned in the other answers findAll()
returns an array of CActiveRecord objects, so $variables
is an array of objects, and $variables[0]
is the first Post object. Yii's CActiveRecord has a host of properties which are objects, for instance a CActiveRecordMetaData object, which in turn has a CDbTableSchema object (and you have it's subclass the CMysqlTableSchema, which means you are using mysql). The print_r
is simply printing out these objects, which are nothing but properties of the main CActiveRecord object. In addition to these objects the attributes
property(which is an array) of a CActiveRecord holds your actual attribute values, so somewhere in the output you'll also see an array like this:
[CActiveRecord:_attributes] => array
(
'attributeName' => 'attributeValue'
'anotherAttributeName' => 'anotherAttributeValue'
'someAttributeName' => 'someAttributeValue'
...
)
Those are your attribute values.
To access a model's properties we can use both object property access, and associative array access(Probably because CActiveRecord's parent class CModel implements php's ArrayAccess interface). Example:
$variables[0]->attributeName;
$variables[0]['attributeName'];
And since yii uses and overrides the __get php magic method we can do:
$variables[0]->attributeName;
// instead of
$variables[0]->attributes['attributeName'];
And of course you can iterate over the array of Post objects using foreach()
as already shown in another answer here:
foreach($variables as $aPost){
echo $aPost->attributeName;
echo $aPost['attributeName'];
echo $aPost->attributes['attributeName'];
}
To access relations, just use the relation name:
$variables[0]->relationName->attributeOfRelatedTable;
$variables[0]['relationName']->attributeOfRelatedTable;
$variables[0]['relationName']['attributeOfRelatedTable'];
If your relation is HAS_MANY, then of course the related models will also be returned as an array:
$variables[0]->relationName[0]->attributeOfRelatedTable;
$variables[0]['relationName'][0]->attributeOfRelatedTable;
$variables[0]['relationName'][0]['attributeOfRelatedTable'];
$variables[0]->relationName[0]['attributeOfRelatedTable'];
And again you can iterate over the relations array incase of HAS_MANY relations.
Edit: example for has_many iteration:
foreach($variables as $aPost) { // get each post one by one
echo $aPost->someAttribute; // or $aPost['someAttribute']
foreach($aPost->relationName as $aComment) { // say we get each comment of each post
// or could have done $aPost['relationName'] as $aComment
echo $aComment->commentAttribute; // or $aComment['commentAttribute']
}
}
findall returns an array of active records for your model see here
Once you have that you can access all the columns in each record returned like so
$results = Post::model()->findAll();
foreach($results AS $model)
{
echo $model->somecolumnname;
echo $model->someothercolumnname;
}
So you don't have to concern yourself too much with all that detail under the hood as you can just use the abstraction directly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With