PHP Text Interpreter

5

I'm creating a text interpreter based on the DuckDuckGo Github documentation > in PHP.

This is one of the codes I created:

if (strpos(strtolower($qt), "rand") !== FALSE){
  if (preg_match("/^rand$/", strtolower(removeAccents($qt)), $match)){
    $result = rand(1,9999);
    $sndline = "Random number";
  }
  elseif (preg_match("/^random$/", strtolower(removeAccents($qt)), $match)){
    $result = rand(1,9999);
    $sndline = "Random number";
  }
  elseif (preg_match("/^rand *\((?<min>[0-9]+),(?<max>[0-9]+)\)$/", strtolower(removeAccents($qt)), $match)){
    $result = rand($match['min'],$match['max']);
    $sndline = "Random number";
  }
  elseif (preg_match("/^random *\((?<min>[0-9]+),(?<max>[0-9]+)\)$/", strtolower(removeAccents($qt)), $match)){
    $result = rand($match['min'],$match['max']);
    $sndline = "Random number";
  }
}

As you can see, the script performs the action if the user types rand , random , rand (1,99) and random (1,99) .

The entire interpreter was written with preg_match functions (that is, everything with RegEx) but found that they overloaded the system.

How can I create something that is fast (without overloading the system) and also understands different "orders" given by the user without using RegEx (remembering that the user can type anything in the search)?

    
asked by anonymous 16.05.2015 / 04:25

2 answers

5

I see at least three points that can be optimized with ease:

  • The% more% from outside seems unnecessary.
  • The if may end up being executed more than once (4 times if you type strtolower(removeAccents($qt)) ).
  • The first two cases are an equality comparison, and you do not need to use regex for this.
  • Translating this into code:

    $cleanQt = strtolower(removeAccents($qt));
    if ($cleanQt == "rand"){
      $result = rand(1,9999);
      $sndline = "Random number";
    }
    elseif ($cleanQt == "random"){
      $result = rand(1,9999);
      $sndline = "Random number";
    }
    elseif (preg_match("/^rand *\((?<min>[0-9]+),(?<max>[0-9]+)\)$/", $cleanQt), $match)){
      $result = rand($match['min'],$match['max']);
      $sndline = "Random number";
    }
    elseif (preg_match("/^random *\((?<min>[0-9]+),(?<max>[0-9]+)\)$/", $cleanQt, $match)){
      $result = rand($match['min'],$match['max']);
      $sndline = "Random number";
    }
    

    And I think you can still condense the last two tests into one:

    $cleanQt = strtolower(removeAccents($qt));
    if ($cleanQt == "rand"){
      $result = rand(1,9999);
      $sndline = "Random number";
    }
    elseif ($cleanQt == "random"){
      $result = rand(1,9999);
      $sndline = "Random number";
    }
    elseif (preg_match("/^rand|random *\((?<min>[0-9]+),(?<max>[0-9]+)\)$/", $cleanQt), $match)){
      $result = rand($match['min'],$match['max']);
      $sndline = "Random number";
    }
    

    And, as qmechanik shows, you can merge the first two conditions:

    $cleanQt = strtolower(removeAccents($qt));
    if ($cleanQt == "rand" || $cleanQt == "random"){
      $result = rand(1,9999);
      $sndline = "Random number";
    }
    elseif (preg_match("/^rand|random *\((?<min>[0-9]+),(?<max>[0-9]+)\)$/", $cleanQt), $match)){
      $result = rand($match['min'],$match['max']);
      $sndline = "Random number";
    }
    
        
    16.05.2015 / 04:58
    4

    As mentioned by bfavaretto , the first if is unnecessary, because just below there is another if which does practically the same thing, except that the latter uses the function removeAccents .

  • You could save a few lines by declaring only once the variable sndline , outside the code block of if .

  • The code blocks of the first two if are the same, just as the last two are as well, use logical operator or to check on the same line.

    Note : You can also use the || operator, more information at What is the difference between "& &" and "||" and "and" and "or" in PHP? Which one to use?

  • Using the preg_match function in the first two if can be replaced by equality operator == ( === for something more rigid) or < a href="http://php.net/manual/en_US/function.strcmp.php"> strcmp , strcasecmp .

  • Another point that can be improved is to declare a variable that contains the value of strtolower(removeAccents($qt)) , so you avoid executing these functions several times unnecessarily. >

  • You use the preg_match function in the last two if to check whether the qt variable contains the word rand or random followed by numbers, you can replace it with the filter_var function, used to filter the contents of a string As you only want numbers, use as FILTER_SANITIZE_NUMBER_INT filter.

  • 16.05.2015 / 05:09