Array structure returned by Yii's model - php

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

Better print_r
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
Why and what structure?
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.
How to access?
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.

A simple answer to this is to use,
print_r($variable->attributes);
where $variable is an object of Model Class.

Related

Multidimensional Array showing data

categories Object
(
[_db:categories:private] => db Object
(
[_pdo] => PDO Object
(
)
[_query] => PDOStatement Object
(
[queryString] => SELECT * FROM categories WHERE name_of_category = ?
)
[_error] =>
[_results] => Array
(
[0] => stdClass Object
(
[id] => 10
[name_of_category] => Vedran
[description_of_category] => adsdasdas
[meta_keywords] => sadasdas
[meta_description] => asdasdas
[notes] => sadsadas
[created] => 2016-01-20 08:26:02
)
[1] => stdClass Object
(
[id] => 9
[name_of_category] => VEdran
[description_of_category] => ddddd
[meta_keywords] => qsqddd
[meta_description] => sqdddd
[notes] => sddd
[created] => 2020-01-16 00:00:00
)
)
[_count] => 2
)
[_fields:categories:private] =>
)
Hello. Can someone help me please with this array. I have created in database categories table. I would like to show categories on page where user would be able to manage categories (delete, edit). When i want to show categories from database i get this array in PHP. Now i dont know how to show for example only "name_of_category" on web page. Can someone please help me.
$categories=$ObjVariable->_results;
then use the $categories array to display the values

How to get value out of this...?

