Bendegúz Csirmaz

PHP quiz #5 - constructor overriding

Most PHP developers probably have already used constructor overriding, as it would be virtually impossible to create object oriented applications without it. Still, many of them might not be familiar with the exact rules around the subject - I know I wasn't.

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

In PHP, the only rule to overriding constructors is that there are no rules!

Constructors can be overridden with any signature. Their parameters can be changed freely and without consequence.

They can be overridden with completely unrelated parameter types:

<?php

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

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

Parameters can also be omitted (or added):

<?php

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

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

Overriding functions

Note that this kind of freedom only applies to constructors. Were these functions 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) {}
}

Credits

This post was inspired by an inaccurate Wikipedia article.


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