【问题标题】:Magento - memory error trying to get thumbnailMagento - 试图获取缩略图的内存错误
【发布时间】:2014-07-23 21:15:28
【问题描述】:

编辑:我使用的是 Magento 1.6.2(社区)

我想迭代产品。我运行以下代码(虽然这不是一个完整的文件,它是 SOAP 服务的类定义的一部分 - 此处未描述的方法对我的问题并不重要):

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

为了获取每个单独项目的图像,我使用了$this-&gt;_getProductAttribute($product, 'thumbnail') 这一行,但它返回了一个相对 url,如:/p/c/pcd0748-1.jpg(url 仅用于说明)。

当我试图获取完整的 url 时,通过知道它的基本 url,所以我只需要附加块,我发现这样的基本 url 不是那么“稳定”(即不是众所周知的文件夹结构,而是一些缓存相关):

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

所以我不能因为散列而简单地将那个长 url 作为基本 url - 常识告诉我们这个基本 url 会改变。

所以我将图像检索行更改为当前给定的 (Mage::helper('catalog/image')-&gt;init($product, 'thumbnail'))我遇到了内存错误(我得到了 10 个产品的子集,所以这样的行运行了 10 次总计)。

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

有没有更高效的方法不会杀死我对 10 张图像的记忆?我知道这样的图片存在,只是想获取图片的网址。

【问题讨论】:

  • 第二个答案here 向您展示了如何做到这一点,而无需每次都创建新的Mage::helper 对象。试试Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA) ...
  • Mage 助手在某种程度上是单例的,所以多次调用Mage::helper('some/helper') 并没有什么坏处——总是返回相同的对象实例
  • 致命错误行是否指向正在生成图像的行?还是您的产品系列实际上比您预期的要大得多? ($collection-&gt;count() 说什么?)
  • 第一个生成的 url 是一个大图像 url - 不是缩略图。第二个生成的 url 是我已经尝试过的,几乎没有区别。
  • 不,那是不可能的。如果问题出在收藏中,我就不会在这里。请坚持陈述,因为我什至告诉了我在内存错误之前得到的原始结果。

标签: php magento


【解决方案1】:

解决方案:

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

这不会返回一个 URL,而是一个非常复杂的对象,它有一个指向产品模型对象的指针。并且这样的对象有一个指向巨大的对象链(或树)的指针,这些对象汇总了这样的内存量。序列化此类对象将需要大量 MB。

要仅获取 url,必须将对象转换为字符串:

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

这将只有 url - 这是我对序列化的期望。

【讨论】:

    猜你喜欢
    • 2011-09-17
    • 2014-07-26
    • 1970-01-01
    • 2012-09-09
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多