Arrayaccess, Iterator и current () - PullRequest
       21

Arrayaccess, Iterator и current ()

3 голосов
/ 10 января 2012

У меня есть класс, который реализует 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, верно?(не мой код ошибки) И есть ли обходной путь, без пользовательской функции (пальцы скрещены)?

[EDIT] Упрощенная версия полного класса (работает):

$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));
    }

}

1 Ответ

1 голос
/ 10 января 2012

Попробуйте разместить свои данные в приватном режиме. Я подозреваю, что у вас есть внешняя процедура, играющая с ней и вносящая изменения в нее. Я скопировал ваш класс и немного изменил ваш конструктор, поскольку у меня не было того же ввода, что и у вас, и я не получаю странного поведения. В конечном счете, вы можете захотеть выяснить, почему вы также извлекаете ($ 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" 

Итак, как я уже сказал, я думаю, что ваша проблема в основном заключается в том, что ваши $ данные являются публичными, и что-то еще играет с ними.

OR

В твоем конструкторе я должен был исправить, чтобы он работал на моей стороне.

Удачи

...