Documentation

Language overview

Bring expressive types, checked recovery, and fearless refactoring to PHP, then ship clean PHP.

++PHP gives PHP code more ways to express what it means. A repository can preserve the entity type it stores. An array can state its key and value types. A service can publish the failures its caller must handle. A multi-branch decision can produce one checked value. The compiler follows those relationships across the project and catches contradictions before the application runs.

The source stays recognizably PHP: <?php files, namespaces, classes, functions, Composer packages, extensions, and the official PHP runtime. ++PHP adds the missing compile-time vocabulary, then emits a complete, readable PHP application.

Write contracts rich enough for confident refactoring. Ship PHP your tools, infrastructure, and team already understand.

PHP, with more room to express intent

The compiler fits naturally between writing source and running the application:

  1. Move the PHP files you choose to .ppphp and add the types that make their intent clear.
  2. Run ppphp check while developing to validate those files with the rest of the project.
  3. Run ppphp build to produce the PHP tree that your application executes or deploys.
  4. Test and run the generated project with the same PHP tools you already use.

A small service can make its complete data flow visible:

<?php

final class BasketTotal
{
    public function calculate(array<LineItem> $items): int
    {
        int $total = 0;

        foreach ($items as LineItem $item) {
            $total += $item->priceInCents;
        }

        return $total;
    }
}

The parameter promises a list of LineItem values. The local $total has one stable meaning for its entire lifetime. The loop variable carries the element type into the body. Rename a member, change a return, or reshape an API and the compiler shows every affected relationship across the project.

What the compiler ships

The compiler turns ++PHP syntax into standard PHP and adds PHPDoc that PHPStan, IDEs, and PHP consumers can understand:

<?php

final class BasketTotal
{
    /** @param list<LineItem> $items */
    public function calculate(array $items): int
    {
        /** @var int $total */
        $total = 0;

        foreach ($items as $item) {
            $total += $item->priceInCents;
        }

        return $total;
    }
}

Generated files preserve namespaces and their source-root-relative paths, contain declare(strict_types=1), pass php -l, and run on PHP 8.4+. Plain PHP files are copied byte-for-byte, so the build output contains the complete application.

Refactor with the whole project in view

In a .ppphp file, parameters, properties, return values, and ordinary locals are explicit. Nullability must be written. Bare assignment cannot silently create a local. Missing returns, invalid arguments, unknown members, and incompatible assignments are caught across the project.

Use mixed, bare array, object, callable, or iterable at genuinely dynamic boundaries. Writing the broad type makes it clear where validation belongs.

The result is a codebase whose signatures and bodies tell the same story. Editors and CI receive source-located diagnostics with stable codes and concrete help, while generated PHPDoc carries generic and error relationships into PHPStan and IDEs.

The output belongs to the PHP ecosystem

The generated application uses standard PHP syntax and useful PHPDoc. Arrays remain PHP arrays. Checked errors remain exceptions. Objects, extensions, comparison, and execution follow PHP behavior. Generated files are designed to be read, debugged, tested, profiled, and deployed with familiar PHP tools.

Operations teams deploy the generated application with the PHP runtime, servers, workers, and monitoring they already use.

Choose your starting point

You can also open the playground from the main navigation to edit and compile the same examples without installing anything.