Search code examples
phpdatetimeoopextend

Extend DateTime and DateTimeImmutable in PHP


I have a bunch of little procedural functions that manipulate DateTime in various ways, and it occurs to me that it might be easier to work with if I extend the DateTime class and turn these functions into methods of the class.

Okay, so easy peasy I can just do:

namespace My\Project;

class DateTime extends \DateTime {
    ... various new methods etc...
}

BUT... I also work with DateTimeImmutable objects, and would also want these additions in that class.

Is there some way to extend both of those classes to include my new functionality without repeating code? (Yes I know I can copy/paste the new methods into both new classes. Trying to be DRY here.)

Doesn't PHP have some way to "sideload" code into a class? Or a way to extend DateTimeInterface but also include the code specific to DateTime and DateTimeImmutable?

Is it bad practice to extend common classes like this? (Is it going to bite me in the butt down the road?)


Solution

  • Just create the two classes, each of those extending either DateTime or DateTimeImmutable, and a trait with all your "new methods, etc" which you can use directly in both of them.

    trait Convenient {
        public function echo() : void {
            echo "bar\n";
        }
    }
    
    class A extends \DateTime  {
        use Convenient;
    }
    
    class B extends \DateTimeImmutable {
        use Convenient;
    }
    

    Regarding "best practice", that's a matter of opinion; but it's hard to imagine anyone objecting to extending base classes. It's done all the time for a lot of valid reasons. Ideally client scripts should be targeting the interfaces, not the classes anyway.

    There are couple of well known and widely use libraries, like Carbon or Chronos that extend on the base date time objects. You may want to check those out before reinventing them.