对象的行为就像一个数组? (PHP)

发布于 2024-09-24 14:06:15 字数 753 浏览 3 评论 0原文

我在 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 对象的基本知识我不知道。

有什么想法吗?提前致谢

I have seen something like this in an 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 />';
    }

How is it possible that an object acts as both array and object? How can I accomplish that?
I was hoping to see a new __magic method or something in Book's parent class, but I couldn't find anything, so there might be something really basic about php objects that I don't know.

Any thoughts? Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小姐丶请自重 2024-10-01 14:06:15

实现 Traversable 接口的对象(通过迭代器IteratorAggregate) 支持 foreach 构造,如果这就是您所说的“充当数组”的意思。例如:

class theClass implements Iterator {
    // implement iterator here
}

// now you can do
$obj = new theClass;

foreach ($obj as $value) {
    // do something
}

Objects that implement the Traversable interface (through Iterator or IteratorAggregate) support the foreach construct, if that's what you mean by "acting as an array." Eg:

class theClass implements Iterator {
    // implement iterator here
}

// now you can do
$obj = new theClass;

foreach ($obj as $value) {
    // do something
}
北音执念 2024-10-01 14:06:15

您无需执行任何特殊操作即可将 foreach 与对象一起使用。

来自对象迭代的 PHP 手册

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

可以实现迭代器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

因为 IteratorIteratorAggregate 扩展Traversable,您的类现在也将是 Traversable 的实例,但如上所示,不需要迭代该对象。

var_dump (new Foo instanceof Traversable); // TRUE

您还可以使用 ArrayObject 使对象表现得像一个混合体类和对象之间。或者您可以实现 ArrayAccess 以允许使用方括号访问类。您还可以将该类子类化为 PHP 提供的迭代器之一

进一步阅读:

You do not have to do anything special to use foreach with objects.

From the PHP manual on Object Iteration:

PHP 5 provides a way for objects to be defined so it is possible to iterate through a list of items, with, for example a foreach statement. By default, all visible properties will be used for the iteration.

Example:

class Foo
{
    public $foo = 1;
    protected $bar = 2;
    private $baz = 3;
}

foreach(new Foo as $prop) echo $prop; // outputs 1 only

Your class does not have to implement Traversable as suggested elsewhere and in fact, the class above doesn't:

var_dump (new Foo instanceof Traversable); // FALSE

You can implement one of the Iterator or IteratorAggregate if you need more control over how the iteration should behave:

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

Because Iterator and IteratorAggregate extend Traversable, your class will now also be an instance of Traversable, but like shown above, it's not necessary for iterating the object.

var_dump (new Foo instanceof Traversable); // TRUE

You can also use an ArrayObject to make the object behave like a hybrid between class and object. Or you can implement ArrayAccess to allow accessing the class with square brackets. You can also subclass the class to be one of the Iterators PHP provides.

Further reading:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文