本文目录导读:

在PHP项目开发中,源码保护是一个重要需求,尤其是商业项目,以下是几种常见的方案,按安全性从低到高排列:
代码混淆(Obfuscation)
基础混淆工具
// 使用 php-obfuscator 或类似工具 composer require --dev nikic/php-parser
混淆前:
<?php
function getUserInfo($userId) {
$db = new Database();
$sql = "SELECT * FROM users WHERE id = ?";
$result = $db->query($sql, [$userId]);
return $result->fetch();
}
混淆后:
<?php
function a1b2c3($x9y8) {
$z7 = new Database();
$s = "SELECT * FROM users WHERE id = ?";
$r = $z7->query($s, [$x9y8]);
return $r->fetch();
}
推荐混淆工具
- PHP Obfuscator:开源,基于AST
- YAK Pro:商业级混淆
- IonCube:最知名,但收费
编译加密(最可靠)
IonCube Encoder
最常用的PHP加密方案:
# 安装 ionCube Loader # 在php.ini中添加 zend_extension = ioncube_loader_lin_7.4.so # 加密命令 ioncube_encoder -o encoded/ --copy "source.php" project/
SourceGuardian
# 安装 SourceGuardian Loader # php.ini配置 extension = SourceGuardian.so # 加密 sg_encrypt -o encoded/ --copy project/
Zend Guard
// 使用 Zend Guard 加密后 <?php // 加密后的代码看起来像乱码 @Zend\Guard\Encoded(x9kLm2n...);
混淆器实现示例
自定义简单混淆器
<?php
class PHPObfuscator {
private $variables = [];
private $functions = [];
public function obfuscate($code) {
// 1. 提取变量名
preg_match_all('/\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $code, $matches);
$this->variables = array_unique($matches[0]);
// 2. 替换变量名
foreach ($this->variables as $var) {
$newName = '$' . $this->generateRandomName();
$code = str_replace($var, $newName, $code);
}
// 3. 压缩空格和换行
$code = preg_replace('/\s+/', ' ', $code);
// 4. 删除注释
$code = preg_replace('/\/\*.*?\*\//s', '', $code);
$code = preg_replace('/\/\/.*?(\n|$)/', '', $code);
// 5. Base64编码关键字符串
$code = $this->encodeStrings($code);
return $code;
}
private function generateRandomName() {
$chars = 'abcdefghijklmnopqrstuvwxyz';
$name = '';
for ($i = 0; $i < rand(8, 15); $i++) {
$name .= $chars[rand(0, strlen($chars) - 1)];
}
return $name;
}
private function encodeStrings($code) {
preg_match_all('/["\'](.*?)["\']/', $code, $matches);
foreach ($matches[1] as $string) {
if (strlen($string) > 3) {
$encoded = base64_encode($string);
$code = str_replace("'$string'", "base64_decode('$encoded')", $code);
}
}
return $code;
}
}
// 使用示例
$obfuscator = new PHPObfuscator();
$source = file_get_contents('source.php');
$obfuscated = $obfuscator->obfuscate($source);
file_put_contents('encrypted.php', $obfuscated);
完整保护方案
多层级加密方案
<?php
// encrypter.php - 完整加密脚本
class CodeProtector {
private $secretKey;
private $iv;
public function __construct($key) {
$this->secretKey = hash('sha256', $key, true);
$this->iv = random_bytes(16);
}
public function protectFile($sourceFile, $destFile) {
$code = file_get_contents($sourceFile);
// 第一步:基础混淆
$code = $this->basicObfuscation($code);
// 第二步:AES加密
$encrypted = openssl_encrypt(
$code,
'AES-256-CBC',
$this->secretKey,
0,
$this->iv
);
// 第三步:生成解密加载器
$loader = $this->createLoader($encrypted);
file_put_contents($destFile, $loader);
}
private function basicObfuscation($code) {
// 移除注释
$code = preg_replace('!/\*.*?\*/!s', '', $code);
$code = preg_replace('!//.*?!s', '', $code);
// Base64编码字符串
$code = preg_replace_callback(
'/[\'"](.*?)[\'"]/',
function($matches) {
if (strlen($matches[1]) > 10) {
return 'base64_decode("' . base64_encode($matches[1]) . '")';
}
return $matches[0];
},
$code
);
// 压缩空白
$code = preg_replace('/\t+/', '', $code);
$code = preg_replace('/ +/', ' ', $code);
return trim($code);
}
private function createLoader($encryptedCode) {
return '<?php
<?php
$key = base64_decode("' . base64_encode($this->secretKey) . '");
$iv = base64_decode("' . base64_encode($this->iv) . '");
$code = openssl_decrypt("' . $encryptedCode . '", "AES-256-CBC", $key, 0, $iv);
eval($code);
?>';
}
}
// 使用
$protector = new CodeProtector('your-secret-key');
$protector->protectFile('source.php', 'protected.php');
License验证系统
<?php
// license_check.php - 集成到加密文件中
class LicenseChecker {
private $licenseKey;
private $domain;
public function __construct($licenseKey, $domain) {
$this->licenseKey = $licenseKey;
$this->domain = $domain;
}
public function validate() {
$expected = md5(hash_hmac('sha256', $this->domain, 'SECRET_KEY'));
if ($this->licenseKey !== $expected) {
http_response_code(403);
die('Invalid license for this domain.');
}
return true;
}
}
// 在加密文件顶部添加
require_once 'license_check.php';
$license = new LicenseChecker('your-license-hash', $_SERVER['HTTP_HOST']);
$license->validate();
注意事项
利弊分析
// 优点 - 保护知识产权 - 防止代码盗窃 - 商业价值高 // 缺点 - 影响性能(每次运行需解密) - 调试困难 - 可能存在兼容性问题
最佳实践
<?php
// 1. 只保护核心逻辑
$coreFiles = [
'core/',
'config/',
'vendor/important/'
];
// 2. 保留开源部分
$openSource = [
'public/',
'assets/',
'views/'
];
// 3. 备份原始代码
// 重要:始终保留未加密的备份
exec('cp -r source/ backup/');
性能优化
// 使用缓存机制
class ProtectedCache {
private $cacheDir;
public function load($file) {
$cacheFile = $this->cacheDir . '/' . md5($file) . '.cache';
// 检查缓存
if (file_exists($cacheFile) && filemtime($cacheFile) > filemtime($file)) {
return file_get_contents($cacheFile);
}
// 解密并缓存
$code = $this->decrypt(file_get_contents($file));
file_put_contents($cacheFile, $code);
return $code;
}
}
推荐的组合方案
// 生产环境最佳实践 1. 使用 IonCube/SourceGuardian 进行编译加密 2. 只加密核心业务逻辑 3. 配置 License 验证 4. 开启 OpCache 提升性能 5. 保持代码库整洁,只有加密文件用于部署
完整示例项目结构
project/
├── source/ # 原始代码(仅开发者访问)
│ ├── app/
│ │ ├── controllers/
│ │ └── models/
│ └── config/
├── protected/ # 加密后的代码(部署用)
│ ├── app/
│ │ ├── controllers/
│ │ └── models/
│ └── config/
├── tools/
│ ├── encrypt.php # 加密脚本
│ └── deploy.php # 部署脚本
├── vendor/ # 开源依赖(不需要加密)
├── public/ # 静态文件
└── backup/ # 备份
注意事项提醒:
- 始终保留原始代码备份
- 测试加密代码的兼容性
- 定期更新加密工具版本
- 考虑加密代码的性能影响
- 咨询法律顾问关于知识产权保护
最安全的方式是使用商业产品如 IonCube,但对于预算有限的项目,基础的混淆加上License验证通常也是可行的方案。