PHP analyzing, handling and converting some object to a stdClass - php

In our backoffice we have a core-system that generates models from the DB. When returning one object we make an instance of stdClass. All the columns from the query-result are set as proprties and when finished processing the query-result the stdClass-object is converted into a (we call it) Decorator-class. Basically the Decorator-class has one proprty $_oObject where the stdClass is stored into. We do this gain control over dynamically created objects. This works all fine.
However, I'm working on a webserver using SOAP. The webservice returns the whole Decorator-object (could possibly have sub-objects, also being Decorator objects, and sub-sub object.. and so on). This structure works perfectly fine with our internal system because we have control over the Decorator-object but for the outside world I want to revert the Decorator-object-structure into a stdClass instance with sub-classes also being stdClasses. Basically I want to remove all the 'nodes' in the print_r-result containing Decorator.
Any ideas how to achieve what I want (see results below). PHP's get_object_vars doesn't return anything and actually I'm stuck..
My sample data:
Decorator Object
(
[oClass:Decorator:private] => stdClass Object
(
[Id] => 1
[FAQCategoryId] => 1
[TitleId] => 1
[ContentId] => 2
[Views] => 226
[DateCreated] => 2011-10-31 11:17:44
[DateModified] =>
[Title] => My title..
[Content] => My content..
[AttachmentSet] => Array
(
[0] => Decorator Object
(
[oClass:Decorator:private] => stdClass Object
(
[Id] => 1
[LanguageId] => 1
[FAQItemId] => 1
[Attachment] => file1.pdf
)
)
[1] => Decorator Object
(
[oClass:Decorator:private] => stdClass Object
(
[Id] => 2
[LanguageId] => 1
[FAQItemId] => 1
[Attachment] => file2.pdf
)
)
)
)
)
I want to convert it into:
stdClass Object
(
[Id] => 1
[FAQCategoryId] => 1
[TitleId] => 1
[ContentId] => 2
[Views] => 226
[DateCreated] => 2011-10-31 11:17:44
[DateModified] =>
[Title] => My title..
[Content] => My content..
[AttachmentSet] => Array
(
[0] => stdClass Object
(
[Id] => 1
[LanguageId] => 1
[FAQItemId] => 1
[Attachment] => file1.pdf
)
[1] => stdClass Object
(
[Id] => 2
[LanguageId] => 1
[FAQItemId] => 1
[Attachment] => file2.pdf
)
)
)

I've figured it out. In my case I've created a function that returns the stdObject of a Decoarator object. In my Controller_Core-class I've made function that recursively handles a given object and returns the whole structure as one stdClass.
My code, if it is helpful to someone:
/**
* Controller_Core::RevertToStdClass
*
* #params: Decorator $oObject
* #return: stdClass $oObject
**/
public function RevertToStdClass(Decorator $oObject)
{
if(is_a($oObject, "Decorator"))
{
$oObject = $oObject->ReturnStdObject();
}
$aProperties = get_object_vars($oObject);
foreach($aProperties as $sProperty => $mValue)
{
if(is_array($mValue))
{
foreach($mValue as $mIndex => $mSubValue)
{
if(is_a($mSubValue, "Decorator"))
{
$oObject->{$sProperty}[$mIndex] = $this->RevertToStdClass($mSubValue);
}
}
}
else
{
if(is_a($mValue, "Decorator"))
{
$oObject->{$sProperty} = $this->RevertToStdClass($oObject->{$sProperty});
}
}
}
return $oObject;
}

Related

How can I merge two or more php objects?

