Process Mathematical Equations in PHP

Process mathematical equations in php

Eval is not Evil!!!!!

Yes it can stuff your system up completely if you write bad code - but recent PHP versions can parse an invalid expression without crashing the whole script. And there are many other ways of exposing your system by writing bad code.

That just leaves the possiblity of code injection attacks - which can easily be avoided by doing a preg_replace on everythnig which is not a safe character (i.e. 0....9, (, ), +, -, *, /, ^, .)

How to use mathematical variables in php to solve an equation

There's no simple easy way to solve any given type of equation in PHP. You might also be looking for something more like MATLAB, as PHP wasn't exactly designed with this in mind.

You can write algorithms in any language to solve it, though. Here I've solved yours using randomness and brute force (probably the simplest and one of the least efficient methods):

<?php

while ($total != 30 || $girls != $boys + 4) {
$girls = rand(0, 30);
$boys = rand(0, 30);
$total = $girls + $boys;
}

echo "There are {$girls} girls and {$boys} boys.";

In academic Computer Science, solutions to problems like these are called Algorithms, and graduates usually cite that course as their program's most important (along with Data Structures).

How do I go about converting a math equation into php?

There are various functions that need to be combined in order to create these equations. The log function performs logarithm operations in a base of your choice (or ln if you do not provide a base). The pow function performs exponentiation.

Your equations would be:

function rank($xp) {
return floor(6 * log((xp * log(2) / 24000 + 1), 2));
}

function xp($rank) {
return floor(24000 * (pow(2, (rank / 6)) - 1) / log(2));
}

function kills($rank) {
return floor(xp($rank) / 200);
}

There are a few more parentheses there than absolutely needed, for clarity's sake.

Mathematical notations in general are considerably more compact and expressive than most programming languages (not just PHP) due to the fact that you can use any symbol you can think of to represent various concepts. In programming, you're stuck calling functions.

Also, I'm not sure what the various hardcoded numbers represent, or if it makes sense to change them, in the context of the formula, but you might want to think about setting them up as extra parameters to the function. For example:

function kills($rank, $killsPerXp = 200) {
return floor(xp($rank) / $killsPerXp);
}

This adds clarity to the code, because it lets you know what the numbers represent. At the same time, it allows you to change the numbers more easily in case you are using them in multiple places.

PHP Mathematical Equation with multiple functions in it

If you look closely to the equation you will find this is Fibonacci Series.you can solve this using recursive function Like this.

    function fib($n) {
if ($n < 0) {
return NULL;
} elseif ($n === 0) {
return 0;
} elseif ($n === 1 || $n === 2) {
return 1;
} else {
return fib($n-1) + fib($n-2);
}
}

As you can see i am calling same function until the base condition satisfied. Hope this help

calculate math expression from a string using eval

While I don't suggest using eval for this (it is not the solution), the problem is that eval expects complete lines of code, not just fragments.

$ma ="2+10";
$p = eval('return '.$ma.';');
print $p;

Should do what you want.


A better solution would be to write a tokenizer/parser for your math expression. Here's a very simple regex-based one to give you an example:

$ma = "2+10";

if(preg_match('/(\d+)(?:\s*)([\+\-\*\/])(?:\s*)(\d+)/', $ma, $matches) !== FALSE){
$operator = $matches[2];

switch($operator){
case '+':
$p = $matches[1] + $matches[3];
break;
case '-':
$p = $matches[1] - $matches[3];
break;
case '*':
$p = $matches[1] * $matches[3];
break;
case '/':
$p = $matches[1] / $matches[3];
break;
}

echo $p;
}

PHP Math Equation

Try using the pow() function:

$equation = ($dec * $amount) / (1 - pow(1 + $dec, $months * -1));

Mathematical formula string to php variables and operators

The correct solution has already been given by Vilx-. So I will give you a not-so-correct, dirty solution.

