This article mainly sorts out the predefined interfaces of PHP. Four interfaces are commonly used in daily project processes: IteratorAggregate (aggregate aggregate iterator Iterator), Countable, ArrayAccess, and Iterator. Friends who need it can refer to it
There are several predefined interfaces in PHP, the four most commonly used interfaces (IteratorAggregate (aggregate aggregate iterator Iterator),Countable,ArrayAccess,Iterator) will be introduced to you in detail respectively.
IteratorAggregate (aggregate aggregate iterator) interface
IteratorAggregate extends Traversable { abstract public Traversable getIterator(void) }
This interface implements a function - creating an external iterator. How to understand it specifically? When we useforeachWhen traversing an object, if theIteratorAggregateinterface is not inherited, all public properties in the object will be traversed (only in the form of public $var). If you inheritIteratorAggregate, the object returned by thegetIteratormethod implemented in the class will be used. Note here that the returned object must be aTraversableobject or extend fromTraversableobject, otherwise an exception will be thrown
//看个例子 class My{ private $_data = [ 'a' => '燕睿涛', 'b' => 'yanruitao', 'c' => 'LULU', ]; public function getIterator() { return new ArrayIterator($this->_data); } } $obj = new My; foreach ($obj as $key => $value) { echo "$key => $value\n"; } //输出结果为空 class My implements IteratorAggregate { private $_data = [ 'a' => '燕睿涛', 'b' => 'yanruitao', 'c' => 'LULU', ]; public function getIterator() { return new ArrayIterator($this->_data); } } $obj = new My; foreach ($obj as $key => $value) { echo "$key => $value\n"; } //结果: a => 燕睿涛 b => yanruitao c => LULU
Countable interface
Countable { abstract public int count(void) }
This interface is used to count the number of objects. How to understand it specifically? When When we callcounton an object, if the function does not inheritCountable, it will always return 1. If it inheritsCountable, it will return the implementedcount.The number returned by the method, look at the following example:
class CountMe { protected $_myCount = 3; public function count() { return $this->_myCount; } } $countable = new CountMe(); echo count($countable); //返回1 class CountMe implements Countable { protected $_myCount = 3; public function count() { return $this->_myCount; } } $countable = new CountMe(); echo count($countable); //返回3 ArrayAccess接口 ArrayAccess { abstract public boolean offsetExists(mixed $offset) abstract public mixed offsetGet(mixed $offset) public void offsetSet(mixed $offset, mixed $value) public void offsetUnset(mixed $offset) } class CountMe { protected $_myCount = 3; public function count() { return $this->_myCount; } } $countable = new CountMe(); echo count($countable); //返回1 class CountMe implements Countable { protected $_myCount = 3; public function count() { return $this->_myCount; } } $countable = new CountMe(); echo count($countable); //返回3
ArrayAccess interface
ArrayAccess { abstract public boolean offsetExists(mixed $offset) abstract public mixed offsetGet(mixed $offset) public void offsetSet(mixed $offset, mixed $value) public void offsetUnset(mixed $offset) }
The function of this interface is to allow us to access it like an array Object, how should I put this? I guess it is actually that if PHP encounters an array when using an object during lexical analysis, it will go back to the object to find whether ArrayAccess is implemented. If so, perform the corresponding operations (set, unset, isset, get), so that we can place an array in the class and let the class implement the basic operations of the array. Here is an example:
class myObj { } $obj = new myObj; $obj['name']; //Fatal error: Cannot use object of type myObj as array in class myObj implements ArrayAccess { public function offsetSet($offset, $value) { echo "offsetSet : {$offset} => {$value}\n"; } public function offsetExists($offset) { echo "offsetExists : {$offset}\n"; } public function offsetUnset($offset) { echo "offsetUnset : {$offset}\n"; } public function offsetGet($offset) { echo "offsetGet : {$offset}\n"; } } $obj = new myObj; $obj[1] = '燕睿涛'; isset($obj['name']); unset($obj['name']); $obj['yrt']; //输出结果: offsetSet : 1 => 燕睿涛 offsetExists : name offsetUnset : name offsetGet : yrt class myObj implements ArrayAccess { private $_data = []; public function offsetSet($offset, $value) { $this->_data[$offset] = $value; } public function offsetExists($offset) { return isset($this->_data[$offset]); } public function offsetUnset($offset) { unset($this->_data[$offset]); } public function offsetGet($offset) { return $this->_data[$offset]; } } $obj = new myObj; $obj['yrt'] = '燕睿涛'; var_dump($obj['yrt']); var_dump(isset($obj['yrt'])); unset($obj['yrt']); var_dump(isset($obj['yrt'])); var_dump($obj['yrt']); //输出: string(9) "燕睿涛" bool(true) bool(false) Notice: Undefined index: yrt //最后一个会报出Notice
The above object can only be used for basic array operations, even traversal Neither works. It can be combined with the previousIteratorAggregateforeach:
class myObj implements ArrayAccess, IteratorAggregate { private $_data = []; public function getIterator() { return new ArrayIterator($this->_data); } ...... } $obj = new myObj; $obj['yrt'] = '燕睿涛'; $obj[1] = '燕睿涛'; $obj['name'] = '燕睿涛'; $obj['age'] = 23; foreach ($obj as $key => $value) { echo "{$key} => {$value}\n"; } //输出: yrt => 燕睿涛 1 => 燕睿涛 name => 燕睿涛 age => 23
Iterator interface:
Iterator extends Traversable { abstract public mixed current(void) abstract public scalar key(void) abstract public void next(void) abstract public void rewind(void) abstract public boolean valid(void) }
can be iterated internally The interface of your own external iterator or class. This is the explanation given by the official document. It is still difficult to understand. In fact, I feel that the function implemented by this interface is the same astrratorAggregate(Document: Create an external iterator interface , the interface directly returns an iterator) is similar, but this is implemented in the class definition. Let’s look at an example:
class myObj implements Iterator{ private $_data = []; public function __construct(Array $arr) { $this->_data = $arr; } public function current() { return current($this->_data); } public function key() { return key($this->_data); } public function next() { next($this->_data); } public function rewind() { reset($this->_data); } public function valid() { return $this->key() !== NULL; } } $t = [ 'yrt' => '燕睿涛', 'name' => '燕睿涛', false, '燕睿涛' ]; $obj = new myObj($t); foreach ($obj as $key => $value) { echo "{$key} => ".var_export($value, true)."\n"; } //输出: yrt => '燕睿涛' name => '燕睿涛' 0 => false 1 => '燕睿涛'
The above refers to an article by Brother Niao about a test question (Iterator mode) , but Brother Bird’s judgment of valid is a bit flawed. When it encounters a value that is false, it will be truncated
Summary
After talking so much, it seems that I still haven’t realized their usefulness. I suggest you take a look. The source code of Yii2 uses a lot of these things in the source code. After reading it, you will slowly feel "oh~ it seems to be really useful..."
The above is the entire content of this article, I hope it will be useful Everyone’s learning is helpful. For more related content, please pay attention to the PHP Chinese website!
Related recommendations:
How to get the current page URL function through PHP
How to prevent users from entering the code directly in the php background analyze
The above is the detailed content of PHP predefined interface analysis. For more information, please follow other related articles on the PHP Chinese website!