Recently reading the book "Core technology and best practices in PHP", the first chapter of the book mentions the use of the __call () method to implement a simple string chain operation, for example, the following filter string and then the operation of the length, it is generally written like this:
Strlen (Trim ($STR));
So can you make the following notation?
$str->trim ()->strlen ();
Let's try it down here.
Chained operation, plainly speaking, is actually a chain-like method of calling an object. Now that you want to implement a chained operation of a string, implement a string class and invoke the object of that class. My expectations for the string class are as follows: (1) When I create an object, I can assign a string to the object's properties, and I can access the property's read value, (2) I can call the trim () and strlen () methods, and (3) I can call the method $str->trim ()- >strlen ().
The above article (1) is a basic requirement for a string class. Let's get this implemented:
Class string{public $value; Public function __construct ($str =null) { $this->value = $str; }}
You can try the following:
1 $str = new String (' 01389 ');
2 echo $str->value;
Then look at 2nd, first put $str->trim () realized, reference books in the idea: Trigger __call method and then execute call_user_func. The code is as follows:
Class string{public $value; Public function __construct ($str =null) { $this->value = $str; } Public Function __call ($name, $args) { $this->value = Call_user_func ($name, $this->value, $args [0]); return $this; }}
Under test:
1 $str = new String (' 01389 ');
2 echo $str->trim (' 0 ')->value;
The results are as follows:
It is important to note that line 12th: $this->value = Call_user_func ($name, $this->value, $args [0]); $name is the name of the callback function (in this case, trim), the following two are the parameters of the callback function (Tirm), and the order of the parameters should not be reversed. $args is an array, and you need to be aware of it.
2nd in the implementation of strlen (), then the above code in the 13th line is very critical: return $this; It does this by calling trim () on line 12th to re-assign the Value property after processing the string, and then returning a reference to the current object so that the other methods within the object can perform continuous operations on the property value, and the chain operation is implemented. $str->strlen () is implemented as follows:
Class string{public $value; Public function __construct ($str =null) { $this->value = $str; } Public Function __call ($name, $args) { $this->value = Call_user_func ($name, $this->value, $args [0]); return $this; } Public Function strlen () { return strlen ($this->value);} }
Under test:
1 $str = new String (' 01389 ');
2 echo $str->strlen ();
Results:
Chained operation:
echo $str->trim (' 0 ')->strlen ();
Results:
Class string{public $value; Public function __construct ($str =null) { $this->value = $str; } Public function Trim ($t) { $this->value = Trim ($this->value, $t); return $this; } Public Function strlen () { return strlen ($this->value);} }
The key to chain operation is to return $this after the operation has been done.
In addition, this article is inspired by this article in the garden, replacing the call_user_func () implementation with Call_user_func_array () and modifying the __call () method as follows.
Public Function __call ($name, $args) { array_unshift ($args, $this->value); $this->value = Call_user_func_array ($name, $args); return $this; }
The effect is the same as the __call () method above, so the code seems to be more elegant than the previous implementation.
Summarize:
__call () is triggered when an object calls an inaccessible method, so the creation of a dynamic method of the class can be implemented, implementing PHP's method overloading function, but it is actually a syntactic sugar (__construct () method is also).
So if there is no __call () and other syntactic sugars, can the creation of dynamic methods and chain operation? I think there are several aspects of the question: whether the class method exists and can be called, this can be implemented by Method_exists, Is_callable, Get_class_methods, and so on, in addition to the creation of the object when the property is assigned (initialized), This syntactic sugar is really handy, but it's not necessary. Wait until you have time to study it.