Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.
a Object
(
[b] => b Object
(
[a] => a Object
(
[b] => *RECURSION*
)
)
)
But it's still pretty bad.
I was wondering: should I roll my own variant of var_dump using get_object_vars() that only goes, say, 2 levels deep (or even one level deep) for debugging bidirectional object structures? Should I make it smart and make it immediately truncate the branch when it detects an object it has seen before (not sure how to do that though...)
AmbCom wrote:
Should I make it smart and make it immediately truncate the branch when it detects an object it has seen before (not sure how to do that though...)
It's easy: to check two objects for identity just set some previously unset property in first obj and then check if it appeared in second obj.
But when you have multiple objects recursing, you'd have to go through each one of them and see whether or not there's an identity. Plus, you've developed an uncertainty phenomena: whenever you observe the class, you modify it!
// from php manual comments
class php {
# in === on objects in php4 does a dumb recusrive check instead
function CompareObject(&$a,&$b) {
$value='Bah! Stupid===';
$key="bah".rand(0,1000);
while(isset($a->$key) || isset($b->$key)) $key.=rand(0,9);
$a->$key=$value;
$result=($a->$key===$b->$key);
unset($a->$key);
if(!$result) // objs are not identical, we need to clean up the second obj
unset($b->$key);
return $result;
}
}
function my_var_dump($object, $level = 0) {
static $objs = array();
if(is_object($object))
$objs[] = &$object;
foreach((array) $object as &$elt) {
if(is_object($elt)) {
// check for recursion
foreach($objs as $obj) {
if(php::CompareObject($object, $obj)) {
echo "recursion at $level";
continue 2;
}
}
// there was no recursion
my_var_dump($elt, $level+1);
} else {
echo $elt;
}
}
}
That works but he implied he doesn't want to make modifications to the object just to observe it. As long as your __sleep function does not modify the object the code I posted above will work without making any modifications at all to the object.
The root of the problem is that PHP4's identitical operator doesn't figure out whether or not the two objects are references. If we have two identical objects THAT ARE NOT references, jshpro2's check will put them out as the same.
Besides... this is what happens when you serialize a recursive object structure:
Enforce strict naming conventions about recursive references, name em all _r_*. Then all the function has to do is check names and not expand _r_* ones.
Weirdan's approach will leave the two objects the same way they were before, so I don't think I'll mind using his method. But you still need to know which two objects to compare.
The function weirdan found does leave the objects the same, but it does make modifications to them, if you don't mind that I would recommend that over taking a checksum just for speed issues alone
Ambush Commander wrote:
But you still need to know which two objects to compare.
For that I used static array of references to those objects that are already visited (it's perfectly fine for single-threaded scripts but problems may arise when using tick).