【问题标题】:Arrayaccess, Iterator and current()数组访问、迭代器和 current()
【发布时间】:2012-02-06 20:29:37
【问题描述】:

我有实现 Countable、ArrayAccess、Iterator 和 Serializable 的类。 我有一个数组形式的公共变量 $data。还有我的迭代实现:

public function rewind() { return reset($this->data); }
public function current() { return current($this->data); }
public function key() { return key($this->data); }
public function next() { return next($this->data); }
public function valid() { return isset($this->data[$this->key()]); }

好吧,一切都适用于 foreach 循环,但如果我手动调用 current($arrayObject),它会返回整个 $data 数组,而不是其中的当前数组。我可以做到current($arrayObject->data),但希望尽可能保留原生数组功能。

这是 php 行为对吗? (不是我的代码错误)是否有任何解决方法,没有自定义功能(手指交叉)?

[编辑]完整类的简化版本(工作):

$arrayObject = mysqli_fetch_object($this->result_id, "simpleMysqliResult ", array(array(
        "fields" => array( "field1", "field2", "field3" )
    )));
class simpleMysqliResult implements Countable, ArrayAccess, Iterator, Serializable {

    public $data = array();

    public function __construct($input) {
        extract($input);
        foreach ($fields as $field) {
            $this->data[$field] = $this->{$field};
            unset($this->{$field});
        }
    }

    public function &toArray() { return $this->data; }
    public function offsetGet($index) { return $this->data[$index]; }
    public function offsetSet($index, $value) { $this->data[$index] = $value; }
    public function offsetUnset($index) { unset($this->data[$index]); }
    public function offsetExists($index) { return $this->offsetGet($index) !== null; }
    public function count() { return count($this->data); }
    public function rewind() { return reset($this->data); }
    public function current() { return current($this->data); }
    public function key() { return key($this->data); }
    public function next() { return next($this->data); }
    public function valid() { return isset($this->data[$this->key()]); }
    public function serialize() { return serialize($this->data); }
    public function unserialize($str) { return $this->data = unserialize($str); }

    public function __call($func, $argv) {
        if (!is_callable($func) || substr($func, 0, 6) !== 'array_')
        {
            throw new BadMethodCallException(__CLASS__.'->'.$func);
        }
        return call_user_func_array($func, array_merge(array($this->data), $argv));
    }

}

【问题讨论】:

  • 显示完整的课程。我见过类似的实现,效果很好。
  • 添加,简化了一点,另外,我正在扩展这个类,但只覆盖 Arrayacces 实现
  • 你考虑过扩展ArrayObject吗?它提供了许多您需要的功能。
  • 我正在使用我自己的实现原因是需要 $data 在数组中而不是对象参数中。我正在用我在这里复制的这个类扩展 mysqliResult 类,并且在 offsetSet() 和 offetGet() 中进行了一些逻辑。这也将mysql变量与对象变量隔离开来。现在新类有 8 个变量 + 2 个静态变量。并且在这 8 个中可以匹配一个 mysql 字段名称。

标签: php iteration arrayaccess


【解决方案1】:

尝试将您的数据置于私密模式。我怀疑你有一个外部程序在玩它并对其进行更改。我复制了您的课程并稍微更改了您的构造函数,因为我没有与您相同的输入,并且没有出现奇怪的行为。最终,您可能还想了解为什么您也提取($input),只需使用您认为合适的 $input['fields'] 或 $input->fields,它仍然可以工作。

以下是我的更正:

private $data = array();

public function __construct($input) {
    foreach($input['fields'] as $field) {
        $this->data[$field] = $input[$field];
    }
}

这是我的测试

$data = array('fields' => array('id', 'name'), 'id' => 1, 'name' => 'Franco');
$smr = new simpleMysqliResult($data);
var_dump($smr->current());
var_dump($smr->current());
var_dump($smr->current());
var_dump($smr->current());
var_dump($smr->next());
var_dump($smr->current());
var_dump($smr->current());

我的输出没问题

int(1) int(1) int(1) int(1) string(6) "Franco" string(6) "Franco" string(6) "Franco" 

所以就像我说的,我认为您的问题主要在于您的 $data 是公开的,并且有其他东西正在使用它。

它存在于你的构造函数中,我必须修复它以使其在我身边工作。

祝你好运

【讨论】:

  • Ups,没有仔细看,你使用的是$smr->current(),我想这对我有用,但我的问题与current($smt)..
  • 是的,使用 $smr->current() 它适用于但 current($smt)。如果我将 $data 作为私有然后 current($smt) 输出一个空数组。所以我想要完成的事情还没有得到 php 的支持。再见向后兼容性..
  • 哦,好吧,是的,我认为你做不到。当您在对象上调用 current 时,不会自动调用类中的 current 函数。 current() 实现仅适用于迭代器实现,因此 FOREACH 可以正常工作。我没听懂你的问题。我不认为存在任何可能的 SPL 实现,让我看看以防万一,但我认为你不能这样做
  • 答案是否定的,似乎没有任何 SPL 功能允许您在对象上使用 CURRENT 并将其映射到对象中的当前函数,对此感到抱歉...
猜你喜欢
  • 2022-11-14
  • 1970-01-01
  • 2017-07-03
  • 1970-01-01
  • 2017-09-02
  • 1970-01-01
  • 2018-08-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多