PHP object-oriented interpreter mode, php object-oriented Interpreter

Source: Internet
Author: User

PHP object-oriented interpreter mode, php object-oriented Interpreter

I have been visiting the blog for more than a year. I have always read articles but have never published any articles. The main reason is that the technology is too good, and there is only a learning part, so there is nothing to share with you at that level. However, I recently read "going deep into PHP object-oriented models and practices". After learning the content in the book, I felt a little too tall! It's actually a dish B. I believe there will also be new friends reading this book (I am also a newbie). I personally want to share and exchange my learning experiences on the content that I personally think is more difficult in this book, 1. I hope to consolidate and deepen my understanding of what I have learned. 2. I hope to help new users who are interested in this article.

This part of content has been read several times and followed several times. It is estimated that the function to be implemented in this article is probably to enter some content on the web page, then, the system will reply after parsing through the background program (the feeling is nonsense ). For example, in the front-end web page input box, enter:

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

After the submission, the system will reply the result similar to "condition is true" or "condition is not true" (a bit similar to writing code directly at the front end and running it, a result will be returned after parsing in the background. Although the original book did not explain the process of entering the entire front-end to the background parsing, I guess this background parsing should also have a process of extracting keywords similar to the above two lines of code using regular expressions)

Although the above two lines of code were invented by the author, it is not difficult to understand the literal meaning. The first line is to define a variable and assign values, the second line is to make a judgment on the variable (the variable is equal to 4 or equal to four ).

Not much nonsense. Let's take a look at the classes defined in this mode (for the class diagram, see the original article ):

1. The interpreterContext class is like a container mainly used to store and obtain the values to be compared and the results to be compared, such as 4, four, and the comparison result is "true" or "false", which is saved in the form of an array, that is, the class attribute $ expressionstore. The Code is as follows:

Class InterpreterContext {
Private $ expressionstore = array (); // store the comparison values and results

Function replace (Expression $ exp, $ value) {// set the value
$ This-> expressionstore [$ exp-> getKey ()] = $ value;
}

Function lookup (Expression $ exp) {// get the value
Return $ this-> expressionstore [$ exp-> getKey ()];
}
}

This class is like a tool for other classes (it has no inheritance, combination, or aggregation relationship with other classes ).

2. Expression is an abstract class of an Expression. The following code defines the abstract method interpret () and method getKey:

Abstract class Expression {
Private static $ keycount = 0; // used for counting
Private $ key; // store a unique value


// The main function is to store the data obtained from the front-end to the InterpreterContext class. When you see the following content, you will find that the inherited class calls the replace () method of the InterpreterContext class.
Abstract function interpret (InterpreterContext $ context );

// Obtain a unique value
Function getKey (){
If (! Isset ($ this-> key )){
Self: $ keycount ++;
$ This-> key = self: $ keycount;
}
Return $ this-> key;
}
}

The classes to be discussed below will all inherit this class, and they and OperatorExpression (operator expression abstract class) are a combination relationship, that is to say, OperatorExpression can contain all subclasses that inherit Expression during initialization (this is also the book's emphasis on interface-oriented programming. This Expression is an interface, which can be used to achieve polymorphism, I don't know what I said when I installed B! For details, refer to the class diagram of the original book)

3. LiteralExpression text expression class, which stores a string in the small container of InterpreterContext and stores it as an index array, for example, save the 4 or four code in the first two sentences of your own Code as follows:

Class LiteralExpression extends Expression {
Private $ value;
Function _ construct ($ value) {// input the value to be saved during initialization
$ This-> value = $ value;
}
Function interpret (InterpreterContext $ context) {// call the replace () of the InterpreterContext class to save $ value to the small container InterpreterContext.
$ Context-> replace ($ this, $ this-> value );
}
}

Iv. VariableExpression: Variable expression class. It is the same as the above class, except that the data will be saved as an associated array. The key in the associated array is the variable name, and the value is the value of the variable, for example, the variable "input" and value "4" in the first two sentences, the Code is as follows:

Class VariableExpression extends Expression {
Private $ name; // variable name
Private $ val; // variable value

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) {// used to set the value of a Variable
$ This-> val = $ value;
}

Function getKey () {// This rewrites the getKey () method of the parent class, and calls the getKey () method of the instance of this class in the lookup () method of InterpreterContext of the small container () it returns a string (that is, the variable name) instead of a numeric index.
Return $ this-> name;
}
}

