0

I have created a demo calculator which works perfect except one time when the form gets submitted it goes inside try block and the rest html page doesn't get displayed.. am i doing it wrong? i dont see any reason why it shouldn't execute the rest of the code

I very well understand the try catch finally concept but cant see where's the error

this is my class.calculator.php

class NoNumberProvided_Exception extends Exception {}

class Calculator {

    function __construct() {
        $args = func_get_args();

        if(!$args) {

            throw new NoNumberProvided_Exception("Please provide atleast 2 numbers");

        } else {

            if($args[0] && $args[1]) {

                if($args[2] == "Add") {

                    echo $args[0]+$args[1];

                } else if($args[2] == "Divide") { 

                    echo $args[0]/$args[1];

                } else if($args[2] == "Subtract") { 

                    echo $args[0]-$args[1];

                } else if($args[2] == "Multiply") { 

                    echo $args[0]*$args[1];

                }   

            } else {

                throw new NoNumberProvided_Exception("Please provide atleast 2 numbers");

            }

        }

    }

}

PHP:

if(isset($_POST['submit'])) {

    include 'class.calculator.php';

    try {

        $num = new Calculator($_POST['number1'], $_POST['number2'], $_POST['submit']);

        echo $num; // after the form gets submitted, this gets echoed but the html form below doesnt show on the page

    } catch (NoNumberProvided_Exception $nonumber) {

        echo $nonumber->getMessage();

    } 

}

HTML:

<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>">

    Number1: <input type="text" name="number1" id="number1" />
    <br/>

    Number2: <input type="text" name="number2" id="number2" />
    <br/><br/>

    <input type="submit" id="submit" name="submit" value="Add" />

    <input type="submit" id="submit" name="submit" value="Divide" />

    <input type="submit" id="submit" name="submit" value="Subtract" />

    <input type="submit" id="submit" name="submit" value="Multiply" />

</form>
7
  • do you prefer that it is right use of <?php echo $_SERVER['PHP_SELF']; ?> Commented Aug 24, 2019 at 11:48
  • maybe you need do this ? <?php echo if(isset($_POST['submit'])) { include 'class.calculator.php'; try { $num = new Calculator($_POST['number1'], $_POST['number2'], $_POST['submit']); echo $num; // after the form gets submitted, this gets echoed but the html form below doesnt show on the page } catch (NoNumberProvided_Exception $nonumber) { echo $nonumber->getMessage(); } } ?> Commented Aug 24, 2019 at 11:53
  • doesn't seem to work Commented Aug 24, 2019 at 12:03
  • oh sorry without echo Commented Aug 24, 2019 at 13:13
  • 1
    dude if i can write this whole block on my own then i must be knowing that i need to wrap it in <?php ?> Commented Aug 24, 2019 at 13:25

1 Answer 1

1

The reason you are not seeing the HTML content after echo $num is because you are getting a fatal error.

This is seen when running your code in a php console (php -a)

php > $num = new Calculator(1,2,'Subtract');
-1
php > echo $num;
PHP Catchable fatal error:  Object of class Calculator could not be converted to string in php shell code on line 1
PHP Stack trace:
PHP   1. {main}() php shell code:0
php >

To address this problem, we could make a few conceptual changes to your Calculator class:

  1. A method should only do One Thing. A constructor is best used for initialization, and your calculator's functions Add, Subtract, Multiply, and Divide probably should be separate methods.
  2. As a general rule, an object (being a part of the model, or logic section), should never echo or print its result. This is, in my opinion, a merging of logic and presentation-- which you should strive to separate. It's also part of the problem you ran into.

My first inclination would be to pass the parameters into the methods, instead of the constructor. This allows you to type hint the values you expect. I'm showing integer as example. If bad data (string) is passed, it will throw an exception. If only 1 value is passed, it will throw an exception.

At the end of the day, there's no one "right" way to do it; experience helps show ways that will be easier to work on later. :)

My suggestions, FWIW...

Class:

<?php

class Calculator {

  public function __construct() { }

  public function add(int $addend1, int $addend2) {
    return $addend1 + $addend2;
  }

  public function subtract(int $subtrahend, int $minuend) {
    return $subtrahend - $minuend;
  }

  public function multiply(int $factor1, int $factor2) {
    return $factor1 * $factor2;
  }

  public function divide(int $dividend, int $divisor) {
    return $dividend / $divisor;
  }
}

PHP / HTML

function assignPostVar($name) {
  if(isset($_POST[$name])) {
    return $_POST[$name]; 
  }
}

$error  = '';
if(isset($_POST['submit'])) {
  $calc   = new Calculator;
  $n1     = assignPostVar('number1');
  $n2     = assignPostVar('number2');

  try {
    switch($_POST['submit']) {
      case 'Add': 
        $result = $calc->add($n1,$n2);
        break;

      case 'Subtract': 
        $result = $calc->subtract($n1,$n2);
        break;

      case 'Multiply': 
        $result = $calc->multiply($n1,$n2);
        break;

      case 'Divide': 
        $result = $calc->divide($n1,$n2);
        break;

      default:
        throw new Exception('Invalid operation');            
    }

  } catch (Exception $e) {
    $error = $e->getMessage();
  }
}
?>




<?php if($error): ?>
  <div class="error">Encountered error: <?= $error ?></div>
<?php endif; ?>
<form method="POST">

Number1: <input type="text" name="number1" id="number1" />
<br/>

Number2: <input type="text" name="number2" id="number2" />
<br/><br/>

<input type="submit" id="add" name="submit" value="Add" />

<input type="submit" id="divide" name="submit" value="Divide" />

<input type="submit" id="subtract" name="submit" value="Subtract" />

<input type="submit" id="multiply" name="submit" value="Multiply" />

</form>
Sign up to request clarification or add additional context in comments.

1 Comment

That's a really clear explanation and to the point. Thanks Tim, for solving the issue and suggesting best oops practices.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.