TypePHP 编译器 https://swoole.com/aot/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

475 lines
8.8 KiB

# PHP AOT 编译器编译模式详解
## 📋 概述
PHP AOT 编译器支持两种编译模式,每种模式针对不同的使用场景。本文档详细说明两种模式的区别、使用方法和最佳实践。
---
## 🔹 扩展模式 (Extension Mode)
### 基本概念
扩展模式将 PHP 代码编译为 PHP 扩展文件(`.so` 或 `.dll`),可以作为标准 PHP 扩展加载到 php-fpm 中运行。
### 编译命令
```bash
php bin/compiler.php <source_dir> --mode=ext -o <output_name>
```
### 示例
```bash
# 编译 Coolify 项目
php bin/compiler.php projects/coolify/app/ --mode=ext -o coolify
# 输出文件
coolify.so # Linux
coolify.dll # Windows
```
### 安装方法
#### 1. 临时加载(测试用)
```bash
php -d extension=./coolify.so -r "echo 'Extension loaded';"
```
#### 2. 永久加载(生产环境)
```bash
# 复制扩展文件到 PHP 扩展目录
sudo cp coolify.so $(php-config --extension-dir)/
# 创建配置文件
echo "extension=coolify" | sudo tee /etc/php/8.1/mods-available/coolify.ini
# 启用扩展
sudo phpenmod coolify
# 重启 PHP-FPM
sudo systemctl restart php8.1-fpm
```
### 代码结构
**不需要 `main()` 函数**
```php
<?php
// 定义类
class UserController {
public function index() {
return "User List";
}
}
// 定义函数
function route_handler($path) {
echo "Handling: {$path}";
}
// 扩展模式下,这些代码会在被 PHP 调用时执行
// 不需要 main() 函数
```
### 使用场景
**适合**:
- Web 应用程序
- API 服务
- 需要与现有 PHP 框架集成
- 依赖 php-fpm 的生产环境
- SaaS 平台
**不适合**:
- 命令行工具
- 独立运行的服务
- 长期驻留的守护进程
### 优点
| 优点 | 说明 |
|------|------|
| 🔒 安全性 | 源码被编译,不易泄露 |
| ⚡ 性能 | 比纯 PHP 快 3-10 倍 |
| 🔄 兼容性 | 完全兼容现有 PHP 生态 |
| 📦 易部署 | 标准的 PHP 扩展安装方式 |
### 缺点
| 缺点 | 说明 |
|------|------|
| 🔧 依赖 PHP | 需要 PHP 运行时环境 |
| 🌐 仅限 Web | 主要面向 Web 场景 |
| ⚙ 配置复杂 | 需要配置 PHP 扩展 |
---
## 🔸 二进制模式 (Binary Mode)
### 基本概念
二进制模式将 PHP 代码编译为独立的可执行文件,不依赖 PHP 运行时环境。
### 编译命令
```bash
php bin/compiler.php <source_dir> -o <output_binary>
```
### 示例
```bash
# 编译 Workerman 项目
php bin/compiler.php projects/workerman/src/ -o workerman
# 输出文件
workerman # Linux 可执行文件
```
### 运行方法
```bash
# 直接运行
./workerman start
# 后台运行
./workerman start -d
# 查看状态
./workerman status
```
### 代码结构
**必须有 `main()` 函数**
```php
<?php
// 类定义
class Application {
public function run() {
echo "Application running\n";
}
}
// ✅ 必须定义 main() 函数
function main() {
$app = new Application();
$app->run();
}
// ✅ 或者带参数的 main()
function main(int $argc, array $argv) {
echo "Arguments: " . implode(', ', $argv) . "\n";
$app = new Application();
$app->run();
}
```
### main() 函数签名
#### 方式一:无参数(默认)
```php
function main() {
// 程序入口
}
```
#### 方式二:带命令行参数
```php
function main(int $argc, array $argv) {
// $argc: 参数个数
// $argv: 参数数组
echo "Script: {$argv[0]}\n";
if ($argc > 1) {
echo "Arguments: " . implode(', ', array_slice($argv, 1)) . "\n";
}
}
```
### 使用场景
**适合**:
- 命令行工具(CLI)
- 长期运行的服务(如 Workerman)
- 微服务架构中的服务节点
- 独立应用程序
- 批处理任务
**不适合**:
- Web 应用(无法在浏览器中访问)
- 需要与现有 PHP 代码混合运行的场景
### 优点
| 优点 | 说明 |
|------|------|
| 🚀 零依赖 | 无需安装 PHP |
| 📦 易分发 | 单个可执行文件 |
| 🔐 安全性 | 完全编译为机器码 |
| ⚡ 高性能 | 优化的原生代码 |
### 缺点
| 缺点 | 说明 |
|------|------|
| 🖥 平台相关 | 需要为不同系统编译 |
| 🔄 更新复杂 | 需要重新编译和替换 |
| 🌐 不支持 Web | 无法在 php-fpm 中使用 |
---
## 📊 模式对比
### 详细对比表
| 特性 | 扩展模式 (`--mode=ext`) | 二进制模式 (默认) |
|------|---------------------|------------------|
| **输出格式** | `.so` / `.dll` | 可执行文件 |
| **运行环境** | php-fpm / CLI | 独立运行 |
| **PHP 依赖** | ✅ 需要 | ❌ 不需要 |
| **main() 函数** | ❌ 不需要 | ✅ 必须 |
| **Web 访问** | ✅ 支持 | ❌ 不支持 |
| **CLI 运行** | ✅ 支持 | ✅ 支持 |
| **部署难度** | 中等 | 简单 |
| **性能提升** | 3-10 倍 | 5-20 倍 |
| **代码保护** | 中等 | 完全 |
| **适用场景** | Web 应用 | CLI 工具/服务 |
### 选择建议
```
需要运行在 Web 环境?
├─ 是 → 选择扩展模式
└─ 否 → 需要 main() 函数吗?
├─ 是 → 选择二进制模式
└─ 是 → 选择扩展模式
```
---
## 🎯 实战示例
### 示例一:Web API(扩展模式)
**项目结构**:
```
api-project/
├── src/
│ ├── Controllers/
│ │ └── UserController.php
│ ├── Routes.php
│ └── index.php
```
**UserController.php**:
```php
<?php
namespace App\Controllers;
class UserController {
public function list() {
return [
['id' => 1, 'name' => 'Alice'],
['id' => 2, 'name' => 'Bob'],
];
}
}
```
**index.php**:
```php
<?php
// 扩展模式:不需要 main()
use App\Controllers\UserController;
$controller = new UserController();
$data = $controller->list();
header('Content-Type: application/json');
echo json_encode($data);
```
**编译**:
```bash
php bin/compiler.php api-project/src/ --mode=ext -o api_extension
```
**使用**:
```bash
# 在 php-fpm 中作为扩展加载
# 通过 Web 服务器访问
```
---
### 示例二:CLI 工具(二进制模式)
**项目结构**:
```
cli-tool/
├── src/
│ ├── Command.php
│ └── main.php
```
**Command.php**:
```php
<?php
class Command {
public function execute($args) {
echo "Executing with args: " . implode(' ', $args) . "\n";
}
}
```
**main.php**:
```php
<?php
// 二进制模式:必须有 main()
function main(int $argc, array $argv) {
$command = new Command();
$command->execute(array_slice($argv, 1));
}
```
**编译**:
```bash
php bin/compiler.php cli-tool/src/ -o mytool
```
**使用**:
```bash
./mytool arg1 arg2 arg3
```
---
## 💡 最佳实践
### 扩展模式
1. **命名空间**: 使用唯一的命名空间避免冲突
```php
namespace MyProject\Api;
```
2. **初始化**: 提供扩展初始化函数
```php
function init_extension() {
// 初始化逻辑
}
```
3. **配置**: 支持通过 php.ini 配置
```php
ini_set('my_extension.enabled', '1');
```
### 二进制模式
1. **错误处理**: 在 main() 中处理全局异常
```php
function main() {
try {
// 主逻辑
} catch (Throwable $e) {
fwrite(STDERR, $e->getMessage());
exit(1);
}
}
```
2. **信号处理**: 处理系统信号
```php
function main() {
pcntl_signal(SIGTERM, function() {
echo "Shutting down...\n";
exit(0);
});
// 主循环
}
```
3. **日志记录**: 实现日志功能
```php
function log_message($level, $message) {
$timestamp = date('Y-m-d H:i:s');
echo "[{$timestamp}] [{$level}] {$message}\n";
}
```
---
## 🔍 故障排除
### 扩展模式问题
#### 问题:扩展加载失败
```bash
PHP Warning: PHP Startup: Unable to load dynamic library
```
**解决方案**:
1. 检查文件权限:`chmod 644 coolify.so`
2. 验证 PHP 版本匹配:`php -v`
3. 检查依赖:`ldd coolify.so`
#### 问题:Segmentation Fault
**解决方案**:
1. 检查代码中是否使用了不支持的语法
2. 查看错误日志:`tail -f /var/log/php/error.log`
3. 使用 gdb 调试核心转储
### 二进制模式问题
#### 问题:Permission denied
```bash
bash: ./myapp: Permission denied
```
**解决方案**:
```bash
chmod +x myapp
```
#### 问题:找不到符号
```bash
error while loading shared libraries
```
**解决方案**:
```bash
# 设置库路径
export LD_LIBRARY_PATH=/path/to/libs:$LD_LIBRARY_PATH
# 或静态编译
php bin/compiler.php src/ -o app --static
```
---
## 📚 相关文档
- [快速入门指南](QUICKSTART.md) - 开始使用 AOT 编译器
- [语法支持规范](UNSUPPORTED_SYNTAX.md) - 了解支持的语法
- [性能优化指南](PERFORMANCE.md) - 提升编译和运行性能
- [故障排除](TROUBLESHOOTING.md) - 解决常见问题
---
**最后更新**: 2024 年 3 月 18 日
**文档版本**: v1.0