5. OperatorExpression operator Expression abstraction base class. This class inherits and combines the Expression abstraction base class. The implemented interpret () method mainly saves the calculation result of the Expression. The Code is as follows:

Abstract class OperatorExpression extends Expression {
Protected $ l_op; // value on the left of the expression
Protected $ r_op; // The value on the right of the expression

Function _ construct (Expression $ l_op, Expression $ r_op) {// a subclass instance that inherits the Expression class can be combined during initialization.
$ This-> l_op = $ l_op;
$ This-> r_op = $ r_op;
}

Function interpret (InterpreterContext $ context) {// mainly used to save the result of the expression test (saved to an instance of the InterpreterContext class)
$ This-> l_op-> interpret ($ context); // Save the value or calculation result of the Expression subclass instance to an instance of the InterpreterContext class.
$ This-> r_op-> interpret ($ context );
$ Result_l = $ context-> lookup ($ this-> l_op); // obtain the value or calculation result of the previous step.
$ Result_r = $ context-> lookup ($ this-> r_op );
$ This-> doInterpret ($ context, $ result_l, $ result_r); // The comparison operation is implemented by the inherited subclass.
}

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

}

6. Expression sexpression, BooleanOrExpression, and BooleanAndExpression are equal expressions that inherit the OperatorExpression abstract base class, or expressions. There is only one method with the expression, doInterpret () internally calls the replace () of the InterpreterContext class () method To save the expression calculation result to an instance of the InterpreterContext class. The Code is as follows:

// Equal expression
Class extends sexpression extends OperatorExpression {
Protected function doInterpret (InterpreterContext $ context, $ result_l, $ result_r ){
$ Context-> replace ($ this, $ result_l = $ result_r );
}
}

// Or expression
Class BooleanOrExpression extends OperatorExpression {
Protected function doInterpret (InterpreterContext $ context, $ result_l, $ result_r ){
$ Context-> replace ($ this, $ result_l | $ result_r );
}
}


// And Expression
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 code has been tested. You can copy and paste it directly to view the results. Now let's take a look at the client code:

Client code 1:

$ Context = new InterpreterContext ();

$ Statement = new BooleanOrExpression (// you can try to replace this operator expression with BooleanAndExpression and run it to see the execution result.

// You can try to change the instantiated parameter in LiteralExpression to another value to view the operation result, or change the value of the extensexpression object to BooleanOrExpression or booleandexpression.
New response sexpression (new LiteralExpression ('four '), new LiteralExpression ('four ')),

New response sexpression (new LiteralExpression ('B'), new LiteralExpression ('4 '))
);

$ Statement-> interpret ($ context );
If ($ context-> lookup ($ statement )){
Echo 'condition true ';
} Else {
Echo 'condition not true ';
}

 

Client Code 2:

$ Context = new InterpreterContext ();

$ Statement = new BooleanOrExpression (
New BooleanAndExpression (
New Short sexpression (new LiteralExpression ('4'), new LiteralExpression ('4 ')),
New response sexpression (new LiteralExpression ('4'), new LiteralExpression ('4 '))
),
New response sexpression (new LiteralExpression ('B'), new LiteralExpression ('4 '))
);

$ Statement-> interpret ($ context );
If ($ context-> lookup ($ statement )){
Echo 'condition true ';
} Else {
Echo 'condition not true ';
}

Client code 3:

The difference between the original client code instance and the preceding client code is that the variable expression VariableExpression is used.

$ Context = new InterpreterContext ();
$ Input = new VariableExpression ('input'); // The input variable is defined but not assigned a value.

$ Statement = new BooleanOrExpression (
New Short sexpression ($ input, new LiteralExpression ('four '), // check whether the values of the variable expression and the text expression are equal.
New response sexpression ($ input, new LiteralExpression ('4 '))
);

Foreach (array ("four", "4", "52") as $ val ){
$ Input-> setValue ($ val); // assign values to the input variable
Print "variable input value: $ val: <br/> ";
$ Statement-> interpret ($ context); // compare and save the comparison result to the InterpreterContext object instance.
If ($ context-> lookup ($ statement) {// obtain the comparison result
Print "condition true <br/> ";
} Else {
Print "the condition is not true <br/> ";
}
}

The above code can run normally after testing. If you need it, you can copy it and run it to check the results. Finally, I borrowed a sentence from the Ancients to encourage them: "The road is long, and I will go up and down to seek help "!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.