Because when a PHP object obtains a variable, when the member variable is not defined in the class, it calls PHP's unique magic method _ get, A magic method call is added.
There are four sample codes below. what do you think is the sorting speed of the object they create and get the member variables?
1: Set the member variable to public. assign a value to the member variable through the value assignment operation to directly obtain the variable.
class Foo { public $id; } $data = new Foo; $data->id = 10; echo $data->id;
2: Set the member variable to public. you can use the constructor to set the value of the member variable and directly obtain the variable.
class Foo2 { public $id; public function __construct($id) { $this->id = $id; } } $data = new Foo2(10); echo $data->id;
3: Set the member variable to protected, set the value of the member variable through the constructor, and get the variable through the member method
class Foo3 { protected $id; public function __construct($id) { $this->id = $id; } public function getId() { return $this->id; } } $data = new Foo3(10); echo $data->getId();
4: Set the member variable to protected, set the value of the member variable through the constructor, and obtain the variable through magic
class Foo4 { protected $id; public function __construct($id) { $this->id = $id; } public function __get($key) { return $this->id; } } $data = new Foo4(10); echo $data->id;
Sort by execution speed: 1243
Let's first look at its opcode:
1:
1 ZEND_FETCH_CLASS 4 :4 'Foo' 2 NEW $5 :4 3 DO_FCALL_BY_NAME 0 4 ASSIGN !0, $5 5 ZEND_ASSIGN_OBJ !0, 'id' 6 ZEND_OP_DATA 10 7 FETCH_OBJ_R$9 !0, 'id' 8 ECHO $9
2:
1 ZEND_FETCH_CLASS 4 :10 'Foo2' 2 NEW $11 :10 3 SEND_VAL 10 4 DO_FCALL_BY_NAME 1 5 ASSIGN !1, $11 6 FETCH_OBJ_R$14 !1, 'id' 7 ECHO $14
3:
1 ZEND_FETCH_CLASS 4 :15 'Foo3' 2 NEW $16 :15 3 SEND_VAL 10 4 DO_FCALL_BY_NAME 1 5 ASSIGN !2, $16 6 ZEND_INIT_METHOD_CALL !2, 'getId' 7 DO_FCALL_BY_NAME 0 $20 8 ECHO $20
4:
1 ZEND_FETCH_CLASS 4 :21 'Foo4' 2 NEW $22 :21 3 END_VAL 10 4 DO_FCALL_BY_NAME 1 5 ASSIGN !3, $22 6 FETCH_OBJ_R $25 !3, 'id' 7 ECHO $25
Based on the opcode above and its opcode implementation in the zend_vm_execute.h file, what can we find?
I. PHP kernel object creation process is divided into three steps:
- ZEND_FETCH_CLASS obtains the storage class variables based on the class name and implements a search operation for hashtalbe EG (class_table ).
- NEW initializes the object and points EX (call)-> fbc to the constructor pointer.
- Call the constructor. the call is the same as that of other functions. they call zend_do_fcall_common_helper_SPEC.
2. the magic method is triggered by a condition instead of a direct call. for example, to obtain the member variable id (zend_std_read_property) in our example, the procedure is as follows:
- Obtain the attributes of an object. if the object exists, go to step 2. if there is no relevant attribute, go to step 3.
- Check whether the property corresponding to the name exists from the properties of the object. if the returned result exists and does not exist, go to step 3.
- If the _ get magic method exists, call this method to obtain the variable. if it does not exist, an error is returned.
Back to sorting:
1. what is the difference between the first and second?
The second opcode is less than the first one, but slower than the first one, because the constructor has more parameters and one more parameter to process opcode. Parameter processing is a time-consuming operation. when code optimization is performed, some unnecessary parameters can be removed. when a function has multiple parameters, you can use an array to encapsulate it and pass it in.
2. Why is the third slowest?
Because its parameter acquisition is essentially a call to the object member method, the call cost of the method is higher than that of the variable.
3. Why is the fourth one faster than the third one?
Because the fourth operation actually obtains the variable, but calls the magic method internally, the call efficiency of the internal function is higher than that of the user-defined method. Therefore, when some PHP kernel implementation methods can be called, do not reinvent the wheel.
4. Why is the fourth one slower than the second one?
Because when a PHP object obtains a variable, when the member variable is not defined in the class, it calls PHP's unique magic method _ get, A magic method call is added.
Summary:
- Use PHP built-in functions
- It is not essential for object-oriented (OOP). object-oriented usually has a high overhead, and each method and object call consumes a lot of memory.
- Try to use less magic methods-unless necessary, do not use the framework, because the framework has a lot of magic methods to use.
- In performance-first application scenarios, setting member variables to public is a good method when you need to use OOP.
- If you can use PHP syntax structure, do not use functions. if you can use built-in functions, do not write them by yourself. if you can use functions, do not use objects.