Home  >  Article  >  Backend Development  >  Detailed explanation of PHP object-oriented interpreter mode

Detailed explanation of PHP object-oriented interpreter mode

墨辰丷
墨辰丷Original
2018-05-22 15:13:321359browse

The following editor will bring you a cliché about the object-oriented interpreter mode of PHP. The editor thinks it’s pretty good, so I’ll share it with you now and give it as a reference. Let’s follow the editor to have a look

Recently I was reading "In-depth PHP Object-Oriented Pattern and Practice". After studying the content in the book, I instantly felt that I was a bit advanced, ha! In fact, it's still a bad idea. I believe that there will be novice friends reading this book (I am also a novice). I would like to share and exchange my learning experience on the content in the book that I personally think is difficult. 1. I hope that it can consolidate the knowledge I have learned. and the role of deepening understanding 2. I hope it will be helpful to novice friends who read this article and are interested.

I have read this part several times and typed the code several times. It is estimated that the function that this article wants to achieve is that the user inputs some content on the web page, and then parses it through the background program to reply (it feels like That’s nonsense). For example, if I enter in the input box of the front-end web page:

$input = "4";
$input equals "4" or $input equals "four";

and then submit, the system will reply with a result similar to "Condition is true" or "Condition is not true" ( It is somewhat similar to writing code directly in the foreground and running it, and a result will be returned after background parsing. Although the original book does not explain the entire process of front-end input to background parsing, I guess this background parsing should also use regular expressions to extract something similar to 2 above. The process of keywords in lines of code)

Although the above two lines of code are the language invented by the author, it is not difficult to understand based on the literal meaning. The first line defines a variable and assigns a value, and the second line The variable performs a judgment (the variable is equal to 4 or equal to four).

Without further ado, let’s take a look at the classes defined by this pattern (please read the original text for the class diagram yourself):

1. interpreterContext This class is like an Container is mainly used to store and obtain the values ​​and comparison results that need to be compared, such as 4, four, and the comparison result "true" or "false" in the above code. The storage form is an array. That is, the attribute $expressionstore of the class, the code is as follows:

class InterpreterContext{
  private $expressionstore = array(); //存放比较的值和结果
  
  function replace(Expression $exp,$value){    // 设置值
    $this->expressionstore[$exp->getKey()] = $value;
  }
  
  function lookup(Expression $exp){        //获取值
    return $this->expressionstore[$exp->getKey()];
  }
}

This class is like a tool for other classes to use (it does not inherit from other classes, combination or aggregation relationship).

2. Expression This is an abstract class of expression, which defines the abstract method interpret() and the method getKey()

The code is as follows :

abstract class Expression {
  private static $keycount = 0;  //计数用的
  private $key;          //存放一个唯一值


  //主要实现将前台获取到的数据存放到上述InterpreterContext类中的功能,看到下面的内容就会发现继承他的类调用了InterpreterContext类的replace()方法
  abstract function interpret (InterpreterContext $context); 

 //获取一个唯一值  
  function getKey(){       
    if(!isset($this->key)){
      self::$keycount++;
      $this->key= self::$keycount;
    }
    return $this->key;
  }
}

The classes to be discussed below will inherit this class, and it has a combined relationship with OperatorExpression (operator expression abstract class). That is to say, OperatorExpression can include all subclasses that inherit Expression during initialization (this is also what this book has been emphasizing on interface-oriented programming. This Expression is an interface. Polymorphism can be achieved using this interface. I don’t know if I am pretending to be B. Is that correct? Ha! You can check the class diagram in the original book for details)

3. LiteralExpression Literal Expression class, its function is to save a string into the small container of InterpreterContext , saved as an index array, for example, save the 4 or four

in the first two sentences of self-created code as follows:

class LiteralExpression extends Expression{
  private $value;  
  function __construct ($value){      //初始化时传入要保存的值
    $this->value= $value;
  }
  function interpret(InterpreterContext $context){    //调用InterpreterContext类的replace()将$value保存到InterpreterContext这个小容器里
    $context->replace($this,$this->value);
  }
}

4. VariableExpression variable expression class has the same function as the above class, except that the data will be saved as an associative array. The key in the associative array is the variable name, and the value is the variable. value, such as the variable "input" and the value "4" in the first two sentences,

The code is as follows:

class VariableExpression extends Expression{
  private $name;    //变量名
  private $val;      //变量值
  
  function __construct ($name,$val=null){
    $this->name = $name;
    $this->val = $val;
  }
  
  function interpret(InterpreterContext $context){
    if(!is_null($this->val)){
      $context->replace($this,$this->val);
      $this->val = null;
    }
  }
  
  function setValue($value){  //用于设置变量的值
    $this->val = $value;
  }
  