As the correct solution states, eval is evil. But, it is also easy and powerful (as evil often is -- but I'll spare you my "hhh join the Dark Side, Luke hhh" spiel).

And since what you need to do is a very small and simple subset of SQL, you actually can use eval() - or even better its SQL equivalent, plugging user supplied code into a SQL query - as long as you do it safely; and with small requirements, this is possible.

(In the general case it absolutely is not. So keep it in mind - this solution is easy, quick, but does not scale. If the program grows beyond a certain complexity, you'll have to adopt Vilx-'s solution anyway).

You can verify the user-supplied string to ensure that, while it might not be syntactically or logically correct, at least it won't execute arbitrary code.

This is okay:

SELECT SUM(pitch)+AVG(runs)-5*(MIN(balls)) /* or whatever */

and this, while wrong, is harmless too:

SELECT SUM(pitch +

but this absolutely is not (mandatory XKCD reference):

SELECT "Robert'); DROP TABLE Students;--

and this is even worse, since the above would not work on a standard MySQL (that doesn't allow multiple statements by default), while this would:

SELECT SLEEP(3600)

So how do we tell the harmless from the harmful? We start by defining placeholder variables that you can use in your formula. Let us say they will always be in the form {name}. So, get those - which we know to be safe - out of the formula:

$verify = preg_replace('#{[a-z]+}#', '', $formula);

Then, arithmetic operators are also removed; they are safe too.

$verify = preg_replace('#[+*/-]#', '', $verify);

Then numbers and things that look like numbers:

$verify = preg_replace('#[0-9.]+#', '', $verify);

Finally a certain number of functions you trust. The arguments of these functions may have been variables or combinations of variables, and therefore they've been deleted and the function has now no arguments - say, SUM() - or you had nested functions or nested parentheses, like SUM (SUM( ()())).

You keep replacing () (with any spaces inside) with a single space until the replacement no longer finds anything:

for ($old = ''; $old !== $verify; $verify = preg_replace('#\\s*\\(\\s*\\)\\s*#', ' ', $verify)) {
$old = $verify;
}

Now you remove from the result the occurrences of any function you trust, as an entire word:

for ($old = ''; $old !== $verify; $verify = preg_replace('#\\b(SUM|AVG|MIN|MAX)\\b#', ' ', $verify)) {
$old = $verify;
}

The last two steps have to be merged because you might have both nested parentheses and functions, interfering with one another:

for ($old = ''; $old !== $verify; $verify = preg_replace('#\\s*(\\b(SUM|AVG|MIN|MAX)\\b|\\(\\s*\\))\\s*#', ' ', $verify)) {
$old = $verify;
}

And at this point, if you are left with nothing, it means the original string was harmless (at worst it could have triggered a division by 0, or a SQL exception if it was syntactically wrong). If instead you're left with something, the formula is rejected and never saved in the database.

When you have a valid formula, you can replace variables using preg_replace_callback() so that they become numbers (or names of columns). You're left with what is either valid, innocuous SQL code, or incorrect SQL code. You can plug this directly into the query, after wrapping it in try/catch to intercept any PDOException or division by zero.

how to use a string as formula for mathematical calculations in php?

Unfortunately, you need to eval it.

And if the values are like:

$deviceData["devicename"] = [
'a' => 20,
'b' => 30,
'c' => 580
];

You might want to isolate them as you will need to extract() them out to make use if there is more then 3 etc, encapsulating in function/closure would work.

<?php
$formula = '(($a+$b)/$c)';

$deviceData["devicename"] = ['a' => 20, 'b' => 30, 'c' => 580];

$runFormula = function ($formula, $data) {
extract($data);
return eval('return '.$formula.';');
};

echo $runFormula($formula, $deviceData["devicename"]);

https://3v4l.org/I2rbk

Or just:

extract($deviceData["devicename"]); 
echo eval('return '.$formula.';');

But you're polluting your global variable table with whats extracted, potentially causing more issues.

Though dont use eval if the formula is defined by the user, or your will have security issues.


In no respect shall I incur any liability for any damages, including,
but limited to, direct, indirect, special, or consequential damages
arising out of, resulting from, or any way connected to the use of the
code provided, whether or not based upon warranty, contract, tort, or
otherwise; whether or not injury was sustained by persons or property
or otherwise; and whether or not loss was sustained from, or arose out
of, the results of, the use if this code. ;p



Related Topics



Leave a reply



Submit