9.4 KiB
PHP AOT Compiler Compilation Modes
📋 Overview
The PHP AOT compiler supports two compilation modes, each targeting different use cases. This document details the differences, usage, and best practices of the two modes.
🔹 Extension Mode
Basic Concepts
Extension mode compiles PHP code into a PHP extension file (.so or .dll), which can be loaded into php-fpm as a standard PHP extension.
Compilation Command
php bin/tpc.php <source_dir> --mode=ext -o <output_name>
Example
# Compile the Coolify project
php bin/tpc.php projects/coolify/app/ --mode=ext -o coolify
# Output files
coolify.so # Linux
coolify.dll # Windows
Installation
1. Temporary Loading (for testing)
php -d extension=./coolify.so -r "echo 'Extension loaded';"
2. Permanent Loading (production)
# Copy the extension file to the PHP extension directory
sudo cp coolify.so $(php-config --extension-dir)/
# Create the configuration file
echo "extension=coolify" | sudo tee /etc/php/8.1/mods-available/coolify.ini
# Enable the extension
sudo phpenmod coolify
# Restart PHP-FPM
sudo systemctl restart php8.1-fpm
Code Structure
No main() function required
<?php
// Define classes
class UserController {
public function index() {
return "User List";
}
}
// Define functions
function route_handler($path) {
echo "Handling: {$path}";
}
// In extension mode, this code runs when called by PHP
// No main() function required
Use Cases
✅ Suitable for:
- Web applications
- API services
- Integration with existing PHP frameworks
- Production environments relying on php-fpm
- SaaS platforms
❌ Not suitable for:
- Command-line tools
- Standalone services
- Long-running daemons
Advantages
| Advantage | Description |
|---|---|
| 🔒 Security | Source code is compiled, not easily leaked |
| ⚡ Performance | 3-10x faster than pure PHP |
| 🔄 Compatibility | Fully compatible with the existing PHP ecosystem |
| 📦 Easy deployment | Standard PHP extension installation |
Disadvantages
| Disadvantage | Description |
|---|---|
| 🔧 Depends on PHP | Requires a PHP runtime environment |
| 🌐 Web only | Primarily oriented toward web scenarios |
| ⚙️ Complex configuration | Requires configuring the PHP extension |
🔸 Binary Mode
Basic Concepts
Binary mode compiles PHP code into a standalone executable, independent of the PHP runtime environment.
Compilation Command
php bin/tpc.php <source_dir> -o <output_binary>
Example
# Compile the Workerman project
php bin/tpc.php projects/workerman/src/ -o workerman
# Output file
workerman # Linux executable
Running
# Run directly
./workerman start
# Run in the background
./workerman start -d
# Check status
./workerman status
Code Structure
Must have a main() function
<?php
// Class definition
class Application {
public function run() {
echo "Application running\n";
}
}
// ✅ Must define a main() function
function main() {
$app = new Application();
$app->run();
}
// ✅ Or a main() with arguments
function main(int $argc, array $argv) {
echo "Arguments: " . implode(', ', $argv) . "\n";
$app = new Application();
$app->run();
}
main() Function Signature
Approach 1: No arguments (default)
function main() {
// program entry point
}
Approach 2: With command-line arguments
function main(int $argc, array $argv) {
// $argc: number of arguments
// $argv: argument array
echo "Script: {$argv[0]}\n";
if ($argc > 1) {
echo "Arguments: " . implode(', ', array_slice($argv, 1)) . "\n";
}
}
Use Cases
✅ Suitable for:
- Command-line tools (CLI)
- Long-running services (such as Workerman)
- Service nodes in microservice architectures
- Standalone applications
- Batch processing tasks
❌ Not suitable for:
- Web applications (cannot be accessed in a browser)
- Scenarios requiring mixed execution with existing PHP code
Advantages
| Advantage | Description |
|---|---|
| 🚀 Zero dependencies | No PHP installation required |
| 📦 Easy distribution | A single executable file |
| 🔐 Security | Fully compiled to machine code |
| ⚡ High performance | Optimized native code |
Disadvantages
| Disadvantage | Description |
|---|---|
| 🖥️ Platform-dependent | Must compile separately for different systems |
| 🔄 Complex updates | Requires recompilation and replacement |
| 🌐 No web support | Cannot be used in php-fpm |
📊 Mode Comparison
Detailed Comparison Table
| Feature | Extension Mode (--mode=ext) |
Binary Mode (default) |
|---|---|---|
| Output format | .so / .dll |
Executable |
| Runtime environment | php-fpm / CLI | Standalone |
| PHP dependency | ✅ Required | ❌ Not required |
| main() function | ❌ Not required | ✅ Required |
| Web access | ✅ Supported | ❌ Not supported |
| CLI execution | ✅ Supported | ✅ Supported |
| Deployment difficulty | Medium | Easy |
| Performance gain | 3-10x | 5-20x |
| Code protection | Medium | Full |
| Applicable scenarios | Web applications | CLI tools / services |
Selection Guidance
Need to run in a web environment?
├─ Yes → choose Extension mode
└─ No → need a main() function?
├─ Yes → choose Binary mode
└─ Yes → choose Extension mode
🎯 Practical Examples
Example 1: Web API (Extension Mode)
Project structure:
api-project/
├── src/
│ ├── Controllers/
│ │ └── UserController.php
│ ├── Routes.php
│ └── index.php
UserController.php:
<?php
namespace App\Controllers;
class UserController {
public function list() {
return [
['id' => 1, 'name' => 'Alice'],
['id' => 2, 'name' => 'Bob'],
];
}
}
index.php:
<?php
// Extension mode: no main() required
use App\Controllers\UserController;
$controller = new UserController();
$data = $controller->list();
header('Content-Type: application/json');
echo json_encode($data);
Compile:
php bin/tpc.php api-project/src/ --mode=ext -o api_extension
Use:
# Load as an extension in php-fpm
# Access through the web server
Example 2: CLI Tool (Binary Mode)
Project structure:
cli-tool/
├── src/
│ ├── Command.php
│ └── main.php
Command.php:
<?php
class Command {
public function execute($args) {
echo "Executing with args: " . implode(' ', $args) . "\n";
}
}
main.php:
<?php
// Binary mode: must have main()
function main(int $argc, array $argv) {
$command = new Command();
$command->execute(array_slice($argv, 1));
}
Compile:
php bin/tpc.php cli-tool/src/ -o mytool
Use:
./mytool arg1 arg2 arg3
💡 Best Practices
Extension Mode
-
Namespaces: use unique namespaces to avoid conflicts
namespace MyProject\Api; -
Initialization: provide an extension initialization function
function init_extension() { // initialization logic } -
Configuration: support configuration via php.ini
ini_set('my_extension.enabled', '1');
Binary Mode
-
Error handling: handle global exceptions in main()
function main() { try { // main logic } catch (Throwable $e) { fwrite(STDERR, $e->getMessage()); exit(1); } } -
Signal handling: handle system signals
function main() { pcntl_signal(SIGTERM, function() { echo "Shutting down...\n"; exit(0); }); // main loop } -
Logging: implement logging functionality
function log_message($level, $message) { $timestamp = date('Y-m-d H:i:s'); echo "[{$timestamp}] [{$level}] {$message}\n"; }
🔍 Troubleshooting
Extension Mode Issues
Issue: Extension fails to load
PHP Warning: PHP Startup: Unable to load dynamic library
Solutions:
- Check file permissions:
chmod 644 coolify.so - Verify PHP version match:
php -v - Check dependencies:
ldd coolify.so
Issue: Segmentation Fault
Solutions:
- Check for unsupported syntax in the code
- Check the error log:
tail -f /var/log/php/error.log - Use gdb to debug the core dump
Binary Mode Issues
Issue: Permission denied
bash: ./myapp: Permission denied
Solution:
chmod +x myapp
Issue: Symbols not found
error while loading shared libraries
Solution:
# Set the library path
export LD_LIBRARY_PATH=/path/to/libs:$LD_LIBRARY_PATH
# Check the actual link path and dependencies
ldd ./app
📚 Related Documents
- Quick Start Guide - Get started with the AOT compiler
- Compatibility Checklist - Understand current limitations
- Build Speed Research - Optimize the compilation pipeline
- Compatibility Classification - Determine the nature and resolution direction of limitations
Last updated: March 18, 2024
Document version: v1.0