darkgr33n Posted November 24, 2009 Share Posted November 24, 2009 Hi I've got a StdClass Object that I need to parse. I can parse specific elements, but not sure how to parse when there is more than one element with the same name. example: $foo = array ( (object) array("Label" => "Street", "Line" => "Stanley Road"), (object) array("Label" => "Town", "Line" => "Manchester"), (object) array("Label" => "Number of Rules", "Line" => "2"), (object) array("Label" => "Rule", "Line" => "X014"), (object) array("Label" => "Rule Text", "Line" => "Rule text for X014"), (object) array("Label" => "Rule", "Line" => "X015"), (object) array("Label" => "Rule Text", "Line" => "Rule text for X015") ); /* this is what $foo contains with print_r Array ( [0] => stdClass Object ( [Label] => Street [Line] => Stanley Road ) [1] => stdClass Object ( [Label] => Town [Line] => Manchester ) [2] => stdClass Object ( [Label] => Number of Rules [Line] => 2 ) [3] => stdClass Object ( [Label] => Rule [Line] => X014 ) [4] => stdClass Object ( [Label] => Rule Text [Line] => Rule text for X014 ) [5] => stdClass Object ( [Label] => Rule [Line] => X015 ) [6] => stdClass Object ( [Label] => Rule Text [Line] => Rule text for X015 ) ) */ foreach($foo as $foo_data) { $foo_list [$foo_data->Label] = $foo_data->Line; } echo ($foo_list["Street"] . "<br>"); echo ($foo_list["Town"] . "<br>"); echo ($foo_list["Number of Rules"] . "<br>"); echo ($foo_list["Rule"] . "<br>"); echo ($foo_list["Rule Text"] . "<br>"); echo ($foo_list["Rule"] . "<br>"); echo ($foo_list["Rule Text"] . "<br>"); /* this is what is written with the echo's above - two sets of X015 Stanley Road Manchester 2 X015 Rule text for X015 X015 Rule text for X015 */ There is a "Number of Rules" element which will tell me how many Rule elements I'm expecting. This could be anything between 0 and 10 rule/rule text element pairs, the example above having 2. Any ideas how I would parse the entire array correctly [i'm going to be putting them into separate variables to use in a database, just using echo in the example. I need to see: Stanley Road Manchester 2 X014 Rule text for X014 X015 Rule text for X015 Thanks Quote Link to comment Share on other sites More sharing options...
flyhoney Posted November 24, 2009 Share Posted November 24, 2009 You mean like this? <?php $foo = array ( (object) array("Label" => "Street", "Line" => "Stanley Road"), (object) array("Label" => "Town", "Line" => "Manchester"), (object) array("Label" => "Number of Rules", "Line" => "2"), (object) array("Label" => "Rule", "Line" => "X014"), (object) array("Label" => "Rule Text", "Line" => "Rule text for X014"), (object) array("Label" => "Rule", "Line" => "X015"), (object) array("Label" => "Rule Text", "Line" => "Rule text for X015") ); foreach ($foo as $bar) { echo "{$bar->Line}<br />"; } Quote Link to comment Share on other sites More sharing options...
darkgr33n Posted November 24, 2009 Author Share Posted November 24, 2009 You mean like this? <?php $foo = array ( (object) array("Label" => "Street", "Line" => "Stanley Road"), (object) array("Label" => "Town", "Line" => "Manchester"), (object) array("Label" => "Number of Rules", "Line" => "2"), (object) array("Label" => "Rule", "Line" => "X014"), (object) array("Label" => "Rule Text", "Line" => "Rule text for X014"), (object) array("Label" => "Rule", "Line" => "X015"), (object) array("Label" => "Rule Text", "Line" => "Rule text for X015") ); foreach ($foo as $bar) { echo "{$bar->Line}<br />"; } Yes, sort of! But, rather than echoing them out, I need to set a session variable named from the Label, which is why I tried putting them in an array, and when I get to the Rule session variable, I can add a number suffix. Sorry, maybe my initial post wasn't that clear. I really want to achieve being able to set the sessions like this: $_SESSION['Street'] = "Stanley road"; $_SESSION['Town'] = "Manchester"; $_SESSION['Rule1'] = "X014"; $_SESSION['RuleText1'] = "Rule text for X014"; $_SESSION['Rule2'] = "X015"; $_SESSION['RuleText2'] = "Rule text for X015"; so, when I come across a Rule or Rule Text Label, I need to add a count suffix to the name, so Rule + 1 Rule + 2 etc Does that make more sense ? Sorry. I've tried a few things, but it starts to get really convoluted, and I'm sure there must be an easier way! Cheers Quote Link to comment Share on other sites More sharing options...
flyhoney Posted November 24, 2009 Share Posted November 24, 2009 This solves your problem, but to be honest, I think you're probably going about this the wrong way. I don't know enough about what you're doing to say for sure, but this is not really the best way to solve things in PHP. If you describe the problem in more detail I might be able to guide you towards a more elegant solution. In the mean time: <?php $foo = array ( (object) array("Label" => "Street", "Line" => "Stanley Road"), (object) array("Label" => "Town", "Line" => "Manchester"), (object) array("Label" => "Number of Rules", "Line" => "2"), (object) array("Label" => "Rule", "Line" => "X014"), (object) array("Label" => "Rule Text", "Line" => "Rule text for X014"), (object) array("Label" => "Rule", "Line" => "X015"), (object) array("Label" => "Rule Text", "Line" => "Rule text for X015") ); $rules = array(); $rule_texts = array(); foreach ($foo as $bar) { if ($bar->Label == "Rule") { $rules[] = $bar->Line; } else if ($bar->Label == "Rule Text") { $rule_texts[] = $bar->Line; } else { $_SESSION[$bar->Label] = $bar->Line; } } for ($x = 1; $x <= count($rules); $x++) { $_SESSION["Rule$x"] = $rules[$x - 1]; $_SESSION["RuleText$x"] = $rule_texts[$x - 1]; } print_r($_SESSION); exit; *EDIT* fixed a typo Quote Link to comment Share on other sites More sharing options...
darkgr33n Posted November 24, 2009 Author Share Posted November 24, 2009 Thanks for that. I've gone down a similar road, spurred on by your first post: $rule_suffix = 0; $text_suffix = 0; foreach($foo as $bar) { if ($bar->Label == 'Rule') { $rule_suffix ++; echo ("RULE" . $rule_suffix . " : " . $bar->Line ."<br>"); } elseif ($bar->Label == 'Rule Text') { $text_suffix ++; echo ("RULE TEXT" . $text_suffix . " : " . $bar->Line ."<br>"); } else { echo ("{$bar->Label} : {$bar->Line}<br>"); } } But you're right, not sure it is the best way to go, but it works at least, so I am further on than I was. As an overview, I'm receiving a SOAP Reponse, in the format of the $foo object, and just need to parse the object, pull out the variables into Session variables, and then write to a database; Obviously if we didn't have elements of the same name returned, it would be a lot less convoluted, but unfortunately, they're the requirements we're working to. Thanks again for helping me out, I appreciate that. Also encouraged that I came up with something similar, although not as robust as yours. Quote Link to comment Share on other sites More sharing options...
flyhoney Posted November 24, 2009 Share Posted November 24, 2009 Just remember that you can store arrays in $_SESSION. Anytime you find yourself with variables like var1, var2, var3 in PHP you are definitely doing things wrong Arrays are WIN. Quote Link to comment Share on other sites More sharing options...
darkgr33n Posted November 24, 2009 Author Share Posted November 24, 2009 Just remember that you can store arrays in $_SESSION. Anytime you find yourself with variables like var1, var2, var3 in PHP you are definitely doing things wrong Arrays are WIN. lol, thanks for the tip, i like WIN; being self-taught I've missed some of those fundamental pearls of wisdom - i shall carry it with me always Quote Link to comment Share on other sites More sharing options...
darkgr33n Posted November 24, 2009 Author Share Posted November 24, 2009 Ok, I've got it down a little, and am using arrays $foo = array ( (object) array("Label" => "Street", "Line" => "Stanley Road"), (object) array("Label" => "Town", "Line" => "Manchester"), (object) array("Label" => "Number of Rules", "Line" => "2"), (object) array("Label" => "Rule", "Line" => "X014"), (object) array("Label" => "Rule Text", "Line" => "Rule text for X014"), (object) array("Label" => "Rule", "Line" => "X015"), (object) array("Label" => "Rule Text", "Line" => "Rule text for X015")); $suffix = 0; $rules = array(); foreach($foo as $bar) { if ($bar->Label == 'Rule') { $suffix ++; $rules[] = array($bar->Label.$suffix => $bar->Line); } elseif ($bar->Label == 'Rule Text') { $rules[] = array($bar->Label.$suffix => $bar->Line); } else { echo ("{$bar->Label} : {$bar->Line}<br>"); } } print_r ($rules); which returns: Street : Stanley Road Town : Manchester Number of Rules : 2 Array ( [0] => Array ( [Rule1] => X014 ) [1] => Array ( [Rule Text1] => Rule text for X014 ) [2] => Array ( [Rule2] => X015 ) [3] => Array ( [Rule Text2] => Rule text for X015 ) ) which I think I can work with. The SOAP Response is always going to be a Rule followed by a Rule Text, so I should be safe ... I think ... Quote Link to comment Share on other sites More sharing options...
darkgr33n Posted November 24, 2009 Author Share Posted November 24, 2009 ok, i've got something now, although still not too happy about two foreach loops for one iteration. foreach($foo as $bar) { if ($bar->Label != 'Rule' AND $bar->Label != 'Rule Text') { $_SESSION[$bar->Label] = $bar->Line; } else { switch ($bar->Label) { case 'Rule': $suffix ++; $rules[$bar->Label.$suffix] = $bar->Line; break; case 'Rule Text': $rules[$bar->Label.$suffix] = $bar->Line; break; } } } foreach ($rules as $key => $value) { $_SESSION[$key] = $value; } which gives the following: var_dump ($_SESSION); array(7) { ["Street"]=> string(12) "Stanley Road" ["Town"]=> string(10) "Manchester" ["Number of Rules"]=> string(1) "2" ["Rule1"]=> string(4) "X014" ["Rule Text1"]=> string(18) "Rule text for X014" ["Rule2"]=> string(4) "X015" ["Rule Text2"]=> string(18) "Rule text for X015" } which is pretty much what I was after, but open to any cleaner suggestions Quote Link to comment Share on other sites More sharing options...
cornetofreak Posted November 24, 2009 Share Posted November 24, 2009 Try typecasting the object to an array. E.g. $foo = $ThestdClass; $bar = (array)$foo; no that should convert the stdClass into an array Quote Link to comment Share on other sites More sharing options...
darkgr33n Posted November 24, 2009 Author Share Posted November 24, 2009 Try typecasting the object to an array. E.g. $foo = $ThestdClass; $bar = (array)$foo; no that should convert the stdClass into an array Thanks, although not used directly, it did get me looking further, and I've come up with the following, although still seems quite long-winded. Perhaps there's no shorter way. I wish the SOAP return would add a sequential suffix to the tag names, but I don't have control over that $foo = array ( (object) array("Label" => "Street", "Line" => "Stanley Road"), (object) array("Label" => "Town", "Line" => "Manchester"), (object) array("Label" => "Number of Rules", "Line" => "2"), (object) array("Label" => "Rule", "Line" => "X014"), (object) array("Label" => "Rule Text", "Line" => "Rule text for X014"), (object) array("Label" => "Rule", "Line" => "X015"), (object) array("Label" => "Rule Text", "Line" => "Rule text for X015"), ); function objectToArray( $object ) { if( !is_object( $object ) && !is_array( $object ) ) { return $object; } if( is_object( $object ) ) { $object = get_object_vars( $object ); } return array_map( 'objectToArray', $object ); } // cast the object $array = (array) $foo; // convert array to object $array = (array) objectToArray($foo); /* which gives: Array ( [0] => Array ( [Label] => Street [Line] => Stanley Road ) [1] => Array ( [Label] => Town [Line] => Manchester ) [2] => Array ( [Label] => Number of Rules [Line] => 2 ) [3] => Array ( [Label] => Rule [Line] => X014 ) [4] => Array ( [Label] => Rule Text [Line] => Rule text for X014 ) [5] => Array ( [Label] => Rule [Line] => X015 ) [6] => Array ( [Label] => Rule Text [Line] => Rule text for X015 ) ) */ $suffix = 0; $array_count = count($array)-1; for ($i=0;$i<=$array_count ;$i++) { if ($array[$i]['Label'] != 'Rule' AND $array[$i]['Label'] != 'Rule Text') { $_SESSION[$array[$i]['Label']] = $array[$i]['Line']; } else { switch ($array[$i]['Label']) { case 'Rule': $suffix ++; $_SESSION[$array[$i]['Label'].$suffix] = $array[$i]['Line']; break; case 'Rule Text': $_SESSION[$array[$i]['Label'].$suffix] = $array[$i]['Line']; break; } } } var_dump($_SESSION); /* prints out: array(7) { ["Street"]=> string(12) "Stanley Road" ["Town"]=> string(10) "Manchester" ["Number of Rules"]=> string(1) "2" ["Rule1"]=> string(4) "X014" ["Rule Text1"]=> string(18) "Rule text for X014" ["Rule2"]=> string(4) "X015" ["Rule Text2"]=> string(18) "Rule text for X015" } Quote Link to comment Share on other sites More sharing options...
salathe Posted November 24, 2009 Share Posted November 24, 2009 I'm not exactly clear precisely what you are trying to achieve (perhaps I haven't read the thread carefully enough) so apologies in advance is this isn't helpful to you. However, the code below takes your array of objects (from SOAP or a hard-coded array for testing) and parses them into a neat array structure. I wasn't going to reply to the thread (not being clear if this is what you want) but the snippet below introduces a different approach to moulding an array of items into some other structure which even if it's not particularly useful to you darkgr33n, may be an idea for others to store for later consideration when doing a task like this. So, onto the snippet which produces the following structure/output from your array of objects (see $foo in above posts). Expected output array(4) { ["Street"]=> string(12) "Stanley Road" ["Town"]=> string(10) "Manchester" ["Number of Rules"]=> string(1) "2" ["Rules"]=> array(2) { ["X014"]=> string(18) "Rule text for X014" ["X015"]=> string(18) "Rule text for X015" } } The snippet function parse_foo($result, $value) { // Stores the last rule id (so its text can be related to it) static $last; if ($value->Label == 'Rule') { // Add empty rule (its value will come next) $last = $value->Line; $result['Rules'][$last] = ""; } elseif ($value->Label == 'Rule Text') { // Add value to rule $result['Rules'][$last] = $value->Line; } else { // Not a rule id or text $result[$value->Label] = $value->Line; } return $result; } // Lets see what parse_foo does var_dump(array_reduce($foo, 'parse_foo')); Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.