nxp / math-executor
简单的数学表达式计算器
Requires
- php: >=8.0 <8.4
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.8
- phpstan/phpstan: ^1.9
- phpunit/phpunit: >=9.0
This package is auto-updated.
Last update: 2024-09-10 13:59:29 UTC
README
一个简单且可扩展的数学表达式计算器
特性
- 内置对 +, -, *, /, % 和幂 (^) 操作符的支持
- 完全支持括号 () 和数组 []
- 支持逻辑操作符 (==, !=, <, <, >=, <=, &&, ||, !)
- 内置对大多数 PHP 数学函数的支持
- 支持 BCMath 随机精度数学
- 支持可变数量的函数参数和可选函数参数
- 条件 If 逻辑
- 支持自定义操作符
- 支持自定义函数
- 支持在自定义对象上的数学运算
- 动态变量解析(延迟计算)
- 变量名长度无限制
- 支持字符串,作为函数参数或由 PHP 评估为数字
- 除以零时抛出异常,或视为零
- 一元加号和减号(例如 +3 或 -sin(12))
- 支持 π ($pi) 和欧拉数 ($e) 到 11 位小数
- 易于扩展
通过 Composer 安装
composer require nxp/math-executor
示例用法
use NXP\MathExecutor; $executor = new MathExecutor(); echo $executor->execute('1 + 2 * (2 - (4+10))^2 + sin(10)');
函数
默认函数
- abs
- acos (arccos)
- acosh
- arccos
- arccosec
- arccot
- arccotan
- arccsc (arccosec)
- arcctg (arccot, arccotan)
- arcsec
- arcsin
- arctan
- arctg
- array
- asin (arcsin)
- atan (atn, arctan, arctg)
- atan2
- atanh
- atn
- avg
- bindec
- ceil
- cos
- cosec
- cosec (csc)
- cosh
- cot
- cotan
- cotg
- csc
- ctg (cot, cotan, cotg, ctn)
- ctn
- decbin
- dechex
- decoct
- deg2rad
- exp
- expm1
- floor
- fmod
- hexdec
- hypot
- if
- intdiv
- lg
- ln
- log (ln)
- log10 (lg)
- log1p
- max
- median
- min
- octdec
- pi
- pow
- rad2deg
- round
- sec
- sin
- sinh
- sqrt
- tan (tn, tg)
- tanh
- tg
- tn
向执行器添加自定义函数
$executor->addFunction('concat', function($arg1, $arg2) {return $arg1 . $arg2;});
可选参数
$executor->addFunction('round', function($num, int $precision = 0) {return round($num, $precision);}); $executor->execute('round(17.119)'); // 17 $executor->execute('round(17.119, 2)'); // 17.12
参数数量可变
$executor->addFunction('average', function(...$args) {return array_sum($args) / count($args);}); $executor->execute('average(1,3)'); // 2 $executor->execute('average(1, 3, 4, 8)'); // 4
操作符
默认操作符:+ - * / % ^
向执行器添加自定义操作符
use NXP\Classes\Operator; $executor->addOperator(new Operator( '%', // Operator sign false, // Is right associated operator 180, // Operator priority function (&$stack) { $op2 = array_pop($stack); $op1 = array_pop($stack); $result = $op1->getValue() % $op2->getValue(); return $result; } ));
逻辑操作符
逻辑操作符(==, !=, <, <, >=, <=, &&, ||, !)受支持,但逻辑上只能返回 true(1)或 false(0)。为了利用它们,请使用内置的 if 函数
if($a > $b, $a - $b, $b - $a)
您可以将 if 函数视为如下原型
function if($condition, $returnIfTrue, $returnIfFalse)
变量
变量可以以美元符号 ($) 前缀添加以实现与 PHP 的兼容性,但这不是必需的。
默认变量
$pi = 3.14159265359
$e = 2.71828182846
您可以向执行器添加自己的变量
$executor->setVar('var1', 0.15)->setVar('var2', 0.22); echo $executor->execute("$var1 + var2");
数组也受支持(作为变量、作为函数参数或可以在用户定义的函数中返回)
$executor->setVar('monthly_salaries', [1800, 1900, 1200, 1600]); echo $executor->execute("avg(monthly_salaries) * min([1.1, 1.3])");
默认情况下,变量必须是标量值(int、float、bool 或 string)或数组。如果您想支持其他类型,请使用 setVarValidationHandler
$executor->setVarValidationHandler(function (string $name, $variable) { // allow all scalars, array and null if (is_scalar($variable) || is_array($variable) || $variable === null) { return; } // Allow variables of type DateTime, but not others if (! $variable instanceof \DateTime) { throw new MathExecutorException("Invalid variable type"); } });
您可以在运行时动态定义变量。如果一个变量计算成本高,但可能不会使用,那么您可以定义一个未定义变量处理器。它只有在变量被使用时才会被调用,而不是必须始终在初始时设置。
$calculator = new MathExecutor(); $calculator->setVarNotFoundHandler( function ($varName) { if ($varName == 'trans') { return transmogrify(); } return null; } );
浮点数BCMath支持
默认情况下,MathExecutor
使用PHP浮点数数学,但如果您需要一个固定精度,请调用useBCMath()
。精度默认为两位小数,或者传递所需的数字。警告
:函数可能返回PHP浮点数。通过在结果上执行基本数学函数,您将得到一个固定的小数位数。在独立函数前使用加号可以返回正确的小数位数。
除以零支持
默认情况下,除以零会抛出\NXP\Exception\DivisionByZeroException
异常
try { echo $executor->execute('1/0'); } catch (DivisionByZeroException $e) { echo $e->getMessage(); }
或者调用setDivisionByZeroIsZero
echo $executor->setDivisionByZeroIsZero()->execute('1/0');
如果您想要其他行为,可以重写除法运算符
$executor->addOperator("/", false, 180, function($a, $b) { if ($b == 0) { return null; } return $a / $b; }); echo $executor->execute('1/0');
字符串支持
表达式可以包含双引号或单引号字符串,它们的评估方式与PHP评估字符串为数字的方式相同。您还可以将字符串传递给函数。
echo $executor->execute("1 + '2.5' * '.5' + myFunction('category')");
要在字符串中使用反斜杠字符(\),或者在单引号字符串中使用单引号字符('),或者在双引号字符串中使用双引号字符("),必须在前面加上反斜杠字符(\)。
echo $executor->execute("countArticleSentences('My Best Article\'s Title')");
扩展MathExecutor
您可以使用MathExecutor中的公共方法添加运算符、函数和变量,但如果您需要对基本行为进行更严重的修改,扩展MathExecutor最简单的方法是在您的派生类中重新定义以下方法
- defaultOperators
- defaultFunctions
- defaultVars
这将允许您根据需要删除函数和运算符,或更简单地实现不同类型。
请注意,您可以通过添加具有相同正则表达式字符串的新运算符来替换现有的默认运算符。例如,如果您只需重新定义TokenPlus,您只需添加一个具有相同正则表达式字符串的新运算符,在这种情况下是“\+”。
文档
完整的类文档请通过PHPFUI/InstaDoc访问
未来增强
此包将继续跟踪当前支持的PHP版本。