DEV Community

Laravel Greatest Trick Revealed: Magic Methods

Steven Yung on April 15, 2019

Photo by Mervyn Chan on Unsplash Laravel has leverage PHP to a whole new level, providing awesome Developer Experience (DX) to craft your next pr...
Collapse
 
mbrown1408 profile image
Michael J Brown

As somebody that is just learning the basics of php, OOP and playing with laravel passively, this article was incredibly helpful. Thank you!

Collapse
 
xstevenyung profile image
Steven Yung

If it was clear for you then my mission is done !

Thank you for the kind words and keep on learning, Laravel is incredible and extremely rewarding ! 💪

Collapse
 
ystrauch profile image
Yaron Strauch • Edited

The magic method __set however has a trap that I fell into and needed many hours to debug.

Say you have your nice object, say Airplane, with a static function to initialise an airplane from some other data.

class Airplane extends \Illuminate\Database\Eloquent\Model {
   private $name;

   public static function fromSomething($foo) {
       $airplane = new Airplane();
       // do something awesome with $foo to derive the name
       $airplane->name = "Airbus";
       $airplane->save();
       return $airplane;
    }
}
Enter fullscreen mode Exit fullscreen mode

And obviously from somewhere else you call $airplane = Airplane.fromSomething($foo), and that part works as expected. But then you check your database (or fetch the model again through eloquent) and... It's empty! Well except for the created/modified timestamps. The rest is just empty.
The caveat: Php docs specify: __set() is run when writing data to inaccessible (protected or private) or non-existing properties. So it's not called because we have write access to the method! This means that all the cool eloquent magic to update your attributes is knocked out.
Solutions? Well just don't define the variables in your class. Which goes against all OOP tutorials out there (including this one) and any programming intuition. Or don't use static initialisers, which is a well-known design pattern. Or add it manually to attributes, therefore implementing framework functionality (variant: call __set yourself). Or use inheritance and use protected (but are they gonna be protected? Don't know either). Maybe there are more solutions? I will stick to the first one and stop defining the fields in my class.

Collapse
 
tacsiazuma profile image
Krisztian Papp

Just a note that magic methods are several times slower than accessing a properly defined variable. It might sound cool and stuff for RAD, but no magic comes without a price.

Collapse
 
xstevenyung profile image
Steven Yung

Good note!

Thanks for sharing 👍

Collapse
 
marlon316 profile image
Marlon Santana

Great Post!

Collapse
 
adi profile image
Adi Sk

Informative article, learnt something new about PHP and how it's utilized in Laravel.

Collapse
 
xstevenyung profile image
Steven Yung

Glad it helped someone 👍

Collapse
 
chyn_km profile image
KM

Loved your post. Learnt a new feature.

Collapse
 
micstudent profile image
micstudent • Edited

What about should i read Book for Laravel to understand OOP

Collapse
 
akashdas profile image
Akash Das • Edited

There are so many magic methods in PHP. I found this article to understand all magic methods in one place.