Внутренняя работа PHP ArrayObject
Где я могу найти полный исходный код ArrayObject (на PHP)?
Чего я не понимаю, так это почему вы можете использовать "стрелку" при добавлении элемента в свой объект ArrayObject, например:
$a = new ArrayObject();
$a['arr'] = 'array data';
$a->prop = 'prop data'; //here it is
Вы можете видеть, что используется $a->prop = 'prop data';
.
Существует ли какой-либо волшебный метод или что было использовано, и как PHP, например, знает, что $a['prop']
и $a->prop
означают одно и то же? (в этом контексте)
1 answers
Да, это волшебство, и его можно выполнить непосредственно в PHP. Взгляните на Перегрузку http://www.php.net/manual/en/language.oop5.overloading.php
Для этого вы можете использовать __get()
и __set
в классе. Чтобы заставить объекты вести себя как массивы, вам необходимо реализовать http://www.php.net/manual/en/class.arrayaccess.php
Вот мой пример кода:
<?php
class MyArrayObject implements Iterator, ArrayAccess, Countable
{
/** Location for overloaded data. */
private $_data = array();
public function __set($name, $value)
{
$this->_data[$name] = $value;
}
public function __get($name)
{
if (array_key_exists($name, $this->_data)) {
return $this->_data[$name];
}
$trace = debug_backtrace();
trigger_error(
'Undefined property via __get(): ' . $name .
' in ' . $trace[0]['file'] .
' on line ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
/** As of PHP 5.1.0 */
public function __isset($name)
{
return isset($this->_data[$name]);
}
/** As of PHP 5.1.0 */
public function __unset($name)
{
unset($this->_data[$name]);
}
public function offsetSet($offset, $value) {
if (is_null($offset)) {
$this->_data[] = $value;
} else {
$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 isset($this->_data[$offset]) ? $this->_data[$offset] : null;
}
public function count(){
return count($this->_data);
}
public function current(){
return current($this->_data);
}
public function next(){
return next($this->_data);
}
public function key(){
return key($this->_data);
}
public function valid(){
return key($this->_data) !== null;
}
public function rewind(){
reset($this->_data);
}
}
Вместо current($a)
, next($a)
использовать $a->current()
, $a->next()