The Proxy Pattern in Laravel
Proxy is one of those words that makes you sound technically smart and it’s seen an increase in usage over the last 20 years according to Google Books Ngram Viewer.
Well what does proxy even mean? Lets take a look in more detail.
Proxy Pattern
The word proxy often means something that replaces something else and behaves similar to the original object. An example of a proxy is when you give the authority to someone to vote on your behalf; it’s called proxy voting.
The proxy pattern in OOP follows a similar concept in that a proxy object stands in place of a real object. That proxy object generally forwards the instuctions on to the real object, but could add additional functionality as needed.
The simplest implementation of a proxy object just uses the magic __call
function to dynamically pass along missing methods to the real object:
Well that’s easy enough in PHP. Gotta love that syntactic sugar.
Proxy Pattern in the Wild 🕵️
There are various uses for the proxy pattern. People give examples of lazy loading files to authorizing method calls in proxy objects. Interestingly, I found a place in the Laravel framework that uses the proxy pattern for neither of these purposes.
Remember that time Taylor Otwell wrote about the tap
function that was inspired by the same named method in Ruby? Well here is his original post. In it, he describes two ways to use the tap
helper function. The first way has 2 arguments:
The second passes along only 1 argument, then chains a method, and he claims that it returns the original object:
I was digging around and found where the tap
helper function is defined and this is what the code looks like:
So the if
block handles when it’s 1 argument and the remaining code handles when there’s 2 arguments. Interesting. So what is this HigherOrderTapProxy
that gets returned instead of the original object? Let’s take a look:
Ahh I see. So this proxy object just intercepts the method call on the object, calls the method with the parameters, but ignores the return value of that method call, and then always returns the “target” aka the original object.
BAM proxy pattern in real life. Definitely did not think I would find one in Laravel that would be easy to understand, but there you have it! Until next time, happy coding!