Yii2中校验语义化版本需三步:先用严格正则(含^$锚点)校验格式,再写public validateSemVer方法做语义逻辑检查(如禁用0.x生产版),最后可选composer/semver库解析约束。

在 Yii2 项目中校验用户输入或配置项中的版本号(如 v1.2.3、2.0.0-beta、0.9.10-alpha.2)是否符合语义化版本规范,需避免仅用正则粗筛导致误放或误拦,尤其要区分预发布段和构建元数据的合法性。
用正则验证器匹配标准语义化版本
在模型 rules() 方法中直接使用 match 验证器,配合严格语义化版本正则(SemVer 2.0.0 兼容):
第一步:复制以下正则到规则中:[['version'], 'match', 'pattern' => '/^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/']
这个正则能准确识别主版本、次版本、修订号,支持可选的 v 前缀、预发布标签(如 alpha.1)、构建元数据(如 +20240911),且拒绝 1.02.3 这类带前导零的非法写法。
注意:不要省略 ^ 和 $ 锚点,否则 abc1.2.3def 也会被误判为合法。
用自定义验证方法做语义级校验
当需要进一步检查版本号逻辑(例如禁止 0.x 版本用于生产环境、要求预发布段不能含 stable 字样),必须写独立验证方法:
方法一:在模型类中添加 public 方法:
public function validateSemVer($attribute, $params)
方法二:提取版本各段并校验:
先用 preg_match 解析出主/次/修订号、预发布、构建元数据;若匹配失败,直接 $this->addError($attribute, '版本格式不合法');;若解析成功但主版本为 0 且当前场景是 production,再加一条错误提示。
这一步必须用 public 修饰,且参数只能是 $attribute 和 $params——少一个、多一个、类型不对,Yii2 会静默跳过该验证,不报错也不生效。
复用第三方语义化版本库校验
安装 composer require composer/semver 后,在验证方法中调用其解析器:
use Composer\Semver\VersionParser;
创建 $parser = new VersionParser(); → 调用 $parser->parseConstraints($this->$attribute) 或 $parser->normalize($this->$attribute);捕获 UnexpectedValueException 并转为模型错误。
【关键前提】 必须确保 Composer 的 semver 包已正确加载,否则 new VersionParser() 会抛出 Class not found。可在控制器中先 class_exists('Composer\Semver\VersionParser') 测试。
这种方法能自动兼容所有 SemVer 2.0.0 正式语法,包括 ~1.2、^2.0.0 等约束表达式,但仅适用于需解析约束而非单纯校验字符串格式的场景。


















