PHP pear库中的RPN类bug及修复

最近使用PHP开发工资管理系统的过程中因为要进行工资计算,需要进行四则运算。查资料后,确定使用PHP的PEAR库的Math_Rpn类进行。然而在使用的过程中发现了该类库的

Bug。

1、问题描述

测试代码:

include('RPN.php');
$expArr=array(
  "(255.3*2)+33.2",
  "(655*2)+32.2",
  "(153*2)+31.2"
);
$rpn = new Math_Rpn();
foreach($expArr as $val){
  echo "$val=".$rpn->calculate($val,false)."<br />";
}

运行结果:

(255.3*2)+33.2=543.8
(655*2)+32.2=Syntax error
(153*2)+31.2=Syntax error

2、bug原因

   经过分析发现,出现此问题的原因在于该类并无构造方法来初始化变量的值,这样对于中缀表达式的计算时,上一次解析的值变成下一次解析运算中的脏数据。

3、解决方法

 /**
     * Calculate the $input expression
     *
     * @param mixed $input Infix expression string or RPN expression string 中缀表达式或逆波兰式
     * @param string $angle Angle's unit - 'rad' or 'deg'  角的单位 rad表弧度,deg表示度
     * @param boolean $is_rpn True if $input is RPN expression or false if $input is infix expression   
     * @return mixed Value of $input expression or a PEAR error
     * @access public
     */
    function calculate($input = '',$is_rpn = true,$angle = 'rad') {

        $this->_angle = (boolean) ($angle == 'rad');

        if($input == '') {
            $this->_error = $this->_raiseError('Empty input expression');
            return $this->_error;
        }

        if(!$is_rpn) {
            /**
             * 多次连续调用计算中缀表达式时,因为未清除堆栈,上次的表达式数据成为脏数据,带入下次运算,
             * 造成表达式解析等出错!
             * 对input_array 和output进行初始化
             * @author kelite
             * 2013-02-24 
             */
            $this->_input_array=array();
            $this->_output=array();
            
            $this->_input = $input;

            $this->_stringToArray ();
            if($this->_error <> null) return $this->_error;

            $this->_arrayToRpn();
            if($this->_error <> null) return $this->_error;
        } else {
            if (is_array($input)) {
                $input = implode(' ', $input);
            }

            $this->_input = $input;
            $this->_input_array = explode(' ',$input);
            $this->_output = explode(' ',$input);
        }

        $this->_rpnToValue();
        if($this->_error <> null) return $this->_error;

        return $this->_value;
    }

  

  

  

  

原文地址:https://www.cnblogs.com/kelite/p/2923917.html