本文目录导读:

在PHP中使用Phar打包应用程序是一个很好的方式,可以创建自包含的可执行PHP文件,以下是详细的使用方法:
基本设置和创建
创建Phar文件的配置
<?php
// create_phar.php
// 确保Phar模块已启用
if (!extension_loaded('phar')) {
die('Phar扩展未启用');
}
// 关闭phar.readonly(在命令行下)
// 注意:需要在php.ini中设置 phar.readonly = 0
// 或者在命令行使用 -d phar.readonly=0
try {
// 设置phar文件的路径
$pharFile = 'myapp.phar';
// 如果文件已存在,先删除
if (file_exists($pharFile)) {
unlink($pharFile);
}
// 创建一个新的phar文件
$phar = new Phar($pharFile);
// 开始缓冲写入
$phar->startBuffering();
// 设置默认的启动文件(stub)
$defaultStub = $phar->createDefaultStub('index.php', 'cli.php');
// 将一个目录添加到phar中
// 第二个参数是phar内的相对路径
$phar->buildFromDirectory(__DIR__ . '/app');
// 添加单个文件
$phar->addFile('config/config.php', 'config/config.php');
// 可以设置phar的元数据
$phar->setMetadata([
'version' => '1.0.0',
'author' => 'Your Name',
'created' => date('Y-m-d H:i:s')
]);
// 压缩文件
$phar->compressFiles(Phar::GZ);
// 设置自定义的stub(可选)
// $phar->setStub($defaultStub);
// 或者自定义stub
$customStub = "#!/usr/bin/env php\n<?php\nPhar::mapPhar('myapp.phar');\nrequire 'phar://myapp.phar/index.php';\n__HALT_COMPILER(); ?>";
$phar->setStub($customStub);
// 结束缓冲
$phar->stopBuffering();
echo "Phar文件创建成功: {$pharFile}\n";
} catch (Exception $e) {
echo "创建失败: " . $e->getMessage() . "\n";
}
示例项目结构
myapp/
├── create_phar.php
├── index.php # Web入口
├── cli.php # CLI入口
├── app/
│ ├── controllers/
│ ├── models/
│ └── views/
├── config/
│ └── config.php
└── vendor/ # 第三方库
使用Phar文件
在命令行中执行
# 执行phar文件
php myapp.phar
# 或者如果你是直接运行的
./myapp.phar
# 查看phar内容
php -r "echo file_get_contents('phar://myapp.phar/index.php');"
# 列出phar文件内容
php -r "
$phar = new Phar('myapp.phar');
foreach (new RecursiveIteratorIterator($phar) as $file) {
echo $file->getFileName() . PHP_EOL;
}
"
在PHP代码中使用
<?php
// 加载phar文件
require 'myapp.phar';
// 或者使用stream wrapper
$content = file_get_contents('phar://myapp.phar/index.php');
// 包含phar中的特定文件
include 'phar://myapp.phar/config/config.php';
高级用法
完整的打包脚本示例
<?php
// package.php
class PharBuilder {
private $pharFile;
private $sourceDir;
private $mainEntry;
public function __construct($pharFile, $sourceDir, $mainEntry = 'index.php') {
$this->pharFile = $pharFile;
$this->sourceDir = $sourceDir;
$this->mainEntry = $mainEntry;
}
public function build() {
// 检查当前是否在web环境中
if (!in_array('phar', stream_get_wrappers())) {
throw new Exception('Phar wrapper不可用');
}
// 检查是否允许写入
if (ini_get('phar.readonly') == '1') {
throw new Exception('请在php.ini中设置 phar.readonly = 0');
}
if (file_exists($this->pharFile)) {
unlink($this->pharFile);
}
$phar = new Phar($this->pharFile);
$phar->startBuffering();
// 添加所有文件
$phar->buildFromDirectory($this->sourceDir);
// 创建默认的stub为web和cli
$phar->setStub(
$phar->createDefaultStub('web/index.php', 'cli.php')
);
// 可选:压缩文件
if ($this->compress()) {
$phar->compressFiles(Phar::GZ);
}
// 签名设置
$phar->setSignatureAlgorithm(Phar::SHA256);
$phar->stopBuffering();
echo "Phar文件已创建: " . $this->pharFile . "\n";
echo "文件大小: " . filesize($this->pharFile) . " bytes\n";
}
private function compress() {
// 可以在这里添加压缩选项配置
return true;
}
}
// 使用示例
try {
$builder = new PharBuilder(
'myapp.phar',
__DIR__ . '/project',
'index.php'
);
$builder->build();
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
}
注意事项
php.ini配置
; 关闭只读限制(开发环境) phar.readonly = 0 ; 启用phar支持 phar.require_hash = On ; 压缩支持 phar.cache_list =
性能优化
<?php
// 在phar中优化加载性能
// 1. 使用 __HALT_COMPILER() 正确终止
$stub = "<?php\nPhar::mapPhar('optimized.phar');\ninclude 'phar://optimized.phar/index.php';\n__HALT_COMPILER(); ?>";
$phar->setStub($stub);
// 2. 压缩文件减小体积
$phar->compressFiles(Phar::GZ);
// 3. 使用opcache
// 在php.ini中设置:
// opcache.enable_cli=1
// opcache.validate_timestamps=0
// 4. 将常用文件放在phar的前部
$phar->addFile('bootstrap.php');
$phar->addFile('core/Application.php');
// 按使用频率排序
常见命令
# 创建phar文件
php create_phar.php
# 运行phar文件
php myapp.phar
# 查看phar内容
php -r "var_dump(new Phar('myapp.phar'));"
# 验证phar文件
php -r "
try {
$phar = new Phar('myapp.phar');
$phar->getSignature();
echo 'Phar文件有效';
} catch (Exception $e) {
echo 'Phar文件无效: ' . $e->getMessage();
}
"
# 列出所有文件
php -r "
$phar = new Phar('myapp.phar');
foreach ($phar as $file) {
echo $file->getPathname() . PHP_EOL;
}
"
实际应用示例
<?php
// 创建一个包含多个模块的完整应用程序phar
// 项目结构
$projectFiles = [
'config/database.php',
'app/core/Autoloader.php',
'app/controllers/UserController.php',
'app/models/User.php',
'app/views/user/list.php',
'vendor/autoload.php',
'vendor/composer/autoload_real.php'
];
$phar = new Phar('cms.phar');
$phar->startBuffering();
// 从目录添加
$phar->buildFromDirectory(__DIR__ . '/project');
// 设置自动加载处理
$autoloadStub = function() {
spl_autoload_register(function ($class) {
$prefix = 'App\\';
$base_dir = 'phar://cms.phar/src/';
if (strpos($class, $prefix) === 0) {
$class = substr($class, strlen($prefix));
$file = $base_dir . str_replace('\\', '/', $class) . '.php';
if (file_exists($file)) {
require $file;
}
}
});
};
// 创建引导文件
$bootstrap = '<?php' . PHP_EOL;
$bootstrap .= 'spl_autoload_register(function($class) {' . PHP_EOL;
$bootstrap .= ' $prefix = "App\\\\";' . PHP_EOL;
$bootstrap .= ' $base_dir = "phar://cms.phar/src/";' . PHP_EOL;
$bootstrap .= ' if (strpos($class, $prefix) === 0) {' . PHP_EOL;
$bootstrap .= ' $class = substr($class, strlen($prefix));' . PHP_EOL;
$bootstrap .= ' $file = $base_dir . str_replace("\\\\", "/", $class) . ".php";' . PHP_EOL;
$bootstrap .= ' if (file_exists($file)) require $file;' . PHP_EOL;
$bootstrap .= ' }' . PHP_EOL;
$bootstrap .= '});' . PHP_EOL;
$bootstrap .= 'require "phar://cms.phar/config/database.php";' . PHP_EOL;
$bootstrap .= '// 应用程序逻辑' . PHP_EOL;
$phar->addFromString('bootstrap.php', $bootstrap);
$phar->setStub(
"#!/usr/bin/env php\n<?php\nPhar::mapPhar('cms.phar');\nrequire 'phar://cms.phar/bootstrap.php';\n__HALT_COMPILER(); ?>"
);
$phar->stopBuffering();
echo "CMS Phar创建成功!\n";
这些示例应该能帮助你开始使用Phar打包PHP应用程序,记得在开发过程中经常测试,确保所有功能都能正常工作。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播