Maison >développement back-end >tutoriel php >Comment évaluer en toute sécurité des chaînes mathématiques en PHP à l'aide de l'analyse Infix vers Postfix ?

Comment évaluer en toute sécurité des chaînes mathématiques en PHP à l'aide de l'analyse Infix vers Postfix ?

Patricia Arquette
Patricia Arquetteoriginal
2025-01-02 22:38:39443parcourir

How to Securely Evaluate Mathematical Strings in PHP Using Infix to Postfix Parsing?

Évaluation mathématique des chaînes utilisant Infix pour l'analyse Postfix

Évaluation mathématique des chaînes, telles que "2-1" pour produire "1, " nécessite d'analyser la chaîne dans ses éléments constitutifs. En PHP, la méthode par défaut d'évaluation mathématique implique l'utilisation de la fonction eval(), qui exécute du code PHP arbitraire et peut introduire des failles de sécurité.

Cependant, une approche plus sécurisée consiste à utiliser un analyseur infixe en postfixe pour convertir la chaîne en notation polonaise inversée (RPN). Un solveur RPN peut ensuite évaluer l'expression résultante sans avoir besoin d'eval().

Implémentation d'un infixe à l'analyseur Postfix

Vous trouverez ci-dessous un exemple de la façon d'implémenter un infixe à l'analyseur postfix en utilisant un PHP classe :

class EOS {
  private $operators = ['+', '-', '*', '/', '^'];
  private $precedence = [
    '*' => 3,
    '/' => 3,
    '+' => 2,
    '-' => 2,
    '^' => 4
  ];

  public function solveIF($infix) {
    $postfix = $this->infixToPostfix($infix);
    return $this->postfixSolver($postfix);
  }

  // Converts infix expression to postfix
  private function infixToPostfix($infix) {
    $stack = new Stack();
    $postfix = '';
    $tokens = explode(' ', $infix);

    foreach ($tokens as $token) {
      if (in_array($token, $this->operators)) {
        while (!$stack->isEmpty() && $this->precedence[$stack->top()] >= $this->precedence[$token]) {
          $postfix .= $stack->pop() . ' ';
        }
        $stack->push($token);
      } else {
        $postfix .= $token . ' ';
      }
    }

    while (!$stack->isEmpty()) {
      $postfix .= $stack->pop() . ' ';
    }

    return $postfix;
  }

  // Solves postfix expression
  private function postfixSolver($postfix) {
    $stack = new Stack();
    $tokens = explode(' ', $postfix);

    foreach ($tokens as $token) {
      if (in_array($token, $this->operators)) {
        $operand2 = $stack->pop();
        $operand1 = $stack->pop();
        $result = $this->evaluateOperator($token, $operand1, $operand2);
        $stack->push($result);
      } else {
        $stack->push($token);
      }
    }

    return $stack->top();
  }

  // Evaluates operators
  private function evaluateOperator($op, $operand1, $operand2) {
    switch ($op) {
      case '+':
        return $operand1 + $operand2;
      case '-':
        return $operand1 - $operand2;
      case '*':
        return $operand1 * $operand2;
      case '/':
        return $operand1 / $operand2;
      case '^':
        return pow($operand1, $operand2);
    }
  }
}

Utilisation :

$eo = new EOS();
$result = $eo->solveIF("2-1");
echo $result; // Prints 1

Alternatives supplémentaires :

Lors de l'utilisation d'un infixe pour postfixer l'analyseur est une méthode sécurisée d'évaluation mathématique, il existe des alternatives supplémentaires disponible :

  • Wolfram|API Alpha : fournit des capacités d'évaluation mathématique via une API.
  • Sage : un système logiciel mathématique open source.
  • PHP Dice Calc : Une bibliothèque PHP pour les opérations mathématiques.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn