Giter VIP home page Giter VIP logo

mathexecutor's Introduction

MathExecutor Tests

A simple and extensible math expressions calculator

Features:

  • Built in support for +, -, *, /, % and power (^) operators
  • Parentheses () and arrays [] are fully supported
  • Logical operators (==, !=, <, <, >=, <=, &&, ||, !)
  • Built in support for most PHP math functions
  • Support for BCMath Arbitrary Precision Math
  • Support for variable number of function parameters and optional function parameters
  • Conditional If logic
  • Support for user defined operators
  • Support for user defined functions
  • Support for math on user defined objects
  • Dynamic variable resolution (delayed computation)
  • Unlimited variable name lengths
  • String support, as function parameters or as evaluated as a number by PHP
  • Exceptions on divide by zero, or treat as zero
  • Unary Plus and Minus (e.g. +3 or -sin(12))
  • Pi ($pi) and Euler's number ($e) support to 11 decimal places
  • Easily extensible

Install via Composer:

composer require nxp/math-executor

Sample usage:

use NXP\MathExecutor;

$executor = new MathExecutor();

echo $executor->execute('1 + 2 * (2 - (4+10))^2 + sin(10)');

Functions:

Default functions:

  • 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

Add custom function to executor:

$executor->addFunction('concat', function($arg1, $arg2) {return $arg1 . $arg2;});

Optional parameters:

$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

Variable number of parameters:

$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

Operators:

Default operators: + - * / % ^

Add custom operator to executor:

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;
    }
));

Logical operators:

Logical operators (==, !=, <, <, >=, <=, &&, ||, !) are supported, but logically they can only return true (1) or false (0). In order to leverage them, use the built in if function:

if($a > $b, $a - $b, $b - $a)

You can think of the if function as prototyped like:

function if($condition, $returnIfTrue, $returnIfFalse)

Variables:

Variables can be prefixed with the dollar sign ($) for PHP compatibility, but is not required.

Default variables:

$pi = 3.14159265359
$e  = 2.71828182846

You can add your own variables to executor:

$executor->setVar('var1', 0.15)->setVar('var2', 0.22);

echo $executor->execute("$var1 + var2");

Arrays are also supported (as variables, as func params or can be returned in user defined funcs):

$executor->setVar('monthly_salaries', [1800, 1900, 1200, 1600]);

echo $executor->execute("avg(monthly_salaries) * min([1.1, 1.3])");

By default, variables must be scalar values (int, float, bool or string) or array. If you would like to support another type, use 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");
    }
});

You can dynamically define variables at run time. If a variable has a high computation cost, but might not be used, then you can define an undefined variable handler. It will only get called when the variable is used, rather than having to always set it initially.

$calculator = new MathExecutor();
$calculator->setVarNotFoundHandler(
    function ($varName) {
        if ($varName == 'trans') {
            return transmogrify();
        }
        return null;
    }
);

Floating Point BCMath Support

By default, MathExecutor uses PHP floating point math, but if you need a fixed precision, call useBCMath(). Precision defaults to 2 decimal points, or pass the required number. WARNING: Functions may return a PHP floating point number. By doing the basic math functions on the results, you will get back a fixed number of decimal points. Use a plus sign in front of any stand alone function to return the proper number of decimal places.

Division By Zero Support:

Division by zero throws a \NXP\Exception\DivisionByZeroException by default

try {
    echo $executor->execute('1/0');
} catch (DivisionByZeroException $e) {
    echo $e->getMessage();
}

Or call setDivisionByZeroIsZero

echo $executor->setDivisionByZeroIsZero()->execute('1/0');

If you want another behavior, you can override division operator:

$executor->addOperator("/", false, 180, function($a, $b) {
    if ($b == 0) {
        return null;
    }
    return $a / $b;
});
echo $executor->execute('1/0');

String Support:

Expressions can contain double or single quoted strings that are evaluated the same way as PHP evaluates strings as numbers. You can also pass strings to functions.

echo $executor->execute("1 + '2.5' * '.5' + myFunction('category')");

To use reverse solidus character (\) in strings, or to use single quote character (') in a single quoted string, or to use double quote character (") in a double quoted string, you must prepend reverse solidus character (\).

echo $executor->execute("countArticleSentences('My Best Article\'s Title')");

Extending MathExecutor

You can add operators, functions and variables with the public methods in MathExecutor, but if you need to do more serious modifications to base behaviors, the easiest way to extend MathExecutor is to redefine the following methods in your derived class:

  • defaultOperators
  • defaultFunctions
  • defaultVars

This will allow you to remove functions and operators if needed, or implement different types more simply.

Also note that you can replace an existing default operator by adding a new operator with the same regular expression string. For example if you just need to redefine TokenPlus, you can just add a new operator with the same regex string, in this case '\+'.

Documentation

Full class documentation via PHPFUI/InstaDoc

Future Enhancements

This package will continue to track currently supported versions of PHP.

mathexecutor's People

Contributors

antonstoeckl avatar bajb avatar beblife avatar diman3210 avatar fatihkizmaz avatar javiermarinros avatar johnrazeur avatar madman-81 avatar mathijsqdrop avatar mrm avatar msztorc avatar neonxp avatar ochi51 avatar peter279k avatar phpfui avatar shadowalker89 avatar waffle-iron avatar zhukv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mathexecutor's Issues

if() truthy and falsy cases are both executed

Hi,

In my case i have an $a and $b variables that are always defined.
I also have a $c variable that is only defined when $a > $b

Using this expression

if($a > $b, $c + 1 : 0)

I get this exception

NXP\Exception\UnknownVariableException: c

When i debugged this code, i found that $c + 1 is being parsed and evaluated even if the condition is not true.
This is caused because the if() is being used a custom function and the toknizer is treating it like any other token.
What if the if() and all it's 3 parameters, should be a single big token that get parsed on it's own, it will check if the condition is true or false and will call the proper logic depending on the condition being true or false

Allow optional parameters in functions

It would be a great feature allow functions to have optional parameters.

For example:

 'log' => function ($arg, $base = null) {
                return isset($base) ? log($arg, $base) : log($arg);
            },

Or

   'if' => function ($expr, $trueval, $falseval = 0) {
                if ($expr === true || $expr === false) {
                    $exres = $expr;
                } else {
                    $exres = $this->execute($expr);
                }
                if ($exres) {
                    return $this->execute($trueval);
                } else {
                    return $this->execute($falseval);
                }
            }

I tried to implement it using ReflectionFunction::getNumberOfRequiredParameters but the parser stack gets in bad state and the execution fails.

This change could even open the door to have an arbitrary number of parameters for some functions, eg.: max(1, 2, 3, 4, 5)

Include if statement

Hi @neonxp, great work!
Any clue on the best approach to include an if parser?
Something like: if(condition; action1; action2)
Thanks

Getting error with $executor->addFunction

Hi,

When I try to add a function, like described in the doc:

$executor->addFunction('round', function ($arg) { return round($arg); }, 1);

I get this error:

Argument 2 passed to NXP\MathExecutor::addFunction() must be
an instance of NXP\callable, instance of Closure given

First, there is no NXP\callable, and second, is Closure an instance of callable or not?
Didn't you have theses errors when running your tests?
Removing the cast "callable" in the arguments of the function in the source make it work, but … should be corected form the source.

Using PHP Version 5.3.21
Thanks!

Token Greater Than Or Equals

Hi,

I wont to write the token '>=', it always the separate the rule in two strings '>' and '=' .

I wrote the class but regex doesn't resolve the rules very well.
Do you have any suggestion ?

/** * @return string */ public static function getRegex() { return '\>\='; }

Negative Numbers don't work?

Hi there,

we're using your Library and it works fine so far, but today we added a negative number and this does not work. Our expression is like:
(5 + 3) * -1

I understand the trouble in parsing that, as without the whitespace it's hard to tell if the expression is missing an operand or one operand has a negativ prefix.

Is there another way to have negative prefixed numbers that I'm missing?

Regards, Anton

Weird parsing with substractions

<?php
require_once 'vendor/autoload.php';
echo (new \NXP\MathExecutor())->execute('1-1') . PHP_EOL;
PHP Fatal error:  Uncaught exception 'NXP\Exception\IncorrectExpressionException' in /home/xx/yy/vendor/nxp/math-executor/src/NXP/Classes/Calculator.php:57
Stack trace:
#0 /home/xx/yy/vendor/nxp/math-executor/src/NXP/MathExecutor.php(191): NXP\Classes\Calculator->calculate(Array, Array)
#1 /home/xx/yy/jee.php(3): NXP\MathExecutor->execute('1-1')
#2 {main}
  thrown in /home/xx/yy/vendor/nxp/math-executor/src/NXP/Classes/Calculator.php on line 57

Use of bcmath functions?

Is it possible that you could replace the simple operations add, sub, mul and div by the operations of bcmath to avoid floating point number errors?

Example: 0.1 + 0.2 - 0.3 does not return 0 when using the MathExecutor but "5.551115123125783E-17".

I would like to use your lib for financial calculations, e.g. to calculate the extra fee or a bid price to an offered product. And this calculation is based on a configured formula like "({StockExchangePrice} * 1.025 + 2.30) * 0.9".

PHP 8.1 support

Adding PHP 8.1 support

  • Updating dependencies (composer.json)
  • Updating tests
  • Updating PHP requirements (PHP >= 7.3)

Prevent cache while executing an expression

Hi,

It would be great to have optional boolean type param $cache = true for execute method to prevent storing tokens in the cache.

public function execute(string $expression, bool $cache = true)

I'm aware of all benefits of having a cache. However, this can be undesirable in some cases, especially if you want to use a particular expression just only once or you if need to parse thousands of unique expressions at the same class instance. This will impact memory usage a lot because of adding thousands of expression tokens to $cache variable and they will never be used again.

According to the above, I suggest adding optional param $cache = true to execute method and additional public method to clear cache if needed.

Possible memory leak

Hi,

I was running a simple test to see if I should be concerned with memory usage when using recursive calculations and I came across this weird memory usage.

I'm using V2.3.0 of this package.

Below is my full code for this test so you can try to reproduce:

This is the function called to run the test in the console

public static function testCalc() {

    $formulas = ['1+1', '2+2', '3+3', '4+4', '5+5'];

    $c = new CalculatorHelper2();

    echo "START | MEMORY USAGE: " . GeneralHelper::memoryUsage() . "\n\n";

    for ($i = 1; $i <= 500000; $i++) {
        foreach ($formulas as $formula) {

            $c->calc($formula);

            echo "MEMORY USAGE: " . GeneralHelper::memoryUsage() . "\n\n";

        }
    }

}

This is the Helper class I'm using to wrap the MathExecutor

namespace App\Helpers;

use Exception;

use NXP\MathExecutor;

class CalculatorHelper2
{
    private $executor;

    public function __construct() {

        $this->executor = new MathExecutor();
    }

    public function calc($formula) {
        try {

            return $this->executor->execute($formula, false);

        } catch(Exception $e) {

            echo "ERROR in formula...";

        }
    }

}

For additional context this is all the GeneralHelper::memoryUsage function is doing

static public function convertSizes($size) {
    $unit=array('b','kb','mb','gb','tb','pb');
    return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}

static public function memoryUsage() {
    return self::convertSizes(memory_get_usage(true));
}

In this video we can clearly see the memory usage increasing even though nothing is being saved in memory by creating or modifying any variables (for example adding the results from the calculations to an array)

3a841c2529fb16399a8d3b696acc3996.mp4

Right when the script starts it seems like it's not increase the memory, however, just two seconds later the memory starts increasing pretty fast after every iteration.

Any idea what's happening here?

Negative number in bracket

I have a IncorrectExpressionException when a negative number is in a bracket:

Expression that throw the exception: 1 + (-3 * -1)

Formula parsing issues

HI,

I have problems parsing simple formulas like this:

  • ROUND(ROUND(0.2456,2),2) - NXP\Exception\IncorrectExpressionException.
    ROUND() is like this:
        $this->calculator->addFunction('ROUND', function ($decimals, $value) {
            return round($value, $decimals);
        }, 2);
  • 10/(4-2) rises exception NXP\Exception\IncorrectExpressionExceptio also. It looks like the space must be present before 2 here!

Any ideas how to solve this?
Thank you.

Subtractions in expressions results in error

Consider the same expression written slightly differently below:

  1. (1+2+3+4-5)*7/100
  2. ( 1 + 2 + 3 + 4 - 5 ) * 7 / 100

The first one fails while the second one works perfectly well. It seems, in the tokens are not created correctly if there is no space between - operator. Seems somewhat related to #1

Error at nxp\math-executor\src\NXP\MathExecutor.php line 235

Double operator fails

Hello,

I am having problems when I have formula with "double" operators.
E.g:

  • --4+5 -> ParseError: syntax error, unexpected '4' (T_LNUMBER)
  • +-4+5 -> Exception: NXP\Exception\UnknownOperatorException
  • -+4+5 -> Exception: NXP\Exception\UnknownOperatorException

Executor wrong result

var_dump($math->execute("1 + 2 * 3 / (min(1, 5) + 2 + 1)"))

output: 10

var_dump(1 + 2 * 3 / (min(1, 5) + 2 + 1))

output: 2.5

$lexer->stringToTokensStream($expression) not working anymore

Hi,

I'm having trouble executing some simple formulas since last update. I'm having this simple formula: 'line1 + line2 + line3 + line4'

I checked and my variables in my MathExecutor instance and they are well defined:

array (size=8)
  'pi' => float 3.14159265359
  'e' => float 2.71828182846
  'line1' => float 162766
  'line2' => float 31417
  'line3' => float 1319
  'line4' => float 1131
  'line5' => float 166809
  'line6' => float 36372

I found that it's when it passing trough $tokenFactory->createToken($token); (Lexer class, line 50) that it throws me an UnknownFunctionException. The $token at that time is equal to 'line1', so I guess that it's trying to find my variable inside its operators list, but I may be wrong.
I'm asking myself, is it OK however that there's an empty function (public function addVariable) in the TokenFactory class?

Must point out that my code was woorking perfectly before Sep 05 changes.

I tried it with PHP 5.3 and 5.5 with same errors.
Thanks!

Removal of symbolic links

Hi,
I'm deploying these library in a complex environment that uses automated scripts.
I get errors with the bin/phpunit symbolic link because it's not always installed. Also I think that, in general it should not be in this package because it's an external dependency that should be resolved in another way.
If you agree please remove the link,
Thanks,
Franco

Not grouping expression with priority.

Hello. I have a bug with use 1 + 0.6 - 3 * 2 / 50
Tokenizer must be a group 3 * 2 / 50 and execute as first, after add other expression.
If i add left/right bracket, than all good.

Thank.

Expression beginning with left bracket and minus

Expression beginning with left bracket and minus throw an exception.
For exemple:

$calculator = new MathExecutor();
$calculator->execute('(-4 + 5)');

throws: NXP\Exception\IncorrectExpressionException: Subtraction requires two operators

The setVars should not refuse non-arithmetic values

Righ now inside the setVars function, you will see:
if (!is_numeric($value)) {
throw new \Exception("Variable value must be a number");
}
I
t's sad: this remove any user to create sum operators for example, and have various use cases where it would be quite useful to have more freedom regarding this specific point.

`If` condition breaks since v2.x

Hi Alexander, thx for the create project. Don't know if this is a bug, or a code change require(Couldn't find any release notes regarding this change).

If we upgrade from 1.1.4 to 2.0.x the if condition doesn't seem to work any more.

Expression used if($trx_amount < 40000, $trx_amount * 0.06, if($trx_amount < 60000, $trx_amount * 0.05, $trx_amount * 0.03))

NXP\Exception\UnknownOperatorException:  in file /var/www/vendor/nxp/math-executor/src/NXP/Classes/Tokenizer.php on line 253
Stack trace:
  1. NXP\Exception\UnknownOperatorException-&gt;() /var/www/vendor/nxp/math-executor/src/NXP/Classes/Tokenizer.php:253
  2. NXP\Classes\Tokenizer-&gt;buildReversePolishNotation() /var/www/vendor/nxp/math-executor/src/NXP/MathExecutor.php:349
  3. NXP\MathExecutor-&gt;execute()

Error in PHP 7.4

It is not working in PHP 7.4

Uncaught Error: syntax error, unexpected 'public' (T_PUBLIC), expecting variable (T_VARIABLE)
in \nxp\math-executor\src\NXP\Classes\Operator.php on line 20

How to fix them?

Too many commas in an if-statement doesn't throw an exception

If an if-statement has only 1 comma, a \NXP\Exception\IncorrectNumberOfFunctionParametersException is thrown, but if it has too many commas, no exception is thrown and the "if" is calculated with the first 3 parameters.

