Ever wonder how an undefined method is called without throwing any error on objects in Magento 2? So today we are gonna find the implementation from where this magic happens.
Have you ever heard about \Magento\Framework\DataObject::class ? Almost everything we used in Magento 2 is used as an object and almost every class somewhere extends \Magento\Framework\DataObject::class in parent. The main application of this class can be seen in Magento 2 ORM (Object Relational Mapping). We call undefined methods in camelcase (like get{Fieldname} & set{Fieldname}) on our model class object and it gives accurate result without throwing 'call to undefined method' exception.
This magic happends in DataObject class itself. Just look at the code written inside the DataObject class -
/**
* Set/Get attribute wrapper
*
* @param string $method
* @param array $args
* @return mixed
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function __call($method, $args)
{
switch (substr($method, 0, 3)) {
case 'get':
$key = $this->_underscore(substr($method, 3));
$index = isset($args[0]) ? $args[0] : null;
return $this->getData($key, $index);
case 'set':
$key = $this->_underscore(substr($method, 3));
$value = isset($args[0]) ? $args[0] : null;
return $this->setData($key, $value);
case 'uns':
$key = $this->_underscore(substr($method, 3));
return $this->unsetData($key);
case 'has':
$key = $this->_underscore(substr($method, 3));
return isset($this->_data[$key]);
}
throw new \Magento\Framework\Exception\LocalizedException(
new \Magento\Framework\Phrase('Invalid method %1::%2', [get_class($this), $method])
);
}
The __call() method is a magic method in PHP which executes when a call to an inaccessible or undefined method is made. So whenever we call any undefined method over an model object, the __call() methods checks for the get, set, uns, has prefixes in the called method name, then check for the fieldname and if all goes good we haven't face any issue and we get the desired result.
Also, we can see DataObject class implements \ArrayAccess interface, this is the interface which is resonsible for accessing the object as array, i.e., we can also use $model['key'] instead of $model->getKey().
Thank you :) . Happy Coding.