PHP 5.4

PHP 5.4 is an obsolete version of PHP. PHP 5.3 gave us a number of things like closures, namespaces, and late static binding. PHP 5.4 adds a number of new features:

With PHP 5.4 there are some things we can start doing, this document attempts to list cleanup tasks that will be need to be conducted as well as new features worth discussing.

TContextSource (traits)Edit

We can use the new traits feature which may be used in RequestContext. Instead of being stuck with the ContextSource class we can implement a TContextSource trait. Context sources with parent classes would then be able to use the trait instead of having to reimplement a bunch of junk since it can't extend ContextSource.

Our ContextSource class can even become something as small as this.

class ContextSource implements IContextSource {
	use TContextSource;

WebRequest (magic_quotes_gpc)Edit

With magic_quotes_gpc() gone WebRequest will no longer need to modify $_COOKIE, $_ENV, $_GET, $_POST, $_REQUEST, and $_SERVER. WebRequest::checkMagicQuotes and WebRequest::fix_magic_quotes can disappear entirely.

As a bonus result thanks to the fact that WebRequest doesn't need to be constructed early on to modify these variables we can stop constructing it inside of Setup.php and can add it properly when the main context is setup.


safe_mode was removed so we won't need to do any more checks for it anymore.


register_globals() is gone, WebStart.php will no longer need to raise an error whenever the flag is enabled. Thus we can remove the following block of code:

# Protect against register_globals
# This must be done before any globals are set by the code
if ( ini_get( 'register_globals' ) ) {
	if ( isset( $_REQUEST['GLOBALS'] ) || isset( $_FILES['GLOBALS'] ) ) {
		die( '<a href="">$GLOBALS overwrite vulnerability</a>' );
	$forbidden = array(
	foreach ( $_REQUEST as $name => $value ) {
		if ( in_array( $name, $forbidden ) ) {
			header( "HTTP/1.1 500 Internal Server Error" );
			echo "register_globals security paranoia: trying to overwrite superglobals, aborting.";
			die( -1 );
		unset( $GLOBALS[$name] );


parse_url() now supports protocol relative urls. We won't need to hack around this as much. Our wfParseUrl() wrapper could probably be made simpler.

$this in ClosuresEdit

$this() is now handled correctly in closures. So cases where we might not have been able to use closures in the past because of needing to use private or protected methods or members can now use closures.

short array syntaxEdit

A shorter syntax is available to declare arrays. The array() construct can be replaced by square brackets [ ] similar to other interpreted languages.

# The PHP 5.3 list:
$list = array( 'a', 'b', 'c' );
# ... can be written in PHP 5.4 as:
$list = [ 'a', 'b', 'c' ];

# The PHP 5.3 hash:
$hash = array( 'x' => 1, 'y' => 2, 'z' => 3 );

# ... can be written in PHP 5.4 as:
$hash = [ 'x' => 1, 'y' => 2, 'z' => 3 ];

Array dereferencingEdit

$first = explode( '-', $str )[0]; will now work as you might expect

JSON formattingEdit

New flags were added to json_encode(), allowing JSON pretty printing and unescaped unicode. This way a large (and slow) block of regex code could be removed from our JSON lib. Useful for the API and some extensions.

callable type-hintEdit

A new 'callable' type hint is now available. We can remove is_callable checks from functions that take a callable as an argument and use the type-hint instead including MWCallableUpdate, ConfigFactory, SkinFactory, and probably more places.