"if( 'A' == 'A', 1)" => \NXP\Exception\IncorrectNumberOfFunctionParametersException ✔️ 
"if( 'A' == 'A', 1, 2)" => 1 ✔️ 
"if( 'A' == 'A', 1, 2, 3)" => 1 ❌ 

If you would add this unit test, it fails:

    public function testFunctionIncorrectNumberOfParametersTooMany() : void
    {
        $calculator = new MathExecutor();
        $this->expectException(IncorrectNumberOfFunctionParametersException::class);
        $calculator->addFunction('myfunc', static function($arg1, $arg2) {
            return $arg1 + $arg2;
        });
        $calculator->execute('myfunc(1,2,3)');
    }

I would expect the IncorrectNumberOfFunctionParametersException if there are too many arguments. Otherwise it's impossible to validate formulas.

Tested with version 2.3.0

Broken formula parsing in v0.6+

I have a formula that works perfectly fine in v0.5, but in v0.6 and v0.7 it breaks in different ways. Formula is: round(100 * 1.10, 2) - 0.01, expected result is 109.99. v0.6+ gives a result of 99.99.

If I change the formula to round((100 * 1.10), 2) - 0.01, then v0.6+ gives the correct value.

The code is:

        $calculator = new MathExecutor();

        $calculator->addFunction('round', function ($decimals, $value) {
            return round($value, $decimals);
        }, 2);

        $result = $calculator->execute('round(100 * 1.10, 2)');

