avadim / ace-calculator
具有自定义操作符、函数和变量的灵活通用计算器
Requires
- php: >=7.4
Requires (Dev)
- phpunit/phpunit: ^9.0
README
您可以使用变量计算经典数学表达式,或者您可以指定自己的计算规则、操作符或自定义函数
从NeonXP/MathExecutor (https://github.com/NeonXP/MathExecutor) 分支,但功能更加强大和改进。
跳转到
安装
|$ composer require avadim/ace-claculator
所有安装说明请见:https://packagist.org.cn/packages/avadim/ace-claculator
示例用法
require 'vendor/autoload.php'; // create the calculator $calculator = new \avadim\AceClaculator\AceClaculator(); // calculate expression print $calculator->execute('1 + 2 * (2 - (4+10))^2 + sin(10)'); // cascade execution - you can calculate a series of expressions // variable $_ has result of previous calculation print $calculator ->calc('4+10') ->calc('1 + 2 * (2 - $_)^2') // the variable $_ contains the result of the last calculation ->calc('$_ + sin(10)') ->result();
默认操作符、函数和常数
默认操作符: + - * / ^
算术函数
- abs()
- avg()
- ceil()
- exp()
- expm1()
- floor()
- fmod()
- hypot()
- intdiv()
- log()
- log10()
- log1p()
- max()
- min()
- sqrt()
- round()
三角函数
- acos()
- acosh()
- asin()
- asinh()
- atan()
- atan2()
- atanh()
- atn() (atan的别名)
- cos()
- cosh()
- deg2rad()
- degrees() (rad2deg的别名)
- rad2deg()
- radians() (deg2rad的别名)
- sin()
- sinh()
- tan()
- tanh()
- tn() (tan的别名)
默认常数
PI = 3.14159265358979323846 E = 2.7182818284590452354
您还可以使用PHP中的任何标准数学常数 - M_LOG2E, M_PI_2 等
$calculator->execute('cos(PI)'); $calculator->execute('cos(M_PI)'); // the same result
变量
您可以将自己的变量添加到执行器中并在表达式中使用它们
$calculator->setVars([ 'var1' => 0.15, 'var2' => 0.22 ]); // calculation with variables $calculator->execute('$var1 + $var2'); // calculate and assign result to $var3 $calculator->execute('$var1 + $var2', '$var3'); // assign values to variable in expression $calculator ->calc('$var3 = ($var1 + $var2)') ->calc('$var3 * 20') ->result();
多个表达式
您可以通过分号分隔在一个中执行多个表达式
$result1 = $calculator ->setVar('$var1', 0.15) ->setVar('$var2', 0.22) ->calc('$var3 = $var1 + $var2') ->calc('$var3 * 20') ->result() ; // $result2 will be equal $result1 $result2 = $calculator->execute('$var1=0.15; $var2=0.22; $var3 = $var1 + $var2; $var3 * 20');
额外操作符和函数
您可以通过方法 loadExtension()
加载带有额外操作符和函数的扩展
// load extension 'Bool' $calculator->loadExtension('Bool');
此扩展加载布尔操作符:< <= > >= == != && ||
您可以使用额外函数 if()
使用布尔操作符
print $calculator->execute('if(100+20+3 > 111, 23, 34)');
自定义函数
向执行器添加自定义函数
$calculator->addFunction('dummy', function($a) { // do something return $result; }); print $calculator->execute('dummy(123)'); // If the function takes more than 1 argument, you must specify this // New function hypotenuse() with 2 arguments $calculator->addFunction('hypotenuse', function($a, $b) { return sqrt($a^2 + $b^2); }, 2); // New function nround() // 1 - minimum number of arguments // true - used optional arguments $calculator->addFunction('nround', function($a, $b = 0) { return round($a, $b); }, 1, true); print $calculator->execute('nround(hypotenuse(3,4), 2)');
自定义操作符
添加操作符的简单方法
use avadim\AceCalculator\Token\Operator\TokenOperator; $func = function (array &$stack) { $op2 = array_pop($stack); $op1 = array_pop($stack); return $op1->getValue() % $op2->getValue(); }; $calculator->addOperator('mod', [TokenOperator::MATH_PRIORITY_DIVIDE, $func]); echo $calculator->execute('286 mod 100');
使用指定类添加操作符的另一种方法。创建自定义操作符的类
<?php use avadim\AceCalculator\Generic\AbstractToken; use avadim\AceCalculator\Generic\AbstractTokenOperator; use avadim\AceCalculator\Token\TokenScalarNumber; class TokenOperatorModulus extends AbstractTokenOperator { protected static $pattern = 'mod'; /** * Priority of this operator, more value is more priority * (1 equals "+" or "-", 2 equals "*" or "/", 3 equals "^") * * @return int */ public function getPriority() { return 3; } /** * Association of this operator (self::LEFT_ASSOC or self::RIGHT_ASSOC) * @return string */ public function getAssociation() { return self::LEFT_ASSOC; } /** * Execution of this operator * @param AbstractToken[] $stack Stack of tokens * * @return TokenScalarNumber */ public function execute(&$stack) { $op2 = array_pop($stack); $op1 = array_pop($stack); $result = $op1->getValue() % $op2->getValue(); return new TokenScalarNumber($result); } }
并将该类添加到执行器中
$calculator = new avadim\AceClaculator\AceClaculator(); $calculator->addOperator('mod', \TokenOperatorModulus::class); echo $calculator->execute('286 mod 100');
标识符的解析
标识符 - 以字母开头,由字母和数字的序列组成。您可以在计算中指定如何解析它们
$calculator->setIdentifiers([ 'ONE' => 1, 'YEAR' => function($identifier) { return date('Y'); }, ]); $calculator->execute('YEAR + ONE');
非数值
非数值值将在算术操作中引起警告。但是,您可以设置一个特殊选项来避免这种情况。
$calculator = new avadim\AceCalculator\AceCalculator(); // calc expression with variable $calculator->setVar('$x', null); // There will be a warning in the next line $calculator->execute('$x * 12'); $calculator->setOption('non_numeric', true); // And now there will be no warning $calculator->execute('$x * 12');
错误处理器
除以零
通常除以零会抛出 DivisionByZeroException
。但您可以重新定义此行为
$s = '10/0'; $calculator->setDivisionByZeroHandler(static function($a, $b) { // $a and $b - the first and second operands return 0; }); echo $calculator->execute($s);
未知标识符
通常未知标识符会抛出 UnknownIdentifier
。但您可以重新定义此行为
$calculator->setIdentifiers([ 'ONE' => 1, 'TWO' => 2, ]); // Will throw an exception echo $calculator->execute('THREE'); $calculator->setUnknownIdentifierHandler(static function($identifier) { return $identifier; }); // Returns name of identifier as string echo $calculator->execute('THREE'); $calculator->setUnknownIdentifierHandler(static function($identifier) use ($calculator) { return $calculator->execute('ONE + TWO'); }); // Returns result of expression ONE + TWO echo $calculator->execute('THREE');
未知变量
通常未知标识符会抛出 UnknownIdentifier
。但您可以重新定义此行为
$calculator = new avadim\AceCalculator\AceCalculator(); // Will throw an exception $calculator->execute('$a * 4'); // Now any undefined variables will be interpreted as 0 $calculator->setUnknownVariableHandler(static function($variable) { return 0; }); $calculator->execute('$a * 4');
支持AceCalculator
如果您觉得这个包有用,您只需在Github上给我一个星标:)