PHP phar打包怎么用

wen PHP项目 3

本文目录导读:

PHP phar打包怎么用

  1. 基本设置和创建
  2. 使用Phar文件
  3. 高级用法
  4. 注意事项
  5. 常见命令
  6. 实际应用示例

在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应用程序,记得在开发过程中经常测试,确保所有功能都能正常工作。

抱歉,评论功能暂时关闭!