Home  >  Article  >  Backend Development  >  Detailed explanation of PHP interpreter mode usage

Detailed explanation of PHP interpreter mode usage

巴扎黑
巴扎黑Original
2017-08-23 13:41:262096browse

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:


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

in the input box of the front-end web page and then submit, the system will reply with a result similar to "Condition is established" or "Condition is not established" (somewhat similar to direct Write code in the foreground and run 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 the two lines of code above. Keyword process)

Although the above two lines of code are languages ​​invented by the author, they are not difficult to understand based on the literal meaning. The first line is to define a variable and assign a value, and the second line is to perform a function on the variable. Judgment (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. For example, 4, four, and the comparison result "true" or "false" in the above code are saved in the form of 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 have inheritance, combination or aggregation with other classes) 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 right to pretend to be B. , ha! For details, you can look at the class diagram of the original book)

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

in the first two self-created codes. The code is 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 value of the variable. For example, the first two The variable "input" and the value "4" in the sentence,

code are 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. 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 are equal expressions, or expressions, and expressions that inherit the OperatorExpression abstract base class respectively. There is only one method, doInterpret(), which 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. You can directly copy and paste and 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 '条件不成立';
}

Client code three:

This is the original client The difference between the 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 is the detailed content of Detailed explanation of PHP interpreter mode usage. 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