【问题标题】:Object acting like an array? (PHP)对象像一个数组? (PHP)
【发布时间】:2010-09-21 05:42:43
【问题描述】:

我在 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 对象的非常基本的东西。

有什么想法吗?提前致谢

【问题讨论】:

    标签: php arrays orm object


    【解决方案1】:

    您不必做任何特别的事情就可以将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
    

    如果您需要更多地控制迭代的行为方式,您可以实现IteratorIteratorAggregate 之一:

    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 以允许使用方括号访问该类。您还可以将该类子类化为one of the Iterators PHP 提供的。

    进一步阅读:

    【讨论】:

      【解决方案2】:

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

      class theClass implements Iterator {
          // implement iterator here
      }
      
      // now you can do
      $obj = new theClass;
      
      foreach ($obj as $value) {
          // do something
      }
      

      【讨论】:

      • 其实每个对象都可以用foreach来处理,但是它会访问所有的公共属性。如果你想改变这种行为,你需要实现Iterator。您可能感兴趣的另一个界面是ArrayAccess
      猜你喜欢
      • 2010-09-09
      • 2021-04-14
      • 1970-01-01
      • 2013-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-07
      相关资源
      最近更新 更多