I have 2 or more php objects that have the same sections. Each section has objects in it. I want to combine these objects together. Since each section has the same title I remove the title of the new object before merging them. My code isn't keeping the proper structure and is adding an unwanted level 'component' to the primary object. Feels like I am missing something obvious but I Can't figure out how to add the new object without the 'component' level.
Object 1 Example
stdClass Object(
[section_1] => stdClass Object
(
[title] => Production
[component_name_68] => stdClass Object
(
[title] => custom component title
[id] => 68
[type] => component_name_68
[subtotal] => 1127.50
[desc] => custom description
)
)
)
Object 2 Example
stdClass Object(
[section_2] => stdClass Object
(
[title] => Production
[component_name_69] => stdClass Object
(
[title] => custom component title2
[id] => 69
[type] => component_name_69
[subtotal] => 1985.50
[desc] => custom description2
)
)
)
Current Code
foreach($this->Details as $section1){
foreach($newinfo as $section2){
if($section1->title == $section2->title){
unset($section2->title);
$section1->{"component"} = $section2;
}
}
}
Current Result
stdClass Object(
[section_1] => stdClass Object
(
[title] => Production
[component_name_68] => stdClass Object
(
[title] => custom component title
[id] => 68
[type] => component_name_68
[subtotal] => 1127.50
[desc] => custom description
)
[component] => stdClass Object (
[component_name_69] => stdClass Object
(
[title] => custom component title2
[id] => 69
[type] => component_name_69
[subtotal] => 1985.50
[desc] => custom description2
)
)
)
Desired Result
stdClass Object(
[section_1] => stdClass Object
(
[title] => Production
[component_name_68] => stdClass Object
(
[title] => custom component title
[id] => 68
[type] => component_name_68
[subtotal] => 1127.50
[desc] => custom description
)
[component_name_69] => stdClass Object
(
[title] => custom component title2
[id] => 69
[type] => component_name_69
[subtotal] => 1985.50
[desc] => custom description2
)
)
)
Might something like this work?
foreach($this->Details as $section1){
foreach($newinfo as $section2){
if($section1->title == $section2->title){
unset($section2->title);
$components = get_object_vars($section2);
// Check to see that only one key is present. Skip if more than one.
if (count($components) > 1) {
continue;
}
$component_keys = array_keys($components);
$component_key = reset($component_keys);
$section1->{$component_key} = $section2->{$component_key};
}
}
}
Basically it seems the issue is determining the key name for the subordinate component. You would have to add your own error checking. For example, I assume the second component will only have the one object, but that may not be true. Perhaps you need to ensure the key begins with the string "component_name", perhaps that is just a placeholder. You would just need to adapt this to your data structure.
Combining Objects sometime is hectic job because we want to keep the object definintion after merging them into single object(parent)
Check this link for more information.

How to read a parameter from an array in PHP?

please help me for read a parameter from array in php:
when use from print_r for view array , result is:
getUserServicesResponse Object (
[getUserServiceResponse] =>
[return] => stdClass Object (
[isactive] => 1
[lastQnum] => 0
[qnum] => 5
[score] => 0
[service] => stdClass Object (
[countActive] => 73657
[countAll] => 199784
[lastTime] => 2015-12-01T08:38:06.065+03:30
[maxScore] => 33000
[minScore] => 0
[minregdate] => 2014-08-05T15:27:12+04:30
[serviceName] => game
[topNumber] => 09121153321
)
[serviceID] => 12946
)
)
i want print serviceName value from array that is game or print score from array that is 0
thanks
To access a parameter from php object (stdClass or normal)
you need object name with -> and the attribute name which you want to access,
in your case there are many stdClass objects one after another so the correct ways is,
echo $getUserServicesResponse->return->service->serviceName;
output:
game
FYI
the structure for which i have generated the output
stdClass Object
(
[return] => stdClass Object
(
[isactive] => Harry Potter and the Prisoner of Azkaban
[service] => stdClass Object
(
[serviceName] => game
)
)
)
Try this
$object->getUserServiceResponse->service->serviceName;

Access part of SimpleXMLElement Object - PHP

I need to loop through the items as an array within the SimpleXMLElement Object below but cannot seem to access it using $order->order->order->items. I can access the delivery and billing addresses using the same format, ie. $order->order->order->delivery_address and expected to get to the items array in the same way. However, I get an empty SimpleXMLElement Object when I print_r($order->order->order->items)
SimpleXMLElement Object
(
[order] => SimpleXMLElement Object
(
[id] => 860268
[shopkeeper_orderno] => 1001
[customer] => 797476
[creationdate] => Apr 19 2012 10:36:38:100AM
[reference] => k2koju45rmaqfl45n20xbkmq
[net] => 1500
[vat] => 17.5
[status] => 0
[isnew] => 1
[deductions] => 0
[postage] => 1
[paymentmethod] => PayPal
[instructions] => SimpleXMLElement Object
(
)
[errors] => SimpleXMLElement Object
(
)
[kashflow_synch] => 0
[order] => Array
(
[0] => SimpleXMLElement Object
(
[billing_address] => SimpleXMLElement Object
(
[0] =>
)
)
[1] => SimpleXMLElement Object
(
[delivery_address] => SimpleXMLElement Object
(
[0] =>
)
)
[2] => SimpleXMLElement Object
(
[items] => Array
(
[0] => SimpleXMLElement Object
(
[id] => 1285158
[headerID] => 860268
[productID] => 4867690
[description] => TEST ORDERING PF NODES - Special Offer Price
[net] => 1400
[vat] => 0
[qty] => 1
[formID] => -1
)
[1] => SimpleXMLElement Object
(
[id] => 1285159
[headerID] => 860268
[productID] => 4959678
[description] => Wedding dress
[net] => 100
[vat] => 17.5
[qty] => 1
[formID] => -1
)
)
)
)
[postage_tax] => 0
[dispatched] => 0
[paybyotherid] => -1
[ip] => 81.168.43.121
[wheredidyouhearid] => -1
)
)
EDIT: I just saw you made a mistake with the naming, the parent needs to be called <orders> and the sub items <order>
The SimpleXMLElement seems to be empty, in fact it's usually filled but not displayed when dumping (whoever thought of this crazy behaviour)
Can you try this?
foreach($order->orders->order as $order) { // should be orders then
echo $item->getName();
}
Or try it with SimpleXMLElement::children()
your items are actually on the second offset of the order array.
I'd just use the xPath to process these.
foreach($xmlObject->xpath('/order/order[2]/items') as $item)
{
// Do something with my $item
}
You can use a loop like the one below, then all you need to do is $items->id
foreach($order->children()->children()->items as $items)
{
}
Using Dan Lees suggestion I tried SimpleXMLElement::children() and did the below which works
foreach ($order->children() as $order) {
foreach ($order->children() as $order_details) {
foreach ($order_details->children() as $order_items) {
echo $order_items->id;
}
}
}

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

Foreach loop with mixed stdClass objects and arrays

Here I have an output from a website using Soap
stdClass Object
(
[page] => 0
[items] => 3
[total] => 3
[saleItems] => stdClass Object
(
[saleItem] => Array
(
[0] => stdClass Object
(
[reviewState] => open
[trackingDate] => 2011-11-03T01:06:43.547+01:00
[modifiedDate] => 2011-11-03T01:06:43.677+01:00
[clickDate] => 2011-10-30T22:57:57.383+01:00
[adspace] => stdClass Object
(
[_] => Beslist.nl [id] => 1437603
)
[admedium] => stdClass Object
(
[_] => 001. Program logo
[id] => 535098
)
[program] => stdClass Object
(
[_] => Zavvi NL
[id] => 8991
)
[clickId] => 1565847253976339456
[clickInId] => 0
[amount] => 40.45
[commission] => 2.83
[currency] => EUR
[gpps] => stdClass Object
(
[gpp] => Array
(
[0] => stdClass Object
(
[_] => shoplink
[id] => zpar0
)
)
)
[trackingCategory] => stdClass Object
(
[_] => Default
[id] => 45181
)
[id] => 46a4f84a-ba9a-45b3-af86-da5f3ec29648
)
)
)
)
I want to have the data (with a foreach loop) from program, commission and gpp->_. I can get the data from program and commission like this:
foreach ($sales->saleItems->saleItem as $sale) {
$programma = $sale->program->_;
$commissie = $sale->commission;
}
Works like a charm. However I can't get the data from the gpp->_ (want to have shoplink as result). I currently have:
foreach ($sales->saleItems->saleItem->gpps->gpp as $tracking) {
echo $tracking->_;
}
I get the error "Trying to get property of non-object". I've tried lots if variations and can't get it to work. Think I'm really close. Anyone has a solution?
This should work
foreach ($sales->saleItems->saleItem as $sale) {
foreach($sale->gpps->gpp as $tracking) {
echo $tracking->_;
}
As saleItem is an array, you won't be able to use chaining on it.

Categories