homepage Welcome to WebmasterWorld Guest from 54.198.140.148
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
Forum Library, Charter, Moderators: coopster & jatar k

PHP Server Side Scripting Forum

    
Comparing PHP objects/classes (scalarly)
noyearzero




msg:4645403
 10:09 pm on Feb 14, 2014 (gmt 0)

So with the built in DateTime() class you can do something like:


$date1 = new DateTime($date_string) ;
$date2 = new DateTime($another_date) ;

if ($date1 < $date2) {
// do something
}


How does PHP decide what values to use for comparison? I'm trying to create my own class for software versions and I'd like it to be able to compare the classes in a similar way as the date classes do. I am using a __toString() magic method that returns a scalar value, but it's not using this for comparison.

(I realize in this case it is trivial since I can just cast both as a string at the time of comparison, or create a special function to compare them, but I'm ultimately looking for a deeper understanding of the language.)

 

penders




msg:4645843
 9:02 pm on Feb 16, 2014 (gmt 0)

AFAIK only the built-in objects can define their own methods of comparison. Ordinary class instances (ie. your own) are compared on a property by property basis (until a property that fails the comparison is reached).

Comparison operators:
php.net/manual/en/language.operators.comparison.php

Comparing objects:
php.net/manual/en/language.oop5.object-comparison.php

noyearzero




msg:4645865
 11:17 pm on Feb 16, 2014 (gmt 0)

Interesting. I saw there was a note in the object comparison docs that says "Extensions can define own rules for their objects comparison (==)." I guess from what you're saying that means only built in extensions?

So as a workaround I have a few ideas.
1) Leach off a built in object that allows storing of a string and properly sorts it by that. I have an extension to the DateTime object that I use and it maintains the built in comparison even though I store some extra data in the child object. I'd just need to find the right built in object for that, if it exists at all.

2) Use multiple objects and nest them so that the outer most only contains the string to use for comparison and in the inner contains all the extra data I want to store. This is supposing the test isn't recursive.

penders




msg:4645901
 1:11 am on Feb 17, 2014 (gmt 0)

I guess from what you're saying that means only built in extensions?


Yes. From the first link (above) regarding comparison operators there is a table that details the behaviour when comparing different types. For the object/object comparison it states (although it's not particularly well written IMO):

Built-in classes can define its own comparison, different classes are uncomparable, same class - compare properties the same way as arrays (PHP 4), PHP 5 has its own explanation


2) Use multiple objects and nest them ...


Not sure what you mean?

I would be very interested to see what you can come up with, however, my gut feeling is to use standard method calls until this feature is built in to PHP, particularly when writing portable, maintainable code.

For example...
if ($object1->version < $object2->version) { ...


("version" could be a protected property retrieved with the __get() magic method. Or call the getVersion() method directly?)

Or to compare two objects (of the same type):

if ($object1->compare($object2)) {...


In this case the compare() method could return -1 if $object1 is less than $object2, 0 if equal and +1 if greater.

The method signature could be defined with a type hint to trap compile time errors...
public function compare(MyClassName $object) {...

noyearzero




msg:4646075
 3:39 pm on Feb 17, 2014 (gmt 0)

What I wanted to do was something like

class a {
public function __construct($v) {
$this->x = '001.000.001' ; // cleaned up and comparable
$this->b = new b($v) ;
}
}

class b {
protected $data ;

public function __construct($v) {
$this->data = $v ;
}
}

$v1 = new a('1.0.1') ;

$v2 = new a('1.00.1') ;


But the comparison is recursive and checks all of sub-class b's properties too even if they are private or protected.

I will probably end up going with the

if ($object1->version < $object2->version) { ...


type comparison. But I would really like to see a magic method for comparisons.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved