0

Edit: I'm using Magento 1.6.2 (community)

I want to iterate over products. I run the following code (althought this is not a full file, it is part of a SOAP service's class definition - methods not described here are not important to my issue):

//ok private function _listProductData($product, $full = false) { $result = array( //_getProductAttribute($product, $attribute) 'product_id' => $product->getId(), 'type' => $product->getTypeId(), 'position' => $product->getCatIndexPosition(), 'sku' => $product->getSku(), 'price' => $this->_getProductAttribute($product, 'price'), 'kilometraje' => $this->_getProductAttribute($product, 'kilometraje'), 'thumbnail' => Mage::helper('catalog/image')->init($product, 'thumbnail'), 'model' => $this->_getProductModel($product) ); if ($full) { //meter mas datos $result = $result + array( 'image' => $this->_getProductAttribute($product, 'small_image'), 'tipo_vehiculo' => $this->_getProductAttribute($product, 'vehiculo_tipo', true), 'cilindrada' => $this->_getProductAttribute($product, 'cilindrada', true), 'combustible' => $this->_getProductAttribute($product, 'combustible', true), 'transmision' => $this->_getProductAttribute($product, 'transmision', true), 'direccion' => $this->_getProductAttribute($product, 'direccion', true), 'traccion' => $this->_getProductAttribute($product, 'traccion', true), 'anio' => $this->_getProductAttribute($product, 'rango_anio', true), 'tapiz' => $this->_getProductAttribute($product, 'tapiz', true), 'aire_acondicionado' => $this->_getProductAttribute($product, 'aire_acondicionado', true), 'vidrios' => $this->_getProductAttribute($product, 'vidrios', true), 'origen' => $this->_getProductAttribute($product, 'origen', true), 'numero_placa' => $this->_getProductAttribute($product, 'numero_placa', true), 'placa' => $this->_getProductAttribute($product, 'placa') ); } //$result = array(); //foreach ($product->getTypeInstance(true)->getEditableAttributes($product) as $attribute) { // if ($this->_isAllowedAttribute($attribute, $attributes)) { // $result[$attribute->getAttributeCode()] = $product->getData($attribute->getAttributeCode()); // } //} return $result; } //ok private function _listProductCollection($collection, $offset, $order) { //ordenamos y nos quedamos con un cachito de la coleccion nomas $order = in_array($order, array('ASC', 'DESC', false)) ? $order : false; $order ? $collection->setOrder('name', $order) : false; $collection->setPage($offset, 10); //iteramos y recolectamos los datos (TO-DO listar los atributos y la imagen principal) $result = array(); foreach ($collection as $product) { $result[] = $this->_listProductData($product, false); } return $result; } //ok public function listVehicles($categoryId=null, $offset=1, $order='ASC') { $categoryId = (int) $categoryId; $offset = (int) $offset; if (($categoryId < 1) || ($offset < 1) || !in_array($order, array('DESC', 'ASC'))) { $this->_fault('bad_params'); } //cargamos categoria actual, y store actual (1). //la categoria no puede ser de una rama que no sea Marcas o Tipos. //si eso pasa, o la categoria no existe, tiramos un 404. $category = $this->_initCategory($categoryId, 1); $parentId = $category->getParentId(); if (!in_array($parentId, array(4, 94))) { $this->_fault('category_not_exists'); } //tratamos su lista de resultado. return $this->_listProductCollection($category->setStoreId($storeId = 1)->getProductCollection()->addAttributeToSelect('*'), $offset, $order); } 

To get the images of each individual item, I used to let the line $this->_getProductAttribute($product, 'thumbnail'), but it returned a relative url like: /p/c/pcd0748-1.jpg (url only illustrative).

When I tried to get the full url, by knowing its base url so I only have to append the chunk, I found such base url is not so "stable" (i.e. is not a well-known folder structure, but something related to cache):

http://www.blablabla.com/media/catalog/product/cache/1/small_image/201x201/17f82f742ffe127f42dca9de82fb58b1/p/c/pcd0748-1.jpg

So I cannot simply take that long url as base url because of the hash - the common sense tells us that this base url will change.

So I changed the image retrieval line to the currently given (Mage::helper('catalog/image')->init($product, 'thumbnail')) and I'm getting a memory error (I get a subset of 10 products, so such line is run 10 times in total).

Fatal error: Allowed memory size of 314572800 bytes exhausted (tried to allocate 295698398 bytes) ... (¡¡¡295MB for 10 images!!!)

Is there a more performant way that doesn't kill my memory for 10 images? I know such images exist, and just want to get the image urls.

5
  • The second answer here shows you how to do it without creating a new Mage::helper object every time. Try Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA) ... Commented Jul 23, 2014 at 21:19
  • Mage helpers are singletons in a way, so calling Mage::helper('some/helper') multiple times does no harm - the same object instance is always returned Commented Jul 23, 2014 at 21:21
  • Does the fatal error line point to this line which is generating images? Or could it be that your product collection is actually much larger than you expect it to be? (what does $collection->count() say?) Commented Jul 23, 2014 at 21:24
  • The first generated url is a big image url - not a thumbnail. the second generated url is what I already tried, with almost no difference. Commented Jul 23, 2014 at 21:26
  • No, that's impossible. If the problem was in the collection, I wouldn't be here. Stick to the statements, please, since I told there even the original results I got before the memory error. Commented Jul 23, 2014 at 21:27

1 Answer 1

0

Solution:

Mage::helper('catalog/image')->init($product, 'thumbnail') 

This does not return an URL, but a very complex object, which has a pointer to the product model object. And such object has a pointer to a huge chain (or tree) of objects, which totalize such memory amount. Serializing such object would ask for a lot of MBs.

To get only the url, the object must be cast as string:

(string) Mage::helper('catalog/image')->init($product, 'thumbnail') 

This will only have the url - which is what I expected for serialization.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.