4

I have come across this problem before and expect to do so again: I want to run a subtotal calculation in both javascript and PHP. I may want to change the calculation at some point.

  • It needs to run in javascript to maximise the speed of the calculation, so that the user knows what to expect.
  • It needs to run in PHP so that I am getting a valid subtotal which a malicious user cannot interfere with.

As such:

  • If I only run the calculation on the client-side (in javascript), a malicious user may hack the javascript and change the subtotal.
  • If I only run the calculation on the server-side (in PHP), an AJAX call would have to be waited on for the user to get their updated subtotal.

So I want to perform the calculation on both sides. The only way I have seen this done is by programming the calculation in PHP and programming the calculation in separate javascript.

My question is, what pattern, technique or technology would people recommend that I use to create the calculation on the server-side and make it compatible with javascript when it is sent to the client-side?

An idea I had, for example, was a PHP array for the calculation, which gets translated into PHP code and javascript code, e.g:

array(
    array(type => "operand", "name" => "variable_A"),
    array(type => "operator", "name" => "multiply"),
    array(type => "operand", "name" => "variable_B"),
)

This might convert into PHP:

return $variable_A * $variable_B;

And into Javascript:

return variable_A * variable_B;

That's an example operational pattern. I don't know what real ones would look like if they exist.

Shoreline
  • 798
  • 1
  • 9
  • 26
  • "So I want to perform the calculation on both sides. The only way I have seen this done is by programming the calculation in PHP and programming the calculation in separate javascript." So the malicious user can see what is done in JS, right? – Voitcus Apr 08 '13 at 08:54
  • You may like to read [this discussion](http://stackoverflow.com/questions/4019418/process-mathematical-equations-in-php) – Voitcus Apr 08 '13 at 08:55
  • @Voitcus Yes the malicious user would be able to find the calculation in the javascript. The idea of the server side would be that they can't interfere with the output of the calculation, only change the input. – Shoreline Apr 08 '13 at 10:02

2 Answers2

0

ajax?

you can pass all the variable entered with javascript and leave the process server based.

or i misunderstand your question?

0

The way I think about your problem is like you described it: do double calculation. And I believe that's how the "big boys" do it.

Example: Add up two numbers. So you have a code like this:

HTML snippet:

<form method="post" action="/add.php">
<input id="firstOperand" name="firstOperand" placeholder="First operand"/>
<input id="secondOperand" name="firstOperand" placeholder="Second operand"/>
<input type="submit" onclick="doCalculation()" value="Add"/>
</form>
<div id="result" />

Your JS might look like:

function doCalculation() {
  var first = parseInt(document.getElementById('firstOperand').value);
  var second = parseInt(document.getElementById('secondOperand').value);

  var result = first + second;
  // the minimum amount of error checking
  if isNan('result') return false;
  document.getElementById('result').innerHTML = result;

  // Now use some framework (like jQuery) to make an Ajax call and pass the result to callback.
  Framework.Ajax('/add.php?format=json', 'POST', {first: first, second: second}, callback);
  return false;
}

function callback(response) b
  var res = response.json.result;
  var resultEl = document.getElementById('result');
  var errorEl = document.getElementById('error');
  // if our result is not correct, we want to update the user on it
  if (res != parseInt(resultEl.innerHTML)) {
    Framework.removeClass(errorEl, 'hidden');
  }
  document.getElementById('result').innerHTML = res;
}

Of course, your PHP result page (add.php) would return json with the result. The added value here is that you can also return a plain HTML result (like if js is disabled).

Your callback could also check if there was an error in the returned result and display that error message too. Or if the result times out, display a notification that the "result" is not saved. But that's out of the scope of the question, I guess (at least, out of the scope of the answer).

Note: this is just the code off the top of my head, not tested, written directly in the answer box, probably a few things should be done better.

Zlatko
  • 18,936
  • 14
  • 70
  • 123
  • The problem with sending the calculation through ajax is the amount of time the user will have to wait for it's return from the server. If the calculation is performed in the javascript it will be fast enough that the user sees the result as instant. I'm afraid your answer is outside the scope of the question. Thanks anyway, though. – Shoreline Apr 08 '13 at 17:31
  • Well that's what I said? You do a local calculation and show result. Then in the backend you can do Ajax call and check the value. Finally the callback for your Ajax call will do nothing if the results match, or inform the user that the server returned different result, that there was an 'error saving' or whatever it is you're trying to do. – Zlatko Apr 08 '13 at 22:26
  • Ok, but my question is how to maintain the calculation consistently without writing it twice. Ideally I would represent the calculation once on the back-end, and the calculation would be translated into PHP and translated into Javascript. I don't know if there is a library which will do that, and I don't know how far exec and eval will support it. – Shoreline Apr 10 '13 at 17:05
  • Oh, the code itself! Now I understand your question! Well, one solution would be to use node.js - that's java on backend and frontend too, so you could use it that way. Alternatively, I'm sure there are JS code generators for PHP, I just don't know any :) – Zlatko Apr 11 '13 at 07:26