Can someone explain me how to get data out of this...like if I just want subject, description..etc...
stdClass Object
(
[tickets] => Array
(
[0] => stdClass Object
(
[url] => https://codemymobilecom.zendesk.com/api/v2/tickets/1.json
[id] => 1
[external_id] =>
[via] => stdClass Object
(
[channel] => sample_ticket
[source] => stdClass Object
(
[from] => stdClass Object
(
)
[to] => stdClass Object
(
)
[rel] =>
)
)
[created_at] => 2015-04-22T08:30:29Z
[updated_at] => 2015-05-19T06:01:22Z
[type] => incident
[subject] => This is a sample ticket requested and submitted by you
[raw_subject] => This is a sample ticket requested and submitted by you
[description] => This is the first comment. Feel free to delete this sample ticket.
[priority] => high
[status] => closed
[recipient] =>
[requester_id] => 794599791
[submitter_id] => 794599791
[assignee_id] => 794599791
[organization_id] => 39742491
[group_id] => 24344491
[collaborator_ids] => Array
(
)
[forum_topic_id] =>
[problem_id] =>
[has_incidents] =>
[due_at] =>
[tags] => Array
(
[0] => sample
[1] => zendesk
)
[custom_fields] => Array
(
)
[satisfaction_rating] =>
[sharing_agreement_ids] => Array
(
)
[fields] => Array
(
)
[followup_ids] => Array
(
)
[brand_id] => 565681
)
[1] => stdClass Object
(
[url] => https://codemymobilecom.zendesk.com/api/v2/tickets/10.json
[id] => 10 //multiple object like [0]...
Thanks...Any help would be great..
When you need to access to array's key, use []. When you have object, use ->.
echo $obj->tickets[0]->subject; // returns first subject
echo $obj->tickets[0]->description; // returns first description
You can put it into foreach loop, of course to gain all subjects, etc.
It's STD object so use properties
$obj->tickets[0]->subject
$obj->tickets[0]->description
You can obviously loop tickets
foreach($obj->tickets as $ticket)
{
echo $ticket->subject;
echo $ticket->description
}
this is an std object.to get subject and description follow this
$obj->tickets[0]->subject;
$obj->tickets[0]->description;
if you feel better in array just make it array using this code
$array = get_object_vars($obj);

CakePHP extended model not inheriting attributes

I apologize if this ends up being a newbish PHP misunderstanding, but anyway, I have the following Vip.php file:
<?php
class Vip extends AppModel {
public $useTable = 'vips';
public $hasOne = 'VipCredential';
public $belongsTo = array('User', 'MasterExhibitor');
public $validate = array();
}
class InviteVipForm extends Vip {
}
class AccreditVipForm extends Vip {
}
So, both InviteVipForm and AccreditVipForm classes should inherit every model attributes from their parent, right? This doesn't happen. I loaded InviteVipForm in the controller and printed. Everything is empty or set to default (useTable, for example, is set to invite_vip_forms, which is of course a table which doesn't exist).
AppModel Object ( [useDbConfig] => default [useTable] => invite_vip_forms [id] => [data] => Array ( ) [schemaName] => [table] => invite_vip_forms [primaryKey] => id [_schema:protected] => [validate] => Array ( ) [validationErrors] => Array ( ) [validationDomain] => [plugin] => [name] => InviteVipForm [alias] => InviteVipForm [tableToModel] => Array ( [invite_vip_forms] => InviteVipForm ) [cacheQueries] => [belongsTo] => Array ( ) [hasOne] => Array ( ) [hasMany] => Array ( ) [hasAndBelongsToMany] => Array ( ) [actsAs] => [Behaviors] => BehaviorCollection Object ( [modelName] => InviteVipForm [_methods:protected] => Array ( ) [_mappedMethods:protected] => Array ( ) [_enabled:protected] => Array ( ) [_loaded:protected] => Array ( ) [defaultPriority] => 10 ) [whitelist] => Array ( ) [cacheSources] => 1 [findQueryType] => [recursive] => 1 [order] => [virtualFields] => Array ( ) [_associationKeys:protected] => Array ( [belongsTo] => Array ( [0] => className [1] => foreignKey [2] => conditions [3] => fields [4] => order [5] => counterCache ) [hasOne] => Array ( [0] => className [1] => foreignKey [2] => conditions [3] => fields [4] => order [5] => dependent ) [hasMany] => Array ( [0] => className [1] => foreignKey [2] => conditions [3] => fields [4] => order [5] => limit [6] => offset [7] => dependent [8] => exclusive [9] => finderQuery [10] => counterQuery ) [hasAndBelongsToMany] => Array ( [0] => className [1] => joinTable [2] => with [3] => foreignKey [4] => associationForeignKey [5] => conditions [6] => fields [7] => order [8] => limit [9] => offset [10] => unique [11] => finderQuery ) ) [_associations:protected] => Array ( [0] => belongsTo [1] => hasOne [2] => hasMany [3] => hasAndBelongsToMany ) [__backAssociation] => Array ( ) [__backInnerAssociation] => Array ( ) [__backOriginalAssociation] => Array ( ) [__backContainableAssociation] => Array ( ) [__safeUpdateMode] => [_insertID:protected] => [_sourceConfigured:protected] => [findMethods] => Array ( [all] => 1 [first] => 1 [count] => 1 [neighbors] => 1 [list] => 1 [threaded] => 1 ) [_eventManager:protected] => [_validator:protected] => )
Could anybody tell me why this is happening? The classes don't need to be in separate files, do they?
That's not how things work, each model has to be placed in a separate file, otherwise CakePHP might not be able to find/load them, and then you'll end up with an instance of the AppModel class being used, which is what you are experincing.
The AppModel instance of course won't have any of the properties or methods that you've defined on your extending class.
This behavior is also mentioned in the Cookbook, see http://book.cakephp.org/2.0/en/models.html
CakePHP will dynamically create a model object for you if it cannot find a corresponding file in /app/Model. This also means that if your model file isn’t named correctly (for instance, if it is named ingredient.php or Ingredients.php rather than Ingredient.php), CakePHP will use an instance of AppModel rather than your model file (which CakePHP assumes is missing). If you’re trying to use a method you’ve defined in your model, or a behavior attached to your model, and you’re getting SQL errors that are the name of the method you’re calling, it’s a sure sign that CakePHP can’t find your model and you need to check the file names, your application cache, or both.

How do I retrieve an item from an PHP Object Array?

I want to retrieve quantities from this array.
invoice Object
(
[data:private] => Array
(
[i_status] => pend
[i_title] => 500 HLCoins , 500 HLCoins x8
[i_member] => 1
[i_items] => Array
(
[0] => Array
(
[act] => new
[app] => nexus
[type] => product
[cost] => 0
[tax] => 0
[renew_term] => 0
[renew_units] =>
[renew_cost] => 0
[quantity] => 1
[physical] =>
[shipping] => Array
(
)
[weight] => 0
[itemName] => 500 HLCoins
[itemID] => 3
[cfields] => Array
(
)
[extra] =>
[opt_id] => 0
[associated] =>
[assocBought] =>
[groupRenewals] => 0
[methods] => Array
(
)
[k] => 0
[_tax] => 0
)
[1] => Array
(
[act] => new
[app] => nexus
[type] => product
[cost] => 0
[tax] => 0
[renew_term] => 0
[renew_units] =>
[renew_cost] => 0
[quantity] => 8
[physical] =>
[shipping] => Array
(
)
[weight] => 0
[itemName] => 500 HLCoins
[itemID] => 3
[cfields] => Array
(
)
[opt_id] => 0
[groupRenewals] => 0
[methods] => Array
(
)
[_tax] => 0
)
)
[i_total] => 0
[i_date] => 1347217384
[i_return_uri] =>
[i_paid] => 0
[i_status_extra] => a:1:{s:4:"type";s:4:"zero";}
[i_discount] => 0
[i_temp] =>
[i_ordersteps] => 0
[i_noreminder] => 1
[i_renewal_ids] => Array
(
)
[i_po] =>
[i_notes] =>
[i_shipaddress] =>
[i_id] => 229
)
[takeAction] => 1
)
I've tried a bunch of codes like $invoice->quantity, $invoice[1]->quantity, $this->$invoice->quantity, but none of them seem to display.
It still does not display at all, I tried to print_r and that is the array it gave me.
All the variables are private which means you cannot access them from outside the object. Check out the class definition for the invoice class. There should be some function to get the quantities from the object, or else you could add such a feature to the class.
The whole point of this is separation of concerns. The class may change in the future and possibly not use the same structure, therefore you should use object functions to access the properties, do not access them directly as variables.
You can read more on this subject in the manual or in a book about object-oriented programming.
Seems like all the data is in a private property. You cannot access it from outside directly.
Read the documentation for the class. It should have some method you can call, like getQuantity(), that'll get you the data. It depends on how the class was written and how it is supposed to be used.

php access object values

EDIT: Thanks everyone. I didn't even notice it was private lol, so I changed them from private to public, now it should be accessible... question now is how can I access the value of say 'backpackPosition'? thanks again!
TF2Inventory Object
(
[fetchDate] => 123456123
[items] => Array
(
[60] => TF2Item Object
(
[equipped] => Array
(
[scout] => 1
[sniper] => 1
[soldier] => 1
[demoman] => 1
[medic] => 1
[heavy] => 1
[pyro] => 1
[spy] => 1
)
[attributes] => Array
(
[0] => stdClass Object
(
[name] => custom employee number
[class] => set_employee_number
[value] => 0
)
[1] => stdClass Object
(
[name] => cannot trade
[class] => cannot_trade
[value] => 1
)
)
[backpackPosition] => 61
[className] => tf_wearable
[count] => 1
[defindex] => 170
[id] => 535518002
[level] => 20
[name] => Primeval Warrior
[quality] => unique
[slot] => misc
[tradeable] =>
[type] => Badge
)
[43] => TF2Item Object
(
[equipped] => Array
(
[scout] => 0
[sniper] => 0
[soldier] => 0
[demoman] => 0
[medic] => 0
[heavy] => 0
[pyro] => 0
[spy] => 0
)
[attributes] => Array
(
[0] => stdClass Object
(
[name] => cannot trade
[class] => cannot_trade
[value] => 1
)
)
[backpackPosition] => 44
[className] => tf_wearable
[count] => 1
[defindex] => 471
[id] => 535518003
[level] => 50
[name] => Proof of Purchase
[quality] => unique
[slot] => head
[tradeable] =>
[type] => Hat
)
[42] => TF2Item Object
(
[equipped] => Array
(
[scout] => 1
[sniper] => 1
[soldier] => 1
[demoman] => 1
[medic] => 1
[heavy] => 1
[pyro] => 1
[spy] => 1
)
[attributes] =>
[backpackPosition] => 43
[className] => tf_wearable
[count] => 1
[defindex] => 278
[id] => 541628464
[level] => 31
[name] => Horseless Headless Horsemann's Head
[quality] => unique
[slot] => head
[tradeable] =>
[type] => Hat
)
[59] => TF2Item Object
(
[equipped] => Array
(
[scout] => 0
[sniper] => 0
[soldier] => 0
[demoman] => 0
[medic] => 0
[heavy] => 0
[pyro] => 0
[spy] => 0
)
[attributes] => Array
(
[0] => stdClass Object
(
[name] => cannot trade
[class] => cannot_trade
[value] => 1
)
)
[backpackPosition] => 60
[className] => tf_wearable
[count] => 1
[defindex] => 115
[id] => 548155039
[level] => 10
[name] => Mildly Disturbing Halloween Mask
[quality] => unique
[slot] => head
[tradeable] =>
[type] => Holiday Hat
)
Private members are just that - private. Only the class they belong to can access them. If you want to be able to retrieve their values, you need to either make them protected (and thus available to parent and children classes) or public (available to all classes). Another option is to write some getters, functions that look like
public function get_slot() {
return $this->slot;
}
or use the __get() magic function to make a general getter that looks like
public function __get($name) {
return $this->$name;
}
More info can be found in the documentation at http://php.net/manual/en/language.oop5.visibility.php
Those items are only accessible by the object itself. You will have to modify the code for that class and provide an accessor method, or change their scope.
http://www.php.net/manual/en/language.oop5.properties.php
You will need accessor method on each object in order to access the values. Since they are private they can only be accessed within each of the classes they belong.
The private properties just can be accessed from inside the object itself. To access try to use $this->propertyName
This answer is for the scenario of trying to get around an imposed private data restriction, for instance if you are by chance working with a library which you don't have access to change the privilege level of the class member, then there is a work around. Presuming the object is serializable/unserializable then consider:
<?php
class SourceProtected {
private $foo = 'one';
protected $baz = 'two';
public $bar = 'three';
}
class SourceUnprotected {
public $foo = 'blah';
public $baz = 'two';
public $bar = 'three';
}
$protected = new SourceProtected();
$unprotected = new SourceUnprotected();
var_dump(serialize($protected), serialize($unprotected));
The output looks something like:
string(110) "O:15:"SourceProtected":3:{s:20:"?SourceProtected?foo";s:3:"one";s:6:"?*?baz";s:3:"two";s:3:"bar";s:5:"three";}"
string(92) "O:17:"SourceUnprotected":3:{s:3:"foo";s:4:"blah";s:3:"baz";s:3:"two";s:3:"bar";s:5:"three";}"
So one solution, is to create a duplicate class that changes the privilege level on the variables to all public. Then serialize the working object, convert*** the serialized class to your versions, then simply unserialize the string and you'll have a working object of your class type with unlimited access.
Obviously the convert method is where you'll have to do some foot work. You'll need to either build a generalized parser which can handle any case or you can code a hacky works just for your specific use case series of str_replaces.
you should see first object oriented php http://www.google.sk/url?sa=t&rct=j&q=object%20oriented%20php&source=web&cd=6&ved=0CGQQFjAF&url=http%3A%2F%2Ftalks.somabo.de%2F200703_montreal_oop.pdf&ei=k3EUT8HnGYHHswbi09A6&usg=AFQjCNEjsA2JgbGQfxnQ26XxTtFuHmvGIA&sig2=Vw4d7aD2GhulZYAM892EKA

Categories