PHP ArrayObject: Массив был изменен вне объекта, и внутренняя позиция больше не действительна

Я пытаюсь создать своего рода класс флеш-сообщений, который будет «сбрасывать» сообщения при первой их загрузке. Так что не при следующем HTTP-запросе, если, например, переадресация с одного действия контроллера на другое (того же HTTP-запроса)

Вот мой класс дизайна:

<?php
namespace MartynBiz;

/**
* Flash messages. Slight variation in that this will store a message until it
* is accessed - whether that is a next http request, or same request. Simply
* when get method is called the message is wiped from session.
* TODO move this to martynbiz\php-flash
*/
class Flash
{
/**
* Message storage
*
* @var ArrayObject
*/
protected $storage;

/**
* @param string $storage Name to store messages in session
*/
public function __construct($storage=null)
{
// if storage is not defined, create ArrayObject (not persistent)
if (is_null($storage)) {
$storage = new \ArrayObject();
}

$this->storage = $storage;
}

/**
* Add flash message
*
* @param string $key The key to store the message under
* @param string $message Message to show on next request
*/
public function addMessage($key, $message)
{
// create entry in the session
$this->storage[$key] = $message;
}

/**
* Get flash messages, and reset storage
* @return array Messages to show for current request
*/
public function flushMessages()
{
$messages = $this->storage->getArrayCopy();

// clear storage items
foreach ($this->storage as $key => $value) {
unset($this->storage[$key]);
}

return $messages;
}
}

Я написал несколько тестов PHPUnit, которые также демонстрируют, как можно использовать класс Flash:

<?php

// TODO test with an ArrayAccess/Object $storage passed in

use MartynBiz\Flash;
use Zend\Session\Container;

class FlashTest extends PHPUnit_Framework_TestCase
{
protected $flash;

public function testInstantiation()
{
$flash = new Flash();

$this->assertTrue($flash instanceof Flash);
}

public function testGettingSetting()
{
$flash = new Flash();

$flash->addMessage('key1', 'value1');
$flash->addMessage('key2', 'value2');
$flash->addMessage('key2', 'value3');

$expected = array(
'key1' => 'value1',
'key2' => 'value3',
);

// assert first time to access messages
$messages = $flash->flushMessages();
$this->assertEquals($expected, $messages);

// assert messages have been cleared
$messages = $flash->flushMessages();
$this->assertEquals(array(), $messages);
}

public function testCustomStorage()
{
$container = new Container('mycontainer');
$flash = new Flash($container);

$flash->addMessage('key1', 'value1');

$expected = array(
'key1' => 'value1',
);

// assert first time to access messages
$messages = $flash->flushMessages();
$this->assertEquals($expected, $messages);

// assert messages have been cleared
$messages = $flash->flushMessages();
$this->assertEquals(array(), $messages);
}
}

Вы можете видеть, что я также передаю пользовательское хранилище $ (экземпляр контейнера сеанса Zend), которое мне бы хотелось. Эти тесты, кажется, проходят, однако я получаю следующую ошибку на других, и я не совсем понимаю, в чем проблема:

$ ./vendor/bin/phpunit tests/library/FlashTest.php 1
PHPUnit 4.8.21-4-g7f07877 by Sebastian Bergmann and contributors.

.E.

Time: 68 ms, Memory: 4.50Mb

There was 1 error:

1) FlashTest::testGettingSetting
MartynBiz\Flash::flushMessages(): ArrayIterator::next(): Array was modified outside object and internal position is no longer valid

/var/www/crsrc-slimmvc/app/library/MartynBiz/Flash/Flash.php:53
/var/www/crsrc-slimmvc/tests/library/FlashTest.php:33

FAILURES!
Tests: 3, Assertions: 3, Errors: 1.

Я искал эту ошибку и попробовал несколько альтернатив (например, $ this-> storage-> getIterator ()), но все равно получаю ту же ошибку. Есть идеи, где я иду не так? Я думаю, что я немного новичок в ArrayObject.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]