On a recent Magento Enterprise project, we encountered a pretty common problem that we’ve run across in the past with Magento. In this case, however, the normal solutions were of no help, which caused us to have to dig into one of the many core changes present in Magento Enterprise 1.13.0.0 and subsequently 1.13.0.1. In this particular case, we had migrated the site from our testing environment up to the client’s server, in order to create a test site. Everything migrated successfully, there we no errors present on the site and the error logs were also clean. The only thing out of place was that product images were now no longer displaying. This issue appeared to only affect product images, as other images across the site appeared unaffected. The following common solutions were explored or implemented in hopes to remedy the issue:

  • Flushed Magento Cache as well as Flushing Catalog Images Cache in System>Cache Management.
  • Ensuring that media/catalog/product was writeable.
  • Validating that a Base, Thumbnail and Small Image were selected on the product image tab in Admin->Catalog-> Manage Products
  • Validating that PHP GD's extension was installed and working correctly.

Each of the above solutions had no effect. When we have witnessed this in the past, it is almost always a permissions problem with the inability to write to the /media directory. Because of this, we further explored and realized that the cache directory in /media/catalog/product/ was not present and was not being created even though the whole media directory was set to 777. Very puzzling!

We then decided as a last resort to try to upload a new product image directly through the admin. We selected a random product, clicked the images tab and attempted to upload a test image. To our surprise we encountered an error that we had not see before, “Memory limit has been reached.” Now we were getting somewhere!

Magento Error: Memory Limit Has Been Reached

Since we had never seen this error before, we SSH’d the server and used Linux’s grep command to pinpoint the exact location of where this exception was being thrown. This search returned only one result, lib/Varien/Image/Adapter/Gd2.php. We opened this file and compared it to the same file present in a Magento Enteprise 1.12 instance, immediately noticing two new functions towards the top of the file.

/**
                * Checks whether memory limit is reached.
                *
                * @return bool
                */
                protected function _isMemoryLimitReached()
                {
                $limit = $this->_convertToByte(ini_get('memory_limit'));
                $size = getimagesize($this->_fileName);
                $requiredMemory = $size[0] * $size[1] * 3;
                return (memory_get_usage(true) + $requiredMemory) > $limit;
                }

                /**
                * Converts memory value (e.g. 64M, 129KB) to bytes.
                * Case insensitive value might be used.
                *
                * @param string $memoryValue
                * @return int
                */
                protected function _convertToByte($memoryValue)
                {
                if (stripos($memoryValue, 'M') !== false) {
                return (int)$memoryValue * 1024 * 1024;
                } elseif (stripos($memoryValue, 'KB') !== false) {
                return (int)$memoryValue * 1024;
                }
                return (int)$memoryValue;
                }

As you might guess, the purpose of these two functions is to perform validation to ensure that the files that you are uploading will not exceed PHP’s memory limit as a way to prevent your browser from timing out during the upload process. These functions are not just called when uploading an image, but also when any manipulation is done to product images. For instance, Magento will generate thumbnail, small and base images for product images when the radio buttons are selected in the admin to do so. These images are generated on the fly when a page loads if they do not already exist, and are stored in a cache directory under media/catalog/product/.

Since the product image cache directory was not being generated and we were receiving the error in the admin originating from this class, we figured we had pinpointed the location of the issue. The server happened to be running Nginx with PHP-FPM so we referred to the instances.conf file and noticed the following:

php_admin_value[memory_limit] = 2G

Our first thought was that there was plenty of memory to upload an 8k image so we should not be reaching a memory limit. We took another glance at the function _convertToByte:

/**
                * Converts memory value (e.g. 64M, 129KB) to bytes.
                * Case insensitive value might be used.
                *
                * @param string $memoryValue
                * @return int
                */
                protected function _convertToByte($memoryValue)
                {
                if (stripos($memoryValue, 'M') !== false) {
                return (int)$memoryValue * 1024 * 1024;
                } elseif (stripos($memoryValue, 'KB') !== false) {
                return (int)$memoryValue * 1024;
                }
                return (int)$memoryValue;
                }

Eureka! The function did not contain a method to evaluate a memory value specified in gigabytes. Because of this, the function converts the memory limit to bytes and Magento thought that the PHP memory limit was set to 2 bytes instead of 2GB. To avoid overriding or modifying core, we set PHP’s memory limit as follows in the .conf file:

php_admin_value[memory_limit] = 2048M

After clearing the cache, product images started displaying again and all was returned to normal. Hopefully this walkthrough will help others out there who have been pulling their hair out, like we were, trying every “trick in the book” to get Magento product images to display.

To learn more about Magento design & development check out the rest of our Developer Toolbox blogs.

 

 

Talk to Us

Tell us about your goals and we'll discover together how Groove can help you meet them.