wuwx/laravel-expression-language is a Laravel package.
It currently has 2 GitHub stars and 1.074 downloads on Packagist (latest version v4.3.0).
Install it with composer require wuwx/laravel-expression-language.
Discover more Laravel packages by wuwx
or browse all Laravel packages to compare alternatives.
Last updated
将 Symfony ExpressionLanguage 组件集成到 Laravel 的扩展包,让你可以在 Laravel 应用中安全地执行动态表达式。
array_get 辅助函数composer require wuwx/laravel-expression-language
该扩展包支持 Laravel 的自动发现功能,安装后即可使用。
如果你需要手动注册,在 config/app.php 中添加:
'providers' => [
// ...
Wuwx\LaravelExpressionLanguage\Providers\ExpressionLanguageServiceProvider::class,
],
'aliases' => [
// ...
'ExpressionLanguage' => Wuwx\LaravelExpressionLanguage\Facades\ExpressionLanguageFacade::class,
],
use ExpressionLanguage;
// 简单的数学表达式
$result = ExpressionLanguage::evaluate('1 + 1'); // 返回 2
// 使用变量
$result = ExpressionLanguage::evaluate('price * quantity', [
'price' => 100,
'quantity' => 3
]); // 返回 300
// 条件表达式
$result = ExpressionLanguage::evaluate('user.age >= 18', [
'user' => ['age' => 20]
]); // 返回 true
// 通过 app 辅助函数
$result = app('expressionLanguage')->evaluate('1 + 1');
// 通过依赖注入
class OrderController extends Controller
{
public function calculate($expressionLanguage)
{
$result = $expressionLanguage->evaluate('...');
// ...
}
}
// 数学运算
ExpressionLanguage::evaluate('10 + 5'); // 15
ExpressionLanguage::evaluate('10 - 5'); // 5
ExpressionLanguage::evaluate('10 * 5'); // 50
ExpressionLanguage::evaluate('10 / 5'); // 2
ExpressionLanguage::evaluate('10 % 3'); // 1
ExpressionLanguage::evaluate('10 ** 2'); // 100 (幂运算)
// 比较
ExpressionLanguage::evaluate('a > b', ['a' => 10, 'b' => 5]); // true
ExpressionLanguage::evaluate('a >= b', ['a' => 10, 'b' => 10]); // true
ExpressionLanguage::evaluate('a < b', ['a' => 5, 'b' => 10]); // true
ExpressionLanguage::evaluate('a <= b', ['a' => 5, 'b' => 5]); // true
ExpressionLanguage::evaluate('a == b', ['a' => 5, 'b' => 5]); // true
ExpressionLanguage::evaluate('a != b', ['a' => 5, 'b' => 3]); // true
// 逻辑运算
ExpressionLanguage::evaluate('a and b', ['a' => true, 'b' => false]); // false
ExpressionLanguage::evaluate('a or b', ['a' => true, 'b' => false]); // true
ExpressionLanguage::evaluate('not a', ['a' => false]); // true
ExpressionLanguage::evaluate('a ? b : c', ['a' => true, 'b' => 1, 'c' => 2]); // 1
ExpressionLanguage::evaluate('status == "active" ? price * 0.9 : price', [
'status' => 'active',
'price' => 100
]); // 返回 90
// 数组访问
$data = [
'user' => [
'name' => '张三',
'profile' => [
'age' => 25
]
]
];
ExpressionLanguage::evaluate('user.name', $data); // '张三'
ExpressionLanguage::evaluate('user.profile.age', $data); // 25
// 使用内置 array_get 函数
ExpressionLanguage::evaluate('array_get(user, "profile.age")', $data); // 25
ExpressionLanguage::evaluate('name ~ " " ~ surname', [
'name' => 'John',
'surname' => 'Doe'
]); // 返回 'John Doe'(字符串连接)
你可以通过直接访问 Symfony ExpressionLanguage 实例来添加自定义函数:
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
$expressionLanguage = app('expressionLanguage');
// 添加自定义函数
$expressionLanguage->expressionLanguage->addFunction(
ExpressionFunction::fromPhp('strtoupper')
);
// 现在可以在表达式中使用
$result = $expressionLanguage->evaluate('strtoupper(name)', [
'name' => 'hello'
]); // 返回 'HELLO'
对于频繁使用的表达式,建议使用缓存:
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
$cache = new ArrayAdapter();
$expressionLanguage = new ExpressionLanguage($cache);
表达式执行过程中可能会抛出异常,建议进行错误处理:
use Symfony\Component\ExpressionLanguage\SyntaxError;
try {
$result = ExpressionLanguage::evaluate('invalid syntax...');
} catch (SyntaxError $e) {
// 处理语法错误
Log::error('表达式语法错误: ' . $e->getMessage());
} catch (\Exception $e) {
// 处理其他错误
Log::error('表达式执行错误: ' . $e->getMessage());
}
// 定义业务规则
$rules = [
'discount' => 'amount > 1000 and is_vip',
'free_shipping' => 'amount > 500 or is_vip',
];
$context = [
'amount' => 1500,
'is_vip' => true,
];
foreach ($rules as $name => $expression) {
$result = ExpressionLanguage::evaluate($expression, $context);
echo "$name: " . ($result ? '适用' : '不适用') . "\n";
}
$validationRules = [
'age' => 'age >= 18 and age <= 120',
'email' => 'email matches "/^[\w.-]+@[\w.-]+\.\w+$/"',
];
$data = ['age' => 25, 'email' => '[email protected]'];
foreach ($validationRules as $field => $rule) {
$isValid = ExpressionLanguage::evaluate($rule, $data);
}
// 电商订单金额计算
$order = [
'items' => [
['price' => 100, 'quantity' => 2],
['price' => 50, 'quantity' => 1],
],
'coupon_discount' => 20,
'is_vip' => true,
];
$formula = '(sum(items, "price * quantity") - coupon_discount) * (is_vip ? 0.95 : 1)';
$total = ExpressionLanguage::evaluate($formula, $order);
运行测试套件:
composer install
vendor/bin/phpunit
| Laravel 版本 | 支持状态 | |-------------|---------| | 5.8 | 支持 | | 6.x | 支持 | | 7.x | 支持 | | 8.x | 支持 | | 9.x | 支持 | | 10.x | 支持 | | 11.x | 支持 | | 12.x | 支持 |
MIT 许可证 - 查看 LICENSE 文件了解详情。
欢迎提交 Issue 和 Pull Request!
提示: 该扩展包是对 Symfony ExpressionLanguage 的轻量级封装,更多高级用法请参考 Symfony 官方文档。