← All docs

Your First Program

Write, compile, and run your first PHP program with elephc.

Hello, World

Create a file called hello.php:

<?php
echo "Hello, World!\n";

Compile it:

elephc hello.php

This produces a native binary called hello in the same directory. Run it:

./hello
Hello, World!

That’s it — a standalone native binary, no PHP interpreter needed.

A slightly bigger example

Create greet.php:

<?php
if ($argc < 2) {
    echo "Usage: ./greet <name>\n";
    exit(1);
}

$name = $argv[1];
echo "Hello, " . strtoupper($name) . "!\n";

Compile and run:

elephc greet.php
./greet elephc
Hello, ELEPHC!

The program reads command-line arguments through $argc and $argv, just like PHP.

FizzBuzz

A classic example to see variables, loops, and conditionals in action:

<?php
for ($i = 1; $i <= 100; $i++) {
    if ($i % 15 == 0) {
        echo "FizzBuzz\n";
    } elseif ($i % 3 == 0) {
        echo "Fizz\n";
    } elseif ($i % 5 == 0) {
        echo "Buzz\n";
    } else {
        echo $i . "\n";
    }
}
elephc fizzbuzz.php
./fizzbuzz

What happens under the hood

When you run elephc hello.php, the compiler:

  1. Lexes the source into tokens
  2. Parses tokens into an AST (Abstract Syntax Tree)
  3. Lowers file-local magic constants and applies ifdef branches from --define
  4. Builds the compile-time autoload registry from Composer metadata and supported spl_autoload_register() rules
  5. Resolves include / require files, pre-scans statically resolvable include declarations, folds compile-time include paths, and lowers *_once runtime guards
  6. Resolves namespaces, imports, and fully-qualified names
  7. Runs static autoload insertion for referenced class-like symbols
  8. Folds constant expressions that are already statically known
  9. Type-checks the program and collects non-fatal warnings
  10. Optimizes checked AST control flow through propagation, pruning, normalization, and dead-code elimination
  11. Generates assembly for the selected target
  12. Assembles and links the .s / .o files into a native executable

The intermediate .s and .o files are cleaned up automatically. You’re left with a single executable.

Useful inspection flags

If you want to inspect the compile more closely, these flags are a good starting point:

# Print per-phase compiler timings to stderr
elephc --timings hello.php

# Emit assembly only, plus a sidecar source-map file
elephc --emit-asm --source-map hello.php

--timings reports phases such as lexing, parsing, early optimization, type checking, constant propagation, post-check pruning, control-flow normalization, dead-code elimination, runtime-cache preparation, code generation, assembling, and linking.

--source-map writes a hello.map JSON file next to hello.s. The map records which emitted assembly lines came from which PHP source lines and columns.

If you want to compare elephc against the PHP interpreter and equivalent C fixtures, see the benchmark suite.

Next steps