получить последний элемент массива в объекте итератора в php - PullRequest
0 голосов
/ 30 марта 2020

У меня есть объект, который выглядит следующим образом

Класс Model_Collection_Sam реализует Countable, Iterator

Ниже приведен объект класса

Model_Collection_Sam Object
(
    [_ClassName:protected] => Model_Sam
    [_mClassName:protected] => Model_Mapper_Sam
    [_collection:protected] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [name] => Blue
                )

            [1] => Array
                (
                    [id] => 2
                    [name] => Green
                )

            [2] => Array
                (
                    [id] => 3
                    [name] => Yellow                    
                )
        )
)

Я использовал функцию print_r для отображения выше

Foreach выполняет итерацию массива точно так, как ожидалось

Я хочу знать, как получить последний элемент массива, используя любую определенную php функцию. Я использовал end, но я получил пустой массив.

1 Ответ

0 голосов
/ 30 марта 2020

Поскольку ваш объект PHP реализует только интерфейсы Countable и Iterator, вы не можете напрямую достичь своей цели. Одним из способов может быть использование API Reflection PHP.

Краткий пример его использования.

class MyIterator implements Countable, Iterator
{
    protected $data = [];
    protected $position;

    public function __construct(array $data)
    {
        $this->data = $data;
    }

    public function count(): int
    {
        return count($this->data);
    }

    public function rewind(): void
    {
        $this->position = 0;
    }

    public function current(): ?string 
    {
        return $this->data[$this->position];
    }

    public function key(): int 
    {
        return $this->position;
    }

    public function next(): void {
        $this->position++;
    }

    public function valid(): bool 
    {
        return isset($this->data[$this->position]);
    }
}

Это простой для понимания пример класса, который реализует Countable и Iterator интерфейс. Ваш PHP класс, вероятно, выглядит примерно так.

$object = new MyIterator([
    'Nina',
    'Marcel',
    'Steffen',
]);
foreach ($object as $name) {
    // dumps every single name
    var_dump($name);
}

Вы не можете получить последний элемент напрямую. Нет прямого способа получить доступ к защищенному свойству данных. Так что просто используйте класс ReflectionClass.

$object->rewind();
$reflector = new ReflectionClass($object);

$property = $reflector->getProperty('data');
$property->setAccessible(true);

$value = $property->getValue($object);

// "Steffen" will be dumped as it is the last value in our data property
var_dump(array_pop($value));

Правда, выглядит немного некрасиво, но ведет прямо к вашей цели.

Если вы можете изменить объект коллекции PHP, попробуйте реализовать ArrayAccess интерфейс. Это автоматически заставляет вас использовать методы offsetExists, offsetGet, offsetSet и offsetUnset. С помощью этого интерфейса вы можете напрямую получить последний элемент.

...
public function offsetGet($offset): ?string
{
    return isset($this->data[$offset]) ? $this->data[$offset] : null;
}

Пример теперь будет выглядеть следующим образом.

// our object with our names
$object = new MyIterator([
    'Nina',
    'Marcel',
    'Steffen',
]);

// return "Steffen" 
// (minus 1, because the internal counter starts with 0 and counts starts at 1)
$object->rewind();
$last = $object->offsetGet($object->count() - 1);

Я бы посоветовал вам реализовать ArrayAccess интерфейс в вашем классе коллекции. Это значительно упростит вашу жизнь вместо использования Reflection.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...