A PHP interpreter written in Rust, implementing a subset of PHP 8.x features.
This is an early-stage implementation that demonstrates the core architecture of a PHP interpreter. The project successfully implements:
- ✅ Lexical analysis (tokenization)
- ✅ Syntax analysis (parsing to AST)
- ✅ Compilation (AST to bytecode/opcodes)
- ✅ Virtual machine execution engine
- ✅ Basic type system (Zval)
- ✅ Extension system architecture
- ✅ CLI SAPI
- ✅ Conditional statements:
if,else,elseif - ✅ Loops:
while,for,foreachwith full support - ✅ Loop control:
breakandcontinuestatements
- ✅ Variables: Declaration and assignment (
$x = 10;) - ✅ Integers and floats: Full arithmetic support
- ✅ Strings: Literals and concatenation (
.operator) - ✅ Booleans:
true,falsewith logical operations - ✅ Null:
nulltype - ✅ Arrays: Indexed and associative arrays with full manipulation
- ✅ Arithmetic:
+,-,*,/,% - ✅ Comparison:
<,>,<=,>=,==,!=,===,!== - ✅ Logical:
&&,||,! - ✅ String:
.(concatenation)
- ✅ User-defined functions: Declaration, parameters, return values
- ✅ Function calls: With argument passing
- ✅ Anonymous functions/Closures:
function($x) use ($y) { ... } - ✅ Arrow functions:
fn($x) => $x * 2(PHP 7.4+) - ✅ Variable capture:
use()clause with value semantics, auto-capture in arrow functions - ✅ Built-in functions:
- Array:
count,array_push,array_pop,in_array,array_merge,array_keys,array_values,array_sum,array_reverse,array_map,array_filter,array_reduce - String:
strlen,substr,str_replace,strtoupper,strtolower,trim,explode,implode - Math:
abs,max,min,pow
- Array:
- ✅ Classes: Definition with properties and methods
- ✅ Objects: Instantiation with
new - ✅ Constructors:
__constructmethod - ✅ Property access:
$obj->property - ✅ Method calls:
$obj->method() - ✅ Inheritance: Single inheritance with
extends - ✅ Visibility:
public,private,protectedmodifiers - ✅ Static members: Static properties and methods
- ✅ Abstract classes: Cannot be instantiated, can have abstract methods
- ✅ Interfaces: Define method contracts
- ✅ Traits: Method and property reuse across classes
- ✅ Type declarations: Parameter, return, and property types with nullable/union support
- ✅ try/catch/finally: Full exception handling blocks
- ✅ throw: Throw exception objects
- ✅ Exception class: Built-in Exception with getMessage()/getCode()
- ✅ Custom exceptions: User-defined exception classes extending Exception
- ✅ Multi-catch:
catch (TypeError | ValueError $e) - ✅ Stack unwinding: Exceptions propagate across function calls
- ✅ Output:
echostatement with multiple expressions
- ✅ include/require:
include,include_once,require,require_once - ✅ Runtime inclusion: Full pipeline (lex → parse → compile → execute) at runtime
- ✅ Once tracking:
include_once/require_onceskip already-loaded files - ✅ Shared scope: Included files share the caller's variable scope
- ✅ Path resolution: Relative paths resolved from current script's directory
- ✅ Namespace declarations:
namespace App\Models; - ✅ Use imports:
use App\Models\User; - ✅ Aliasing:
use App\Models\User as UserModel; - ✅ Qualified names:
new App\Models\User()in expressions - ✅ Global fallback: Built-in functions/classes accessible from any namespace
- ✅ Single-line:
//,# - ✅ Multi-line:
/* */
The interpreter follows the classic compilation pipeline:
PHP Source → Lexer → Tokens → Parser → AST → Compiler → Opcodes → VM → Execution
src/zend/lexer/: Tokenizes PHP source codesrc/zend/parser/: Parses tokens into Abstract Syntax Treesrc/zend/ast/: AST node definitionssrc/zend/compiler/: Compiles AST to bytecode (opcodes)- Loop context tracking for break/continue
- Jump target patching
src/zend/vm/: Virtual machine that executes opcodesvm.rs: Main VM execution engine (1122 lines)operations.rs: Generic arithmetic operationsbuiltins/: Modular builtin function implementationmod.rs: Central dispatcherarrays.rs: Array functionsstrings.rs: String functionsmath.rs: Math functions
src/zend/types/: Zval and PHP type systemsrc/error/: Error handling with line number trackingsrc/ext/: Extension systemsrc/sapi/: Server API layer
Requires Rust 1.70 or later.
# Build the project
cargo build
# Or use make
make build# Run a PHP script
cargo run <script.php>
# Or use make
make run FILE=<script.php>RPHP includes a comprehensive test suite:
# Run all tests
./run_tests.sh
# Or use make
make test
# Run a single test
cargo run tests/fixtures/04_if_true.phpCurrent test status: 68/68 passing (100%)
✅ All features tested and working:
- Basic arithmetic and expressions
- Conditional statements (if/else/elseif)
- All comparison and logical operators
- While, for, and foreach loops
- Break and continue statements
- String operations and concatenation
- Arrays (indexed and associative)
- Array manipulation functions
- Higher-order array functions (map, filter, reduce)
- User-defined functions with parameters and returns
- Classes with inheritance
- Object properties and methods
- Constructors
- Static properties and methods
- Type declarations
- Parameter types
- Return types
- Property types
- Nullable types
- Union types
- Abstract classes and interfaces
- Abstract class declarations
- Abstract method declarations
- Interface definitions
- Class implements interface
- Runtime checks for abstract class instantiation
- Traits
- Trait declarations with methods and properties
- Class uses one or multiple traits
- Trait method/property flattening at compile time
- Class overrides trait methods
- Trait methods override parent class methods
- Closures and anonymous functions (NEW)
- Traditional anonymous functions with
function() {} - Arrow functions with
fn() => - Variable capture with
use()clause - Auto-capture in arrow functions
- Closures as callbacks to built-in functions
- Higher-order functions (functions returning closures)
- Traditional anonymous functions with
- Exception handling
- try/catch/finally blocks
- throw statements
- Built-in Exception class
- Custom exception classes with inheritance
- Multi-catch with | operator
- Stack unwinding across function calls
- Built-in functions (21 functions across arrays, strings, math)
- Include/Require
- Basic file inclusion with functions and classes
- require_once deduplication
- Shared variable scope between files
- Namespaces
- Namespace-qualified class instantiation
- Use imports with alias support
- Global fallback for built-in functions
See tests/README.md for detailed test documentation.
<?php
$x = 10;
$y = 20;
$z = $x + $y;
echo $z; // Output: 30$ cargo run test.php
30<?php
$x = 15;
if ($x > 10) {
echo 100;
} else {
echo 200;
}
// Output: 100<?php
// Break example
for ($i = 0; $i < 10; $i = $i + 1) {
if ($i == 5) {
break; // Exit loop at 5
}
echo $i;
}
// Output: 01234
// Continue example
for ($i = 0; $i < 5; $i = $i + 1) {
if ($i == 2) {
continue; // Skip iteration 2
}
echo $i;
}
// Output: 0134<?php
$arr = [1, 2, 3, 4, 5];
echo count($arr); // Output: 5
function double($x) {
return $x * 2;
}
$result = array_map("double", $arr);
foreach ($result as $val) {
echo $val; // Output: 246810
}<?php
class Animal {
public $name;
public function __construct($name) {
$this->name = $name;
}
public function speak() {
echo $this->name;
}
}
class Dog extends Animal {
public function bark() {
echo "Woof";
}
}
$dog = new Dog("Buddy");
$dog->speak(); // Output: Buddy
$dog->bark(); // Output: Woof<?php
// Parameter and return type declarations
function add(int $a, int $b): int {
return $a + $b;
}
// Nullable types
function greet(?string $name): string {
if ($name === null) {
return "Hello, Guest!";
}
return "Hello, " . $name;
}
// Union types (PHP 8.0+)
function process(int|float|string $value): string {
return "Value: " . $value;
}
// Property type declarations
class User {
public string $name;
public int $age;
private ?string $email = null;
public function __construct(string $name, int $age) {
$this->name = $name;
$this->age = $age;
}
public function getInfo(): string {
return $this->name . " is " . $this->age;
}
}
$user = new User("Alice", 30);
echo $user->getInfo(); // Output: Alice is 30See docs/plans/2026-02-27-rphp-design.md for detailed design documentation.
- ✅ Basic lexer, parser, compiler, VM
- ✅ Variables, arithmetic, and type system
- ✅ Control flow (if/else)
- ✅ Loops (while, for, foreach)
- ✅ Break and continue statements
- ✅ Functions with parameters and returns
- ✅ Arrays (indexed and associative)
- ✅ String operations
- ✅ Classes, objects, inheritance
- ✅ 21 built-in functions
- ✅ Error reporting with line numbers
- ✅ VM refactoring for maintainability
Status: All 49 tests passing
- ✅ Static properties and methods (Completed)
- ✅ Type declarations (Completed)
- Parameter type declarations:
function foo(int $x, string $y) - Return type declarations:
function foo(): int - Property type declarations:
public int $age; - Nullable types:
?int,?string - Union types:
int|string,int|float - Built-in types:
int,float,string,bool,array,object,void,mixed
- Parameter type declarations:
- ✅ Abstract classes and interfaces (Completed)
- ✅ Anonymous functions and closures (Completed)
- ✅ Traits (Completed)
- ✅ Namespaces (Completed)
- ✅ use/import statements (Completed)
- ✅ include/require (Completed)
- ✅ try/catch/finally blocks
- ✅ throw statements
- ✅ Exception class hierarchy (built-in Exception + custom subclasses)
- ✅ Multi-catch support
- ✅ Stack unwinding across function/method calls
- Error to exception conversion
- Named arguments
- Union types
- Match expressions
- Enums
- Readonly properties
- Constructor property promotion
- Attributes
- File system operations (fopen, fread, fwrite, etc.)
- Network operations (curl, sockets)
- JSON support (json_encode, json_decode)
- Regular expressions (preg_match, preg_replace)
- Date/time handling (date, time, strtotime)
- Database abstraction (PDO)
- Opcode caching
- Constant folding and dead code elimination
- Inline caching for property access
- JIT compilation (experimental)
- Memory pool optimization
- CGI/FastCGI SAPI
- Web server integration (Nginx, Apache)
- Configuration system (php.ini parsing)
- Debugging support (xdebug compatibility)
- Profiling and performance monitoring
- No reference support: Variables are copied by value, not reference (no
&$var) - No variadic functions:
...$argssyntax not yet implemented - No static analysis: Type errors only detected at runtime
- Limited error context: Error messages could provide more detailed context
- No superglobals:
$_GET,$_POST,$_SERVER, etc. not available (CLI only) - Memory management: Cycle detection GC not implemented (simple reference counting only)
This is an educational/experimental project. Contributions are welcome!
MIT OR Apache-2.0
This project is inspired by the official PHP implementation (php-src) and aims to demonstrate how a programming language interpreter works using Rust's safety and performance features.