如何在PHP中正确验证URI(非仅URL)的结构格式
PHP通用URI验证实现方案
PHP原生提供的parse_url()仅用于URL解析,官方明确说明不支持URI验证场景,针对非HTTP/HTTPS类的自定义URI(如content://com.example.provider/articles/?optional=queries)可通过以下方案实现验证:
方案1:基于RFC 3986正则快速验证
直接使用通用URI标准定义的正则做全量匹配,适合不需要拆分URI各字段的场景:
/** * 验证是否符合RFC 3986标准的通用URI * @param string $uri 待验证的URI字符串 * @return bool */ function validateUri(string $uri): bool { // RFC 3986标准URI匹配正则 $rfc3986Pattern = '/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/'; if (!preg_match($rfc3986Pattern, $uri, $matches)) { return false; } // 可选校验:必须存在合法scheme,可根据业务需求调整 $scheme = $matches[2] ?? ''; return preg_match('/^[a-zA-Z][a-zA-Z0-9\+\-\.]*$/', $scheme); } // 测试用例 $testUri = 'content://com.example.provider/articles/?optional=queries'; var_dump(validateUri($testUri)); // 输出 bool(true)
方案2:自定义严谨校验规则
如果需要针对特定scheme做个性化校验,可手动拆分URI各部分分别验证:
/** * 支持自定义允许scheme的严格URI校验 * @param string $uri 待验证的URI字符串 * @param array $allowedSchemes 允许的scheme列表,为空则不限制scheme类型 * @return bool */ function strictValidateUri(string $uri, array $allowedSchemes = []): bool { // 校验是否存在scheme分隔符 $schemeSplitPos = strpos($uri, ':'); if ($schemeSplitPos === false) { return false; } // 校验scheme格式 $scheme = substr($uri, 0, $schemeSplitPos); if (!preg_match('/^[a-zA-Z][a-zA-Z0-9\+\-\.]*$/', $scheme)) { return false; } // 校验scheme是否在允许范围内 if (!empty($allowedSchemes) && !in_array($scheme, $allowedSchemes)) { return false; } // 校验scheme对应内容不为空 $schemeContent = substr($uri, $schemeSplitPos + 1); return trim($schemeContent) !== ''; } // 测试:仅允许content、http、https三类scheme $testUri = 'content://com.example.provider/articles/?optional=queries'; var_dump(strictValidateUri($testUri, ['content', 'http', 'https'])); // 输出 bool(true)
如果需要对URI的路径、参数、片段等部分做更细致的校验,可基于上述逻辑扩展对应字段的校验规则即可。
内容的提问来源于stack exchange,提问作者Amitoj
相关产品推荐
相关产品推荐

