This RFC proposes policies and strategies to mitigate problems arising from the need to change PHP interfaces that are implemented by classes defined by extensions. The core of the proposal is to recommend the use of base classes instead, and be more explicit about what constitutes MediaWiki's stable interface, and what guarantees apply to which part of it.
== Problem ==
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.
== Proposal (Daniel, September 2019)==
The problem outlined above is best addressed by using (abstract) base classes instead of "proper" PHP interfaces for extension points, and by providing more explicit guarantees to extension authors. The following steps are proposed:
# Adopt a Stable Interface Policy as drafted at https://www.mediawiki.org/wiki/Stable_Interface_Policy. The policy will take effect with the release of MW 1.35, giving extension authors time to adapt.
# Change the //Scope// section of the [[https://www.mediawiki.org/wiki/Deprecation_policy|deprecation policy]] to the text proposed below.
# Before the release of MW 1.35, add the annotations defined by the Stable Interface Policy to the relevant classes in MediaWiki core. Use existing extensions as a guide for what needs the new annotations.
**New Scope of the Deprecation Policy**
//This policy applies to the parts of the MediaWiki core (mediawiki/core.git) codebase defined to be stable by the [[https://www.mediawiki.org/wiki/Stable_Interface_Policy|Stable Interface Policy]].//
//This policy does not apply to the api.php API, client-side JavaScript, HTML output, or database schemas. Those should (and do) have their own deprecation practices. If changes do affect those components, they should also follow those deprecation practices as necessary. As with all policies, developers should apply their best judgement when following it, and use common sense as necessary.//
The rest of the section is to be removed.