PHP 项目怎么加功能开关

wen PHP项目 3

本文目录导读:

PHP 项目怎么加功能开关

  1. 最简单的配置常量方式
  2. 数据库驱动的方式
  3. 使用配置文件 + 环境变量
  4. 使用现成的库
  5. 高级特性:百分比发布 + 用户分组
  6. 完整的集成示例
  7. 最佳实践建议

在 PHP 项目中实现功能开关(Feature Flag)有多种方式,从简单到复杂,以下是几种常见方案:

最简单的配置常量方式

// config/features.php
return [
    'new_checkout' => true,
    'dark_mode' => false,
    'beta_features' => false
];
// 使用方法
$features = require 'config/features.php';
if ($features['new_checkout']) {
    // 新结账流程
} else {
    // 旧结账流程
}

数据库驱动的方式

// 创建功能开关表
CREATE TABLE feature_flags (
    id INT PRIMARY KEY AUTO_INCREMENT,
    feature_name VARCHAR(100) UNIQUE,
    is_enabled BOOLEAN DEFAULT false,
    description VARCHAR(255),
    updated_at TIMESTAMP
);
// 封装为类
class FeatureManager {
    private $db;
    private $cache = [];
    public function __construct(PDO $db) {
        $this->db = $db;
        $this->loadFeatures();
    }
    private function loadFeatures() {
        $stmt = $this->db->query("SELECT feature_name, is_enabled FROM feature_flags");
        while ($row = $stmt->fetch()) {
            $this->cache[$row['feature_name']] = (bool)$row['is_enabled'];
        }
    }
    public function isEnabled($featureName) {
        return isset($this->cache[$featureName]) ? $this->cache[$featureName] : false;
    }
}
// 使用示例
$featureManager = new FeatureManager($pdo);
if ($featureManager->isEnabled('new_checkout')) {
    // 新功能代码
}

使用配置文件 + 环境变量

// config/features.php
return [
    'new_checkout' => getenv('FEATURE_NEW_CHECKOUT') !== false 
        ? filter_var(getenv('FEATURE_NEW_CHECKOUT'), FILTER_VALIDATE_BOOLEAN) 
        : true,
    'dark_mode' => getenv('FEATURE_DARK_MODE') !== false
        ? filter_var(getenv('FEATURE_DARK_MODE'), FILTER_VALIDATE_BOOLEAN)
        : false
];

使用现成的库

Laravel 环境

// 使用 laravel-feature-flag 包
composer require laravel-feature-flag/laravel-feature-flag
// 使用示例
use LaravelFeatureFlag\FeatureFlag;
if (FeatureFlag::isEnabled('new_checkout')) {
    // 新结账流程
}

独立库

// 使用 php-feature-flags 等库
composer require php-feature-flags/php-feature-flags
// 初始化和使用
$lookup = new RedisFeatureFlagLookup($redis);
$flags = new FeatureFlags($lookup);
if ($flags->isOn('new_checkout')) {
    // 新功能代码
}

高级特性:百分比发布 + 用户分组

class PercentFeature {
    private $featureName;
    private $percent;
    public function __construct($featureName, $percent) {
        $this->featureName = $featureName;
        $this->percent = $percent;
    }
    public function isEnabled($userId) {
        // 使用用户ID作为种子,确保同一用户始终看到同一版本
        $hash = crc32($userId . '-' . $this->featureName);
        return ($hash % 100) < $this->percent;
    }
}
// 使用示例
$newCheckout = new PercentFeature('new_checkout', 20); // 20%的用户
if ($newCheckout->isEnabled($userId)) {
    // 新结账流程(面向20%用户)
}

完整的集成示例

<?php
class FeatureFlagService {
    private $config;
    private $cache = [];
    private $db;
    public function __construct(PDO $db = null) {
        $this->db = $db;
        $this->config = require 'config/features.php';
    }
    public function isEnabled($feature, $userId = null) {
        // 检查缓存
        $cacheKey = $feature . (isset($userId) ? ":{$userId}" : '');
        if (isset($this->cache[$cacheKey])) {
            return $this->cache[$cacheKey];
        }
        $enabled = $this->checkConfig($feature); // 基础配置
        $enabled = $this->checkDatabase($feature, $enabled); // 数据库覆盖
        $enabled = $this->checkUserGroup($feature, $userId, $enabled); // 用户分组
        // 缓存结果
        $this->cache[$cacheKey] = $enabled;
        return $enabled;
    }
    private function checkConfig($feature) {
        return isset($this->config[$feature]) ? $this->config[$feature] : false;
    }
    private function checkDatabase($feature, $default) {
        // 从数据库获取配置,如果没找到则返回默认值
        return $default;
    }
    private function checkUserGroup($feature, $userId, $default) {
        // 实现百分百发布或用户分组逻辑
        return $default;
    }
}
// 使用示例
$featureFlags = new FeatureFlagService($pdo);
// 在业务代码中
if ($featureFlags->isEnabled('new_checkout', $currentUserId)) {
    // 新结账流程
} else {
    // 旧结账流程
}

最佳实践建议

  1. 默认关闭:新功能默认关闭,确保安全
  2. 易于管理:提供管理界面或配置中心
  3. 日志记录:记录功能开关的使用情况
  4. 灰度发布:支持分阶段发布(10% → 25% → 50% → 全部)
  5. 监控和回滚:实时监控功能表现,支持快速回滚

选择哪种方案取决于你的项目规模和需求:

  • 小项目使用配置文件
  • 中型项目使用数据库
  • 大型项目建议使用专业的 Feature Flag 服务(如 LaunchDarkly、Split.io)

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