本文目录导读:

在 PHP 中进行规则测试,主要有以下几种常见方式:
单元测试(PHPUnit)
安装 PHPUnit
composer require --dev phpunit/phpunit
示例:测试业务规则
<?php
use PHPUnit\Framework\TestCase;
class DiscountRuleTest extends TestCase
{
private $discountCalculator;
protected function setUp(): void
{
$this->discountCalculator = new DiscountCalculator();
}
/** @test */
public function testVIPCustomerGets20PercentDiscount()
{
$customer = new Customer('VIP');
$order = new Order(1000);
$finalPrice = $this->discountCalculator->calculate($order, $customer);
$this->assertEquals(800, $finalPrice);
}
/** @test */
public function testNormalCustomerGetsNoDiscount()
{
$customer = new Customer('NORMAL');
$order = new Order(1000);
$finalPrice = $this->discountCalculator->calculate($order, $customer);
$this->assertEquals(1000, $finalPrice);
}
}
验证规则(Validation Rules)
使用 Laravel 验证规则
<?php
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
class UserController extends Controller
{
public function store(Request $request)
{
$rules = [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'age' => 'required|integer|min:18|max:65',
'password' => 'required|min:8|confirmed',
'role' => ['required', Rule::in(['admin', 'user', 'moderator'])],
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return response()->json([
'errors' => $validator->errors()
], 422);
}
}
}
自定义验证规则
<?php
// 自定义规则类
class ValidPhoneNumber implements Rule
{
public function passes($attribute, $value)
{
return preg_match('/^(\+86)?1[3-9]\d{9}$/', $value);
}
public function message()
{
return '手机号格式不正确';
}
}
// 使用
$rules = [
'phone' => ['required', new ValidPhoneNumber],
];
业务规则引擎测试
使用规则引擎包(如 RulerZ)
<?php
require 'vendor/autoload.php';
use RulerZ\RulerZ;
use RulerZ\Compiler\Compiler;
use RulerZ\Target\ArrayTarget;
// 定义规则
$rules = [
'user.is_active = true AND user.balance > 100',
'user.age >= 18 AND user.country IN ["CN", "US", "UK"]',
'user.is_vip OR user.purchase_count > 10'
];
// 创建引擎
$rulerz = new RulerZ(
Compiler::create(),
[new ArrayTarget()]
);
// 测试数据
$users = [
['name' => '张三', 'age' => 25, 'is_active' => true, 'balance' => 500, 'country' => 'CN', 'is_vip' => false, 'purchase_count' => 5],
['name' => '李四', 'age' => 17, 'is_active' => false, 'balance' => 50, 'country' => 'US', 'is_vip' => false, 'purchase_count' => 8],
];
// 测试规则
foreach ($users as $user) {
$isEligible = $rulerz->satisfies($user, $rules[0]);
var_dump("用户 {$user['name']} 是否符合规则: " . ($isEligible ? '是' : '否'));
}
规则验证函数
<?php
class BusinessRuleValidator
{
private $rules = [];
public function addRule($name, callable $rule, $errorMessage)
{
$this->rules[$name] = [
'validator' => $rule,
'message' => $errorMessage
];
}
public function validate($data)
{
$errors = [];
foreach ($this->rules as $name => $rule) {
if (!$rule['validator']($data)) {
$errors[$name] = $rule['message'];
}
}
return $errors;
}
}
// 使用示例
$validator = new BusinessRuleValidator();
$validator->addRule(
'minimum_order',
function($order) {
return $order['amount'] >= 100;
},
'订单金额不能低于 100 元'
);
$validator->addRule(
'max_quantity',
function($order) {
return count($order['items']) <= 10;
},
'单个订单最多 10 个商品'
);
$validator->addRule(
'valid_date',
function($order) {
return strtotime($order['date']) <= time();
},
'订单日期不能在未来'
);
$order = [
'amount' => 150,
'items' => [1, 2, 3, 4],
'date' => '2024-01-15'
];
$errors = $validator->validate($order);
print_r($errors);
数据验证辅助函数
<?php
function validateEmail($email) {
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}
function validatePhone($phone) {
return preg_match('/^[0-9+\-\(\) ]{10,15}$/', $phone);
}
function validateIp($ip) {
return filter_var($ip, FILTER_VALIDATE_IP) !== false;
}
function validateUrl($url) {
return filter_var($url, FILTER_VALIDATE_URL) !== false;
}
function validateBetween($value, $min, $max) {
return $value >= $min && $value <= $max;
}
function validateIn($value, array $allowed) {
return in_array($value, $allowed, true);
}
// 测试
$email = "test@example.com";
$phone = "+86 138-0013-8000";
$userId = 25;
echo validateEmail($email) ? "邮箱有效" : "邮箱无效";
echo "<br>";
echo validatePhone($phone) ? "电话有效" : "电话无效";
echo "<br>";
echo validateBetween($userId, 18, 60) ? "年龄在范围内" : "年龄超出范围";
Web 框架中的规则测试
Symfony 表单验证
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Validation;
class UserRegistrationForm
{
/**
* @Assert\NotBlank(message="用户名不能为空")
* @Assert\Length(min=3, max=32)
*/
private $username;
/**
* @Assert\NotBlank
* @Assert\Email
*/
private $email;
/**
* @Assert\NotBlank
* @Assert\Length(min=6, max=128)
*/
private $password;
// ... getters/setters
}
$validator = Validation::createValidatorBuilder()
->enableAnnotationMapping()
->getValidator();
$user = new UserRegistrationForm();
$user->setUsername('abc');
// ... 设置其他属性
$errors = $validator->validate($user);
测试建议
编写有效测试的原则
<?php
class OrderValidationTest extends TestCase
{
/** @test */
public function testOrderValidationRules()
{
$validator = new OrderValidator();
// 测试成功场景
$validData = [
'customer_name' => '张三',
'items' => ['item1', 'item2'],
'total_amount' => 150.00,
'payment_method' => 'credit_card'
];
$this->assertTrue($validator->validate($validData));
// 测试失败场景
$invalidData = [
'customer_name' => '',
'items' => [],
'total_amount' => -1,
'payment_method' => 'invalid_method'
];
$this->assertFalse($validator->validate($invalidData));
// 测试边界情况
$boundaryData = [
'customer_name' => 'A',
'items' => ['item'],
'total_amount' => 0.01,
'payment_method' => 'cash'
];
$this->assertTrue($validator->validate($boundaryData));
}
}
PHP 规则测试的核心方式:
- 单元测试:使用 PHPUnit 等框架测试业务逻辑
- 验证规则:使用内置或框架验证功能
- 规则引擎:处理复杂的业务规则
- 自定义验证器:根据需求创建专用验证工具
- Web 框架集成:使用框架提供的验证功能
选择哪种方式取决于你的具体需求:
- 简单的数据验证 → 使用验证函数
- 复杂业务逻辑 → 单元测试
- Web 表单 → 框架验证功能
- 动态规则 → 规则引擎
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播