Basic usage?

I cloned this project but I don't know how to use it. When I try to make a new MathExecutor() it says class not found. Am I retarded? Can someone please tell me a very basic example? I have been trying for 2 hours. Thank you.

Divided by zero

Divided by zero should raise an exception or return some flag to identify the divided by zero case. currently execute function returns 0 in case of divided by zero i.e 2/0 or 0/0

Unary Minus results in error when used with non-digits

Hi,
I've found a case in which the use of the unary minus results in an error. This happens when there is a numeric value in front of it.

Let me give an example:

(new NXP\MathExecutor())->execute("3 -log(4)"); //Fine
(new NXP\MathExecutor())->execute("-log(4)"); //Error

(new NXP\MathExecutor())->execute("3 -(2+5)"); //Fine
(new NXP\MathExecutor())->execute("-(2+5)"); //Error

The error that results is A non-numeric value encountered in MathExecutor.php which I've traced to defaultOperators().
The "-" character ends up in the $a or $b variable as a separate value instead of being part of a negative digit.

Uncaught Error

If an expression begins or ends with an operator, instead of throwing an Exception the Fatal error occurs (the only working scenario is when the expression begins with the minus sign).

For example:

echo $calculator->execute('*1+2'); or echo $calculator->execute('1+2-');.

Also, in case when the expression begins with the plus sign it should be evaluated:

echo $calculator->execute('+1+2');

The error message:

Fatal error: Uncaught Error: Call to a member function getValue() on null in ...\vendor\nxp\math-executor\src\NXP\Classes\Token\TokenPlus.php on line 50

Error: Call to a member function getValue() on null in ...\vendor\nxp\math-executor\src\NXP\Classes\Token\TokenPlus.php on line 50

Should't it throw an exception if a operator is missing?

Hello,

I'm tinkering with this library, and feels great on my tests so I'm using it for my project.

One question arised on my tests: evaluating the expression 3 4 returns the value 34, but I think it really should throw an exception as an operator is missing, and simply removing the space and concatenating the numbers seems counter intuitive to me.

Maybe we should check if previous token is an operator, right parenthesis, etc., and check next token to throw an exception if they result in an incorrect formula?

Object Variables

Hi, I'm using MathExecutor in combination with a money library to calculate prices (without floating point errors).

I've extended MathExecutor and overwritten all the operators to also work with with Money objects and it works great, however setting variables is not possible as it only allows for scalar types. Unfortunately I can't override the setVar function as $variables is private.

A simple fix would be to put the validation in a separate function so it's possible to override it, or make the $variables array protected. Not sure if this might cause problems in other areas though.

I'd be happy to create a PR for the above or for a different solution if you're willing to accept it.

Quoted arguments

In readme:

Expressions can contain double or single quoted strings that are evaluated

In fact:
$result = $executor->execute('DATE("2019-01-09 04:08:00")'); - works (argument = "2019-01-09 04:08:00")
$result = $executor->execute("DATE('2019-01-09 04:08:00')"); - error (argument = "00")

Need to investigate.

php7.3.28 can not use composer to install

my php version is 7.3.28, when I use composer require nxp/math-executor, I got the ErrorException like this:
"continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"?

TokenFunction implementation improvements suggestion

I want to be able to add optional parameters in functions.

Can I propose the following changes to TokenFunction execute function?

  1. Add an if statement to see if stack is empty so ->getValue doesn't fire an error if an argument is missing.

    if (!(empty($stack))) { //added to allow it to call function with fewer args
    array_push($args, array_pop($stack)->getValue());
    }

  2. Reverse the resulting array so the arguments are back in the right order before calling the function

    $args = array_reverse($args); //array_pop and push flips the order of the arguments so reverse back

Thanks for your consideration.

discrepancy in license

composer.json says "GPLv2", while the LICENSE file is not GPLv2.
What is the exact license for this library ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.