3

Working with DateTime in projects again have a problem with duplicating if use array_unique to array which have a elemts of object,(but probles only with DateTime), see code:

class simpleClass
{
    public $dt;

    function __construct($dt)
    {
        $this->dt = $dt;
    }
}

$dateObj = new simpleClass(new DateTime);
$std = new stdClass;
$arr = [$dateObj, $dateObj, $std, $std, $std, $std];

var_dump(array_unique($arr, SORT_REGULAR));

Expected 1 element with dateObj But actually there 2

2

2 Answers 2

1

Function array_unique() will compare strings, so objects will be casted to strings. Solution to that would be to use __toString() magic method to return full date identifier:

class simpleClass
{
    public $dt;

    function __construct(DateTime $dt) {
        $this->dt = $dt;
    }

    public function __toString() {
        return $this->dt->format('r');
    }

}

$dateObj1 = new simpleClass(new DateTime);
$dateObj2 = new simpleClass(new DateTime);
$dateObj3 = new simpleClass(new DateTime('today'));
$arr = [$dateObj1, $dateObj2, $dateObj3];

print_r(array_unique($arr));

Demo.

Sign up to request clarification or add additional context in comments.

5 Comments

ehh, but the difference that you create 3 objects, but I trying to find the reason of my problem, I my project, I can not just to create objects such as in your example
I find this some kind of bug, and have an issue to find the reasons
@sergio: yes, your example is behaving strangelly, it should throw somekind of error, or notice, because if you cast your $dateObj or $std to string, it will throw Catchable fatal error: Object of class CLASSNAME could not be converted to string, but when you use them in function array_unique(), where internal cast to string is performed, no error appears and output is strange...
Hmm, that's why I read a lot of documentation of php but does not find the answer..
@sergio: nevertheless, array_unique() works with strings. Two elements are considered equal if and only if (string)$elem1===(string)$elem2. In words: when the string representation is the same. The first element will be used. You are casting objects to strings, that don't have toString magic method, so this is the big error.
0

I still can't understand. Setting the array with:

$arr = [$dateObj, $dateObj, $std, $std];

returns:

array (size=2)
    0 => 
        object(simpleClass)[1]
            public 'dt' => 
              object(DateTime)[2]
                  public 'date' => string '2013-11-14 14:37:08' (length=19)
                  public 'timezone_type' => int 3
                  public 'timezone' => string 'Europe/Rome' (length=11)
    2 => 
       object(stdClass)[3]

This way, array_unique seems to work...

6 Comments

Ehh, some strange behaviour
Like I said, you cannot work with function array_unique() if objects are not convertable to string; results will be unpredictable. See demo.
Ok ok, I'm just investigating. It seems to me that also with the magic __toString() it doesn't work.
@ilpaijin: can you make a eval.in example where __toString() doesn't work? It seems hard to believe that it won't work.
@ilpaijin: remove 2nd parameter SORT_REGULAR from array_unique() function. Demo.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.