photo credit: Bubble Wizard via photopin (license)

Magento’s Magical Getters and Setters demystified

For those of you who are already familiar with Magento 1 or 2, this article will tell you nothing new. For those who are new to Magento, this article is fundamental information for almost every class in Magento. If you are one of those pupils that are new to Magento, keep on reading…

Getters and Setters

If you don’t know what getters and setters are, they are a design pattern almost available in any programming language. They offer a way to keep private parameters private, and perform additional actions when someone from outside tries to access or set such parameter. An example:

This is the most basic example of a getter and a setter in PHP. We have a private variable, $var , which we want to be able to set or get from the outside. We use 2 methods to make sure that what is saved or retrieved is always an integer.

So why not use public variables?

A good question. Consider the following example:

In this example we have a method called timesTwo() , who expects $var  to be of an integer. Making $var  a public accessible (and therefore, changeable) variable, all kind of weird stuff can happen since we can no longer be sure that $var  will always be an integer.

How does Magento handle this?

You might already have used this without knowing how it works, but Magento models (and some other class types) have an interesting way to set and get data. Take the following example:

This code will work, without the need to declare the methods setSomething()  and getSomething() . So how does this work? Well under water Magento maps above methods to the following code:

And this is perfectly valid code, because most class in Magento 1 extend from Varien_Object  and most classes in Magento 2 extend from Magento\Framework\DataObject . Inside those classes is a method named __call() , which more or less has the following code:

What kind of sorcery is this ?!?

For those who don’t know __call() : it’s awesome, but in the wrong hands is a great recipe for spaghetti code. What it does is the following: when PHP cannot find the method that is called (setSomething()  in our example), it executes the magic method  __call() . This method gets 2 parameters:

  1. $method : this is the name of the method.
  2. $args : these are the arguments passed to the method.

Now in Magento’s case, it checks if the method starts with either get , set , uns  or has  and if so, maps it to getData() , setData() , unsetData()  and isset() .
This is of course a great little trick, but it’s also important to know this when you want to develop with Magento 1 or 2.

Benefits and drawbacks

This way of working has 2 sides. The benefits are:

  • Easier to write code.
  • Great when rewriting or extending classes just to catch the reading of one parameter. For example, the getDescription() -method of the Product class doesn’t exists. It just bubbles down to getData(‘description’) . This means that if you want to do something whenever getDescription()  is called, you can simply rewrite the Product class and only declare this method.
  • It works great with XML configuration too!. For example, in Magento 1, you can simply add <action method=”setSomething”><var>foo</var></action>  to make getSomething()  work in your template file.

There are however some drawbacks as well:

  • Code completion: Needless to say, your IDE doesn’t care about magic methods. This means that you have to add a bunch of @method -parameters to the docblock of your class. Ugly!
  • Performance: an extra call is an extra call. So if you let PHP figure out that when you use getSomething() , you actually want getData(‘something’) , your wasting precious clock cycles. On performance intensive tasks, you might want to ditch the magic getters and setters, although it’s performance impact might be small.

Visitors give this article an average rating of 4.4 out of 5.

How would you rate this article?

Leave a Reply