PHP 怎么管理版本号

wen PHP项目 2

本文目录导读:

PHP 怎么管理版本号

  1. 基础版本号获取
  2. 应用自身版本管理
  3. 语义化版本管理(SemVer)
  4. 数据库版本管理
  5. API 版本控制
  6. 配置文件方式
  7. 最佳实践建议

在 PHP 中管理版本号通常涉及以下几个层面,我会从简单到复杂逐一说明:

基础版本号获取

当前 PHP 版本

// 获取完整版本号
echo PHP_VERSION;          // 输出: 8.2.12
echo phpversion();         // 功能相同
// 获取主要版本号
echo PHP_MAJOR_VERSION;    // 输出: 8
echo PHP_MINOR_VERSION;    // 输出: 2
echo PHP_RELEASE_VERSION;  // 输出: 12

版本比较

// 版本号比较(支持语义化版本)
if (version_compare(PHP_VERSION, '7.4.0', '>=')) {
    echo "PHP 版本 >= 7.4.0";
}
// 检查是否支持特定特性
if (version_compare(PHP_VERSION, '8.0.0', '>=')) {
    // PHP 8 特有的写法
}

应用自身版本管理

常量定义方式

class App {
    const VERSION = '1.2.3';
    const BUILD = '20231212';
    public static function getVersion() {
        return self::VERSION . '-' . self::BUILD;
    }
}
// 使用
echo App::getVersion(); // 输出: 1.2.3-20231212

Composer 方式(推荐)

composer.json 中定义版本:

{
    "name": "my/project",
    "version": "1.0.0"
}

同时在 PHP 中读取:

// 自动加载后读取
$composer = json_decode(file_get_contents('../composer.json'), true);
echo $composer['version'];

语义化版本管理(SemVer)

完整实现类

class VersionManager {
    private $major;
    private $minor;
    private $patch;
    private $preRelease; //  alpha, beta, rc
    private $buildMeta;  // 构建元数据
    public function __construct($version = '1.0.0') {
        $this->parse($version);
    }
    private function parse($version) {
        // 正则解析语义化版本
        preg_match('/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+([0-9A-Za-z.-]+))?$/', 
                  $version, $matches);
        if (count($matches) >= 4) {
            $this->major = (int)$matches[1];
            $this->minor = (int)$matches[2];
            $this->patch = (int)$matches[3];
            $this->preRelease = $matches[4] ?? null;
            $this->buildMeta = $matches[5] ?? null;
        } else {
            throw new InvalidArgumentException("无效版本号: $version");
        }
    }
    // 版本号递增
    public function bumpMajor() {
        $this->major++;
        $this->minor = 0;
        $this->patch = 0;
        $this->preRelease = null;
        return $this;
    }
    public function bumpMinor() {
        $this->minor++;
        $this->patch = 0;
        $this->preRelease = null;
        return $this;
    }
    public function bumpPatch() {
        $this->patch++;
        $this->preRelease = null;
        return $this;
    }
    // 转换为字符串
    public function toString() {
        $version = "{$this->major}.{$this->minor}.{$this->patch}";
        if ($this->preRelease) {
            $version .= "-{$this->preRelease}";
        }
        if ($this->buildMeta) {
            $version .= "+{$this->buildMeta}";
        }
        return $version;
    }
    // 比较版本
    public function compareTo(VersionManager $other) {
        return version_compare($this->toString(), $other->toString());
    }
}
// 使用示例
$version = new VersionManager('1.2.3');
$version->bumpMinor();
echo $version->toString(); // 输出: 1.3.0
$v1 = new VersionManager('2.0.0-alpha');
$v2 = new VersionManager('2.0.0');
echo $v1->compareTo($v2); // -1 (v1 < v2)

数据库版本管理

记录版本在数据库中