  function getKey(){    //这个复写了父类的getKey()方法,在小容器InterpreterContext的lookup()方法调用这个类的实例的getKey()方法时 它将返回一个字符串(即变量名)而不是数字索引
    return $this->name;
  }
}

5. OperatorExpression operator expression abstract base class, this class inherits and combines the Expression abstract base class, and the implemented interpret() method mainly saves the calculation results of the expression

The code is as follows:

abstract class OperatorExpression extends Expression{
protected $l_op;  //表达式左边的值
protected $r_op;  //表达式右边的值

function __construct (Expression $l_op,Expression $r_op){    //初始化时可组合继承了Expression类的子类实例
$this->l_op = $l_op;
$this->r_op = $r_op;
}

function interpret(InterpreterContext $context){  //主要用于保存表达试的结果(保存到InterpreterContext 类的实例中)
$this->l_op->interpret($context);        //将Expression子类实例的值或计算结果保存到InterpreterContext 类的实例中
$this->r_op->interpret($context);
$result_l = $context->lookup($this->l_op);    //获取上一步的值或计算结果
$result_r = $context->lookup($this->r_op);
$this->doInterpret($context,$result_l,$result_r);  //具体的比较运算由继承的子类来实现
}

protected abstract function doInterpret(InterpreterContext $context,$result_l,$result_r);

}

##6. EqualsExpression, BooleanOrExpression, and BooleanAndExpression respectively inherit the OperatorExpression abstract base class There is only one method for equal expressions, or expressions, and expressions. doInterpret() internally calls the replace() method of the InterpreterContext class to save the calculation result of the expression to an instance of the InterpreterContext class.

The code is as follows:

//相等表达式
class EqualsExpression extends OperatorExpression {
protected function doInterpret(InterpreterContext $context,$result_l,$result_r){
$context->replace($this,$result_l == $result_r);
}
}

//或表达式
class BooleanOrExpression extends OperatorExpression{
protected function doInterpret(InterpreterContext $context,$result_l,$result_r){
$context->replace($this,$result_l || $result_r);
}
}


//与表达式
class BooleanAndExpression extends OperatorExpression{
protected function doInterpret(InterpreterContext $context,$result_l,$result_r){
$context->replace($this,$result_l && $result_r);
}
}

So far, the classes related to this mode have been introduced. The above codes have been tested and can be copied and pasted directly. Run to see the results. Now let’s take a look at the client code:

Client code one:

$context = new InterpreterContext();

$statement = new BooleanOrExpression (  //可尝试将此操作符表达式换成BooleanAndExpression 运行一下 看看执行结果

//可尝试将LiteralExpression中实例化的参数改成其他值看看运算结果,或者直接将EqualsExpression对象换成BooleanOrExpression 或BooleanAndExpression 
new EqualsExpression(new LiteralExpression('four'),new LiteralExpression('four')), 

new EqualsExpression(new LiteralExpression('b'),new LiteralExpression('4'))
);

$statement->interpret($context);
if($context->lookup($statement)){
echo '条件成立';
} else {
echo '条件不成立';
}

Client code two

$context = new InterpreterContext();

$statement = new BooleanOrExpression(
new BooleanAndExpression(
new EqualsExpression(new LiteralExpression('4'),new LiteralExpression('4')),
new EqualsExpression(new LiteralExpression('4'),new LiteralExpression('4'))
),
new EqualsExpression(new LiteralExpression('b'),new LiteralExpression('4'))
);

$statement->interpret($context);
if($context->lookup($statement)){
echo '条件成立';
} else {
echo '条件不成立';
}

Customer Terminal code three:

The difference between this is the original client code example and the above client code is the use of variable expression VariableExpression

$context = new InterpreterContext();    
$input = new VariableExpression('input');  //这里定义了一个变量input 但并未赋值

$statement = new BooleanOrExpression(
new EqualsExpression($input,new LiteralExpression('four')),  //这里变量表达式和文字表达式的值将进行一个是否相等的比较
new EqualsExpression($input,new LiteralExpression('4'))
);

foreach (array("four","4","52") as $val){
$input->setValue($val);        //对input这个变量赋值
print "变量input的值为:$val:<br/>";
$statement->interpret($context);  //进行比较并将比较结果存入InterpreterContext对象实例
if($context->lookup($statement)){  //获取比较的结果
print "条件成立 <br/>";
} else {
print "条件不成立 <br/>";
}
}

The above code can run normally after testing. Friends in need can copy it and run it to see the results.

Related recommendations:

PHPInterpreter ModeDetailed Usage

php Design PatternInterpreter modeIn-depth analysis and detailed explanation

PHP object-oriented advanced design mode: Interpreter modeUsage examples

The above is the detailed content of Detailed explanation of PHP object-oriented interpreter mode. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn