我在ORM中看到过类似的东西:
$b = new Book();
$b->limit(5)->get();
echo 'ID: ' . $b->id . '<br />';
echo 'Name: ' . $b->title . '<br />';
echo 'Description: ' . $b->description . '<br />';
echo 'Year: ' . $b->year . '<br />';
foreach ($b as $book)
{
echo 'ID: ' . $book->id . '<br />';
echo 'Name: ' . $book->title . '<br />';
echo 'Description: ' . $book->description . '<br />';
echo 'Year: ' . $book->year . '<br />';
echo '<br />';
}
对象如何同时充当数组和对象?我怎么能做到这一点? 我本来希望在Book的父类中看到一个新的__magic方法,但是我找不到任何东西,所以可能有一些关于php对象的基本功能,我不知道。
有什么想法?提前致谢
答案 0 :(得分:12)
实现Traversable
接口(通过Iterator
或IteratorAggregate
)的对象支持foreach
构造,如果这是“充当数组”的意思。例如:
class theClass implements Iterator {
// implement iterator here
}
// now you can do
$obj = new theClass;
foreach ($obj as $value) {
// do something
}
答案 1 :(得分:6)
对于对象使用foreach
,您无需执行任何特殊操作。
来自PHP manual on Object Iteration:
PHP 5提供了一种定义对象的方法,因此可以使用例如foreach语句迭代项目列表。默认情况下,所有可见属性都将用于迭代。
示例:
class Foo
{
public $foo = 1;
protected $bar = 2;
private $baz = 3;
}
foreach(new Foo as $prop) echo $prop; // outputs 1 only
您的课程不必按照其他地方的建议实施Traversable
,事实上,上述课程不会:
var_dump (new Foo instanceof Traversable); // FALSE
如果您需要更多地控制迭代的行为方式,可以实施Iterator或IteratorAggregate之一:
class Foo implements IteratorAggregate
{
public $foo = 1;
protected $bar = 2;
private $baz = 3;
public function getIterator()
{
return new ArrayIterator((array) $this);
}
}
foreach(new Foo as $prop) echo $prop; // outputs 123
由于Iterator
和IteratorAggregate
扩展Traversable
,您的类现在也将成为Traversable
的实例,但如上所示,迭代对象不是必需的。
var_dump (new Foo instanceof Traversable); // TRUE
您还可以使用ArrayObject使对象的行为类似于类和对象之间的混合。或者,您可以实现ArrayAccess以允许使用方括号访问类。您还可以将该类子类化为PHP提供的one of the Iterators。
进一步阅读: