Memoize Method Calls in PHP with Cache Decorators

A “memoized” function is a function that only calculates the return value for each combination of arguments once and returns the previously calculated value if the function is called a second time with the same arguments.

In PHP, I often see this implemented with code like this:

class ProductRepository implements ProductRepositoryInterface
{
    private $products = [];
    public function product($id)
    {
        if (! isset($this->products[$id])) {
            $this->products[$id] = $this->load($id);
        }
        return $this->products[$id];
    }

    private function load($id) { ... }
}

Continue reading “Memoize Method Calls in PHP with Cache Decorators”

5 Minute Tips: Magento Performance Tweaks

My “Week On StackExchange” Series takes a break at the moment because I don’t have not too much blog-worthy.

Instead, I’m starting something new again: Tips on a specific topic which you can read in 5 minutes maximum during coffee break. Mostly not by me, just found by me 🙂

I don’t try to make it a regular thing but I have a loose collection of useful stuff so why not use the blog to bring order into it and hopefully it’s also useful for others.

Let’s start with Magento Performance Tweaks, all with little effort and can be used without hesitation:

Continue reading “5 Minute Tips: Magento Performance Tweaks”

The week on StackExchange #10 / 2016

Here’s the next update with new, hopefully interesting, questions and answers on StackExchange.

New Answers

New Questions:

EcomDev PHPUnit Tip #13

For years, the test framework EcomDev_PHPUnit is quasi-standard for Magento unit tests. The current version is 0.3.7 and last state of official documentation is version 0.2.0 – since then, much has changed which you have to search yourself in code and GitHub issues. This series shall collect practical usage tips.

Tip #13: Speed up EAV fixtures

If you use the EAV fixtures to create products, categories and customers for tests, the fixture processor or EcomDev_PHPUnit makes a backup of the according tables before each test and restores it afterwards. Since the “magento_unit_tests” test database is copied from the current Magento database by default, this can result in much unnecessary overhead.

We can speed up tests that run several minutes many times over, by cleaning up the EAV tables in the test database. To do so, delete all rows in the entity main tables of the test DB, the associated attributes etc. are deleted automatically with triggers. With one exception: Do not delete the default root category:

delete from catalog_product_entity;
delete from catalog_category_entity where entity_id > 2;
delete from customer_entity;

Show random products in Magento: You are doing it wrong

Well, probably (I certainly have).

A typical requirement is to show random products on the home page, random products of a category on the category page, or similar. Magento offers a simple block that can show a specified number of random products, Mage_Catalog_Block_Product_List_Random. To add filtering, like by category, you still need to write your own block, but it could easily be extended.

This is the CMS code:

{{block type="catalog/product_list_random" num_products="4"}}

But don’t get too excited. This block type will make your site slow, you should not use it. The problem is in this line:

$collection->getSelect()->order('rand()');

I’ve been recently advocating against using ORDER BY RAND() to select random products from a Magento database. 1 Generally, this method is discouraged because of its performance issues.

Continue reading “Show random products in Magento: You are doing it wrong”

Notes:

  1. For example in this Magento StackExchange post: Four Random Products on Homepage

Efficiently Draw Random Elements From Large PHP Array

I recently needed to select few random elements from a big database table and was looking for alternatives to ORDER BY RAND() (because of its performance issues). Because the IDs are not continuous, the proposed solutions in the linked article are not sufficient.

So the idea is to fetch all IDs from the table, pick X random IDs and query these directly. The memory overhead of reading an array of about 100,000 IDs is not too big, so the problem is reduced to how to pick random IDs efficiently with PHP.
Continue reading “Efficiently Draw Random Elements From Large PHP Array”

CSV Processing In Magento

A development principle , not only with Magento, is that you shouldn’t try to reinvent the wheel and especially use the functions of the used framework wherever possible. Magento has many more or less known universal helpers, in the helper classes in Mage_Core as well as in lib/Varien and of course in the Zend Framework.

A classic is for example JSON encoding. Although PHP has its built-in functions json_encode and json_decode, but they have some shortcomings that are compensated for in the Zend_Json implementation. So Zend_Json::encode() has a cycle check, Magento added support for inline translations within JSON strings in Mage_Core_Helper_Data::jsonEncode(). Thus in Magento you always should use Mage::helper('core')->jsonEncode() (and jsonDecode).

Varien_File_Csv

How is it with processing CSV files? Since import and export works with CSV files in the standard implementation, Magento should have somthing, right? Presenting Varien_File_Csv! Well, I’ll anticipate the result: except for very simple tasks with small files, the class is not useful at all.

Continue reading “CSV Processing In Magento”

PHP: References and Memory

Never ever use references in PHP just to reduce memory load. PHP handles that perfectly with its internal copy on write mechanism. Example:

$a = str_repeat('x', 100000000); // Memory used ~ 100 MB
$b = $a;                         // Memory used ~ 100 MB
$b = $b . 'x';                   // Memory used ~ 200 MB

You should only use references if you know exactly what you are doing and need them for functionality (and that’s almost never, so you could as well just forget about them). PHP references are quirky and can result to some unexpected behaviour.

Question and Answer on StackOverflow