Jump to content

Equality between two object's attributes


Go to solution Solved by requinix,

Recommended Posts

I wish to compare that two objects which are instances of the same class have identical attribute names but not necessarily attribute values.  In addition, I would like an optional check to determine if the object attribute values are the same type.  My last two checks provide the results, however, curious if the script can be improved using built in functions or some other approach.  Thanks

<?php
function comp($o1,$o2){
    var_dump($o1);
    echo('<br>');
    var_dump($o2);
    echo('<br>');
    echo('==: '.($o1==$o2?'TRUE':'FALSE')."\n");
    echo('<br>');
    echo('===: '.($o1===$o2?'TRUE':'FALSE')."\n\n");
    echo('<br>class name: '.get_class($o1).' are '.(get_class($o1)==get_class($o2)?'EQUAL':'NOT EQUAL'));
    $a1=(array) $o1;
    $a2=(array) $o2;
    $cnt=count(array_intersect_key($a1,$a2));
    echo('<br>Attributes names are the same (but not necessarily value types): '.($cnt==count($a1) && $cnt==count($a2)?'TRUE':'FALSE'));
    $cnt=count(array_intersect_assoc(conv($a1),conv($a2)));
    echo('<br>Attributes names are the same and so are value types: '.($cnt==count($a1) && $cnt==count($a2)?'TRUE':'FALSE'));
    echo('<br><br>');
}


function conv($a){
    $anew=[];
    foreach($a as $k=>$v) $anew[$k]=gettype($v);
    return $anew;
}


$o=(object)['a'=>1,'b'=>2,'c'=>3];


comp($o,$o);
comp($o,(object)['a'=>'1','b'=>'2','c'=>'3']);
comp($o,(object)['c'=>'3','b'=>'2','a'=>'1']);
comp($o,(object)['c'=>3,'b'=>2,'a'=>1]);
comp($o,(object)['c'=>10,'b'=>20,'a'=>30]);
comp($o,(object)['c'=>'10','b'=>'20','a'=>'30']);
comp($o,(object)['c'=>'10','b'=>'20']);
comp($o,(object)['d'=>'123','c'=>'10','b'=>'20','a'=>'30']);
object(stdClass)#1 (3) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(3) } 
object(stdClass)#1 (3) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(3) } 
==: TRUE 
===: TRUE 
class name: stdClass are EQUAL
Attributes names are the same (but not necessarily value types): TRUE
Attributes names are the same and so are value types: TRUE

object(stdClass)#1 (3) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(3) } 
object(stdClass)#2 (3) { ["a"]=> string(1) "1" ["b"]=> string(1) "2" ["c"]=> string(1) "3" } 
==: TRUE 
===: FALSE 
class name: stdClass are EQUAL
Attributes names are the same (but not necessarily value types): TRUE
Attributes names are the same and so are value types: FALSE

object(stdClass)#1 (3) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(3) } 
object(stdClass)#2 (3) { ["c"]=> string(1) "3" ["b"]=> string(1) "2" ["a"]=> string(1) "1" } 
==: TRUE 
===: FALSE 
class name: stdClass are EQUAL
Attributes names are the same (but not necessarily value types): TRUE
Attributes names are the same and so are value types: FALSE

object(stdClass)#1 (3) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(3) } 
object(stdClass)#2 (3) { ["c"]=> int(3) ["b"]=> int(2) ["a"]=> int(1) } 
==: TRUE 
===: FALSE 
class name: stdClass are EQUAL
Attributes names are the same (but not necessarily value types): TRUE
Attributes names are the same and so are value types: TRUE

object(stdClass)#1 (3) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(3) } 
object(stdClass)#2 (3) { ["c"]=> int(10) ["b"]=> int(20) ["a"]=> int(30) } 
==: FALSE 
===: FALSE 
class name: stdClass are EQUAL
Attributes names are the same (but not necessarily value types): TRUE
Attributes names are the same and so are value types: TRUE

object(stdClass)#1 (3) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(3) } 
object(stdClass)#2 (3) { ["c"]=> string(2) "10" ["b"]=> string(2) "20" ["a"]=> string(2) "30" } 
==: FALSE 
===: FALSE 
class name: stdClass are EQUAL
Attributes names are the same (but not necessarily value types): TRUE
Attributes names are the same and so are value types: FALSE

object(stdClass)#1 (3) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(3) } 
object(stdClass)#2 (2) { ["c"]=> string(2) "10" ["b"]=> string(2) "20" } 
==: FALSE 
===: FALSE 
class name: stdClass are EQUAL
Attributes names are the same (but not necessarily value types): FALSE
Attributes names are the same and so are value types: FALSE

object(stdClass)#1 (3) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(3) } 
object(stdClass)#2 (4) { ["d"]=> string(3) "123" ["c"]=> string(2) "10" ["b"]=> string(2) "20" ["a"]=> string(2) "30" } 
==: FALSE 
===: FALSE 
class name: stdClass are EQUAL
Attributes names are the same (but not necessarily value types): FALSE
Attributes names are the same and so are value types: FALSE
Link to comment
https://forums.phpfreaks.com/topic/306270-equality-between-two-objects-attributes/
Share on other sites

This may be a learning moment for me but I have to ask (much like the OP). If two vars are of the same class, then don't they have the same attribute names? Of course - not the same values, but the names are set by definition.

This may be a learning moment for me but I have to ask (much like the OP). If two vars are of the same class, then don't they have the same attribute names? Of course - not the same values, but the names are set by definition.

Good point.  I should have said "stdClass".

I too would use array_intersect_key for the property names. For the value types I'd do array_map+gettype+array_intersect_assoc.

Actually, I meant to say, I was planning on using array_walk().  How should arry_map() be used?

This may be a learning moment for me but I have to ask (much like the OP). If two vars are of the same class, then don't they have the same attribute names? Of course - not the same values, but the names are set by definition.

Generally speaking, yes. However PHP allows dynamically creating properties by just assigning it, so it's technically possible that they don't.

 

I would probably be willing to assume objects of the same class have the same property list though, as dynamic properties on anything other than stdClass are signs of poor code IMO.

Actually, I meant to say, I was planning on using array_walk().  How should arry_map() be used?

The big difference (which you know by now) is that array_walk is like a foreach over an array which does not return anything particularly useful, while array_map can return a whole new array based on a transformation to the original. A transformation such as "turn each value into gettype(value)".
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.