-
Notifications
You must be signed in to change notification settings - Fork 0
Home
XP Compiler compiles future PHP to today's PHP. Kind of like the Babel of the PHP world.
It supports a large set of Hack, PHP 8.3, PHP 8.2, PHP 8.1 and PHP 8.0 but runs on anything >= PHP 7.4. Builtin features from newer PHP versions are translated to work with the currently executing runtime if necessary.
XP Compiler can be used in two ways: First of all, there is a command line tool, xp compile
. Second, it plugs into the class loading mechanism and compiles code just in time - providing a seamless experience of writing code, saving, and running PHP.
Some features from newer PHP versions as well as Hack language are still missing. The goal, however, is to have all features implemented - with the exception of where Hack's direction conflicts with PHP! An overview can be seen on this Wiki page.
We allow you to express types more concisely. On top of primitives, void, arrays, callables, iterables, objects and value types supported in today's PHP it allows nullable, function and union types, mixed, as well as array and map types:
function cookies(string $header): array<Cookie> {
// …
}
On top of this, property type hints are supported:
class Person {
private string $name;
}
Explore the type system.
One of the most requested PHP features are annotations - or attributes. XP Compiler supports them using PHP 8 attributes syntax:
use unittest\Test;
class FixtureTest {
#[Test]
public function can_create() {
new Fixture();
}
}
Continue reading the overview of supported annotation features
Using arrow notation, you can shorten closures:
$mul= function($a, $b) { return $a * $b; }
$mul= fn($a, $b) => $a * $b;
All details on arrow functions can be found here.
Because the =>
operator essentially stands for omit braces and return, it will also work in function and method declarations:
class Person {
private string $name;
public fn name(): string => $this->name;
}
This feature is unique to the XP Compiler (not found in PHP or Hack Language) and is described in the XP Compact functions RFC. See also C#'s Expression-bodied members.
Another way to shorten your code is to use constructor argument promotion. It replaces the declaration of a member and its initialization via the constructor with a single keyword:
class Connection {
public function __construct(private URL $url) { }
public fn url() => $this->url;
}
This feature comes from Hack language
Another HHVM / Hack feature supported by XP Compiler is the using
statement. You might know this from C#, or as "try with resources" from Java. It integrates with both the Disposabe
interface as well as XP's lang.Closeable
.
using ($c= new Connection($url)) {
…
} // $c->close() called automatically
See Using statement / Disposables for details.
Null handling can be tedious. XP Compiler supports the ?->
operator, which accesses instance members like ->
, but only if the expression on the left-hand side is not null.
$name= $list->first()?->name() ?? '(no name)';
See also the Null-safe instance operator documentation.
Trailing commas are allowed in all places PHP 7.3+ supports them:
- Arrays and maps - this has worked in PHP for a long time
- Function calls -
$f(1, 2, )
, see this RFC - Grouped use statements -
use lang\{Value, CommandLine, }
, see here
This PHP feature is supported natively in all PHP 7 versions:
$instance= new class() implements Runnable {
public function run() { … }
};
See https://wiki.php.net/rfc/anonymous_classes
Because of the way the XP Compiler is implemented, dereferencing from an instance creation expression can be done without the need to put it inside braces:
$string= new Date()->toString();
Of course, surrounding it with braces also works!
Sometimes, it is necessary to handle unrelated exceptions in the same manner:
try {
// ...
} catch (IllegalArgumentException | FormatException $e) {
$log->warn($e);
// ...
}
This PHP 7.1 feature is simulated on PHP 7.0. In addition, XP compiler also supports omitting the types in order to catch all exceptions (try { … } catch ($e) { … }
).
Class constants can have a public, private or protected modifier since PHP 7.1:
class FixtureTest extends TestCase {
private const SERVER = 'http://test.url/';
// ...
}
See https://wiki.php.net/rfc/class_const_visibility
Consistent with short array syntax, you can now also use a shorter form of list()
:
[$localpart, $domain]= explode('@', $mail);
This was introduced in PHP 7.1 and will be rewritten in older PHP versions.
With XP Compiler, throw
can be used inside ternary (?:) and null-coalesce (??) operators as well as inside lambda expressions and compact function syntax.
$command= $args ? $args[0] : throw new IllegalArgumentException('Argument expected');
class Test {
public fn invoke() => throw new MethodNotImplementedException(__METHOD__);
}
This feature is unique to XP Compiler and neither present in PHP nor HHVM. It is inspired by C# 7.0 and an open JavaScript proposal, as well as Kotlin.
Instead of having to write array_merge()
, the XP Compiler will allow using the ...
operator inside arrays:
$commandLine= ['xp', Splat::class, ...$args];
// same as:
$commandLine= array_merge(['xp', Splat::class], $args);
This feature was drafted as a PHP RFC at https://wiki.php.net/rfc/additional-splat-usage
All types in the type system can also be cast to. The following all also work in PHP:
$i= (int)"123"; // 123
$s= (string)$name; // string, invokes __toString() if object, coerces otherwise
$a= (array)$value; // array, objects' properties, an empty array for NULL, [$value]
On top of this, XP Compiler supports value type casts:
$h= (Handle)$h; // invokes cast($h, Handle::class)
Also, casting to nullable types work out of the box:
$i= (?int)null; // null
$h= (?Handle)$h; // null or an instance of Handle