class DatabaseVersionManager {
    private $db;
    private $versionTable;
    public function __construct(PDO $db, $versionTable = 'schema_migrations') {
        $this->db = $db;
        $this->versionTable = $versionTable;
        $this->createVersionTable();
    }
    private function createVersionTable() {
        $this->db->exec("
            CREATE TABLE IF NOT EXISTS {$this->versionTable} (
                version VARCHAR(20) PRIMARY KEY,
                applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        ");
    }
    public function getCurrentVersion() {
        $stmt = $this->db->query("SELECT MAX(version) FROM {$this->versionTable}");
        return $stmt->fetchColumn() ?: '0.0.0';
    }
    public function migrateTo($targetVersion) {
        $currentVersion = $this->getCurrentVersion();
        // 获取迁移文件列表
        $migrations = $this->getMigrationFiles();
        foreach ($migrations as $file) {
            $version = pathinfo($file, PATHINFO_FILENAME);
            if (version_compare($version, $currentVersion, '>') && 
                version_compare($version, $targetVersion, '<=')) {
                $this->runMigration($file);
                $this->recordVersion($version);
                echo "已执行迁移: $version\n";
            }
        }
    }
    private function runMigration($file) {
        // 执行迁移文件
        $sql = file_get_contents($file);
        $this->db->exec($sql);
    }
    private function recordVersion($version) {
        $stmt = $this->db->prepare(
            "INSERT INTO {$this->versionTable} (version) VALUES (?)"
        );
        $stmt->execute([$version]);
    }
    private function getMigrationFiles() {
        $migrationDir = __DIR__ . '/migrations';
        return glob($migrationDir . '/*.sql');
    }
}

API 版本控制

REST API 版本管理

class ApiVersionManager {
    private $supportedVersions = ['v1', 'v2', 'v3'];
    private $defaultVersion = 'v1';
    public function detectVersion() {
        // 从请求头获取
        $header = $_SERVER['HTTP_ACCEPT'] ?? '';
        if (preg_match('/application\/vnd\.myapi\.(v\d+)\+json/', $header, $matches)) {
            return $this->validateVersion($matches[1]);
        }
        // 从 URL 获取
        $path = $_SERVER['REQUEST_URI'] ?? '';
        if (preg_match('/\/api\/(v\d+)\//', $path, $matches)) {
            return $this->validateVersion($matches[1]);
        }
        return $this->defaultVersion;
    }
    private function validateVersion($version) {
        if (in_array($version, $this->supportedVersions)) {
            return $version;
        }
        throw new HttpException(400, "不支持的 API 版本: $version");
    }
    public function routeToVersion($routes) {
        $version = $this->detectVersion();
        if (!isset($routes[$version])) {
            throw new HttpException(404, "版本 $version 不存在");
        }
        return $routes[$version];
    }
}

配置文件方式

config/version.php

return [
    'version' => '1.0.0',
    'build' => '20231212.1430',
    'released_at' => '2023-12-12 14:30:00',
    'php_minimum' => '7.4.0',
    'dependencies' => [
        'laravel/framework' => '^8.0',
        'guzzlehttp/guzzle' => '^7.0'
    ],
    'environment' => [
        'min_php_extensions' => ['pdo', 'mbstring', 'curl'],
    ]
];
class Application {
    private $config;
    public function __construct() {
        $this->config = include('config/version.php');
        $this->checkEnvironment();
    }
    private function checkEnvironment() {
        if (version_compare(PHP_VERSION, $this->config['php_minimum'], '<')) {
            throw new RuntimeException(
                "需要 PHP {$this->config['php_minimum']} 或更高版本,当前是 " . PHP_VERSION
            );
        }
        foreach ($this->config['environment']['min_php_extensions'] as $extension) {
            if (!extension_loaded($extension)) {
                throw new RuntimeException("缺少 PHP 扩展: $extension");
            }
        }
    }
    public function getVersion() {
        return [
            'version' => $this->config['version'],
            'environment' => PHP_VERSION
        ];
    }
}

最佳实践建议

  1. 使用语义化版本 (SemVer):始终保持 MAJOR.MINOR.PATCH 格式
  2. 自动化版本管理:使用 Composer 或环境变量
  3. 版本日志:维护 CHANGELOG.md
  4. 兼容性检测:上线前检查环境版本
  5. API 版本策略:URL 路径或 Accept Header
  6. 数据库迁移:记录每次 schema 变更版本

这些方法可以根据项目需求组合使用,对于大型应用,建议使用 Composer 管理依赖版本,并结合 Git tag 管理发布版本。

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