7

I'm trying to remove the first two items in an Object. For example, if I wanted to remove the first two items from an array, I'd use array_slice($arrayName, 2).

I've tried this on my object (Hey, why not? I know it's not technically an array, but I'm optimistic) and it didn't work.

When searching for this, all I found were methods for removing items from arrays.

    $categories = array_slice(Mage::getModel('catalog/category')->getCollection()->addAttributeToSelect('*'), 2);


    foreach($categories as $category){
        echo "<div class='col'>{$category->getName()}</div>";
    }

In the example above, I'd like to remove the first two categories from the $categories (which are 'Root Category' and 'Default') object before running it through the foreach loop. What would be the best method to go about this? I know I could do;

if($category->getName() != 'Root Category' && $category->getName() != 'Default'){
  echo $category->getName();
}

But this feels like a dirty solution.

Edit

After reading Patrick Q's comment, I realised that this is indeed an array of objects. So my question now becomes, why when applying an array_slice to this array, does it result in a blank screen? The loop works fine when array_slice is not applied.

Edit 2

Ignore the last Edit. It is an Object.

As for possible duplication, while the question (in question) did indeed help me solve my problem, I think, inherently they are different questions. This question, at it's core, centred around finding a useful alternative to array_slice() for objects. The question linked on the other hand, wants to to find a way, specifically, to filter Magento collections based on a drop-down attribute. Whilst they may have arrived at the same destination, the purpose and journey are very different.

18
  • 2
    Wait, isn't $categories an array of category objects? Commented Mar 11, 2016 at 15:04
  • 2
    "blank screen" could mean an error. Did you check your error logs when this happened? Commented Mar 11, 2016 at 15:08
  • 2
    But this feels like a dirty solution. ... that's the feeling I've got from the whole of Magento from my exposure to it so far *sighs* Commented Mar 11, 2016 at 15:10
  • 1
    If you cast as array a not-stdObject you will loose all methods object Commented Mar 11, 2016 at 15:16
  • 1
    I've never used Magento, but based on the answers to this question, it appears that there is an addAttributeToFilter() function that can be called on your collection that might help. Commented Mar 11, 2016 at 15:23

2 Answers 2

6

The functionality doesn't, to my knowledge, exist in Magento.

I'm trying to remove the first two items in an Object (emphasis mine)

By default, PHP objects do not act like arrays. There's no internal to PHP concept of what it would mean for an object to have a first, second, or third item.

The reason you can foreach or count a Magento collection object as though it were an array is because the base collection object implements special interfaces from PHP's standard library -- IteratorAggregate and Countable

#File: lib/Varien/Data/Collection.php
class Varien_Data_Collection implements IteratorAggregate, Countable
{
}

By implementing these interface, (by defining methods in Varien_Data_Collection per the manual links above) the object gets foreach and count() functionality.

Magento's IteratorAggregate implementation (the thing that gives you foreach functionality) relies on PHP's built in ArrayIterator class

#File: lib/Varien/Data/Collection.php
class Varien_Data_Collection implements IteratorAggregate, Countable
{
    public function getIterator()
    {
        $this->load();
        return new ArrayIterator($this->_items);
    }
}

And objets created from the ArrayIterator class have no built in slice functionality. This makes sense -- conceptually the idea behind an iterator is that it allows you to traverse a list without loading the entire underlying list into memory at once. That Magento and PHP's base iterators work with already loaded arrays is a bit of all-to-common redundancy in OO PHP.

So, if you wanted to use slice with a Magento collection object, I'd try the getArrayCopy method of the underlying iterator.

$array = array_slice($categories->getIterator()->getArrayCopy(), 2);

This should (untested) return a PHP array with the expected elements sliced.

Hope that helps!

Sign up to request clarification or add additional context in comments.

2 Comments

This is very interesting, thank you! However, duplicating it to an array and slicing that, I'd assume that the resultant array loses the object methods rendering them difficult to use in the foreach loop?
@Lewis The collection object would lose its methods. However, the resulting array should still contain individual category objects. i.e. $category->getName() would still work.
3

LimitIterator is iterator related version of slice function. You can use it like:

$categories = new LimitIterator(
    Mage::getModel('catalog/category')
    ->getCollection()
    ->addAttributeToSelect('*')
    ->getIterator(), 
    2
);


foreach($categories as $category){
    echo "<div class='col'>{$category->getName()}</div>";
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.