Historically, the main contact surface between MediaWiki and extensions were base classes (to be subclassed by extensions) and hook signatures. This made non-breaking changes (with support for outdated code during some deprecation period) relatively easy: it was possible to add more parameters to a hook signature, add more parameters (with default values) to a base class method, and add new methods to a base class, without breaking anything, since all of these are valid in PHP:
```lang=php
function hook1( $a ) {}
call_user_func( 'hook1', 1, 2 );
```
```lang=php
class Core1 {
public function f( $a, $b = null ) {}
}
class Extension1 extends Core1 {
public function f( $a ) {}
}
// will raise a warning but still work
```
```lang=php
class Core2 {
public function f( $a ) {}
public function f2( $b ) {}
}
class Extension2 extends Core2 {
public function f( $a ) {}
}
```
With dependency injection and generic [[https://en.wikipedia.org/wiki/Composition_over_inheritance|composition over inheritance]] practices, we are increasingly moving towards asking extensions to implement an interface instead of subclassing a base class (and there are plans to change the hook system in similar ways). The above change mitigation strategies fail for interfaces:
```lang=php
interface Core3 {
public function f( $a, $b = null );
}
class Extension3 implements Core3 {
public function f( $a ) {}
}
// fatal error
```
```lang=php
interface Core4 {
public function f( $a );
public function f2( $b );
}
class Extension4 implements Core4 {
public function f( $a ) {}
}
// fatal error
```
Replacing the old interface with a new one is not much better as it will break type hints. If we want to avoid inflicting a lot of pain on wiki owners with in-house or not fully up to date extensions, we need to come up with new change mechanisms.