back

Bendegúz Csirmaz

This post is part of a series based on a presentation I gave at Cheppers on March 20, 2019.

PHP quiz #5 - constructor overriding

Okay! We have only seen weird edge cases so far. This one is actually pretty important.

Question

What will this code output?

<?php

class A {
  public function __construct(LogicException $l) {
    echo "A";
  }
}

class B extends A {
  public function __construct(Exception $e) {
    echo "B\n";
  }
}

new B(new Exception('Exception!'));
  • A Warning: Declaration of B::__construct(Exception $e) should be compatible with A::__construct(LogicException $l)
  • B
    B
  • C
    AB
  • C Fatal error: Uncaught Exception: Exception!

Answer

Show the answer
B
B

Explanation

Overriding constructors

PHP constructors can be overridden with any signature.

Their parameters can be changed freely and without consequence.

Unrelated types

They can be overridden even if the parameter types are not related.

<?php

class A {
  public function __construct(array $a) {}
}

class B extends A {
  // Works fine!
  public function __construct(Closure $c) {}
}

More/less parameters

They can be overridden even if the number of parameters differ.

<?php

class A {
  public function __construct(array $a) {}
}

class B extends A {
  // This is OK too.
  public function __construct() {}
}

Overriding functions

Were they not constructors, PHP would issue a warning.

<?php

class A {
  public function abc(LogicException $l) {}
}

class B extends A {
  // Warning: Declaration of B::abc(Exception $e) should be
  // compatible with A::abc(LogicException $l)
  public function abc(Exception $e) {}
}

Conclusion

This post was inspired by an inaccurate Wikipedia article.

I'm sure most PHP developers have already used constructor overriding, even if they didn't realize it. It's virtually impossible to create object oriented applications without it.

We'll take a look at overriding regular methods next.

<< previous

next >>