<?php
class Field
{
private $value;
private $data;
/**
* @return mixed
*/
public function getData()
{
return $this->data;
}
/**
* @param mixed $data
*/
public function setData($data)
{
$this->data = $data;
}
public function getValue()
{
return $this->value;
}
public function setValue($value)
{
$this->value = $value;
}
public function __toString()
{
return $this->value;
}
}
class BaseModel implements Iterator, ArrayAccess
{
private $data;
/**
* @var ArrayIterator
*/
protected $iterator;
public function __construct()
{
$this->data = new StdClass();
$this->iterator = new ArrayIterator($this->data);
}
public function __set($key, $value)
{
if(!property_exists($this->data, $key)) {
$this->data->{$key} = new Field();
}
$this->data->{$key}->setValue($value);
}
public function __get($key)
{
if(property_exists($this->data, $key)) {
return $this->data->{$key};
}
return null;
}
public function __invoke()
{
echo "Invoke\n";
}
/**
* (PHP 5 >= 5.0.0)<br/>
* Return the current element
* @link http://php.net/manual/en/iterator.current.php
* @return mixed Can return any type.
*/
public function current()
{
return $this->iterator->current();
}
/**
* (PHP 5 >= 5.0.0)<br/>
* Move forward to next element
* @link http://php.net/manual/en/iterator.next.php
* @return void Any returned value is ignored.
*/
public function next()
{
$this->iterator->next();
}
/**
* (PHP 5 >= 5.0.0)<br/>
* Return the key of the current element
* @link http://php.net/manual/en/iterator.key.php
* @return mixed scalar on success, or null on failure.
*/
public function key()
{
return $this->iterator->key();
}
/**
* (PHP 5 >= 5.0.0)<br/>
* Checks if current position is valid
* @link http://php.net/manual/en/iterator.valid.php
* @return boolean The return value will be casted to boolean and then evaluated.
* Returns true on success or false on failure.
*/
public function valid()
{
return $this->iterator->valid();
}
/**
* (PHP 5 >= 5.0.0)<br/>
* Rewind the Iterator to the first element
* @link http://php.net/manual/en/iterator.rewind.php
* @return void Any returned value is ignored.
*/
public function rewind()
{
$this->iterator->rewind();
}
/**
* (PHP 5 >= 5.0.0)<br/>
* Whether a offset exists
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
* @param mixed $offset <p>
* An offset to check for.
* </p>
* @return boolean true on success or false on failure.
* </p>
* <p>
* The return value will be casted to boolean if non-boolean was returned.
*/
public function offsetExists($offset)
{
return property_exists($this, $offset);
}
/**
* (PHP 5 >= 5.0.0)<br/>
* Offset to retrieve
* @link http://php.net/manual/en/arrayaccess.offsetget.php
* @param mixed $offset <p>
* The offset to retrieve.
* </p>
* @return mixed Can return all value types.
*/
public function offsetGet($offset)
{
return $this->{$offset};
}
/**
* (PHP 5 >= 5.0.0)<br/>
* Offset to set
* @link http://php.net/manual/en/arrayaccess.offsetset.php
* @param mixed $offset <p>
* The offset to assign the value to.
* </p>
* @param mixed $value <p>
* The value to set.
* </p>
* @return void
*/
public function offsetSet($offset, $value)
{
$this->{$offset} = $value;
}
/**
* (PHP 5 >= 5.0.0)<br/>
* Offset to unset
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
* @param mixed $offset <p>
* The offset to unset.
* </p>
* @return void
*/
public function offsetUnset($offset)
{
unset($this->{$offset});
}
}
/**
* Class TestModel
* @property Field test
* @property Field test2
*/
class TestModel extends BaseModel
{
}
$t = new TestModel();
$t->test = 'test';
$t->test->setData('test data');
foreach ($t as $key => $value) {
echo $key, '->', $value, "(", $value->getData() ,")\n";
}