In this article, we will discuss about Laravel tap
. We'll discuss tap
helper functions and methodscollection
in .tap
Tap helper functions
old implementation
Laravel proposes a tap
feature . This is a very strange feature, inspired by Ruby. This is the basic implementation of the tap
helper function.
function tap($value, $callback)
{
$callback($value);
return $value;
}
The above code will take a parameter and it will call an anonymous function with that parameter. After calling the callback function, it will return the parameters. Let's see how we can use it in a meaningful way. E.g:
<?php
$photo = App\Photo::find(1);
return tap($photo, function($photo) {
$photo->validated = true;
$photo->save();
});
In the above example, we pass a parameter (the photo model) and a callback function that simply validated
sets to true
and saves the model. This function then returns the photo model instance to the caller.
new implementation
In the latest versions of Laravel 5.4 and Laravel 5.5, the more advanced ones tap
are coming . It introduces a shorter way to use it. Here is the new implementation of the tap
function .
function tap($value, $callback = null)
{
if (is_null($callback)) {
return new HigherOrderTapProxy($value);
}
$callback($value);
return $value;
}
The callback function is now optional. You can also use multiple methods in the parameters in a chain, which is actually the method supported in the Photo Model. E.g
<?php
$photo = App\Photo::find(1);
return tap($photo)->update([
'validated' => 'true',
])
We can tap
chain . This update method normally returns true
or false
, but the tap
function . In this case it will return the photo model. tap
Can help you return the object passed as parameter.
how it works
tap
is a very useful feature, but sometimes it's hard to understand how it works. Here to explain how it works.
If no callback function is given, since it is optional, Laravel will return HigherOrderTapProxy
a new instance of . The call magic method is defined in the HigherOrderTapProxy
class . Calling magic methods is called dynamically by the language (so called methods are not defined in the class). HigherOrderTapProxy
Because there are no methods defined in the tap
class other than calling the magic method, it will be called every time any method is called using the function. In calling the magic method, our update method or whatever method we call will be called with arguments, and it will return the arguments we originally passed to the tap
function .
Here is the actual content of calling the magic method in the HigherOrderTapProxy
class .
// vendor/laravel/framework/src/Illuminate/Support/HigherOrderTapProxy.php
public function __call($method, $parameters)
{
$this->target->{$method}(...$parameters);
return $this->target;
}
In the above code, target
properties are the parameters we pass in tap.
The tap method in Laravel collections
Laravel collection
also has a tap
method in the class that allows you to pass parameters to the tap in specific places and process those results. tap
Does not affect the results of the main collection. This is useful for debugging code and finding where things go wrong when processing collections. We explain this method with an example. Initialize the following arrays.
$photos = [
['file_name' => 'wallpaper', 'validated' => true, 'extension' => 'jpg'],
['file_name' => 'spring', 'validated' => true, 'extension' => 'png'],
['file_name' => 'flowers', 'validated' => false, 'extension' => 'jpg'],
['file_name' => 'mac', 'validated' => true, 'extension' => 'png'],
['file_name' => 'books', 'validated' => false, 'extension' => 'jpg'],
['file_name' => 'mobiles', 'validated' => false, 'extension' => 'jpg'],
['file_name' => 'glass', 'validated' => false, 'extension' => 'png'],
['file_name' => 'fruit', 'validated' => true, 'extension' => 'jpg'],
];
Now let's try to use the tap
method . First, we have to convert this array into a set, and then at a certain point tap
this set.
return collect($photos)
->where('validated', true)
->tap(function ($validated) {
return var_dump($validated->pluck('file_name'));
});
});
The above code will output the following result:
wallpaper
spring
mac
fruit
tap VS Pipe
In Laravel, there is a similar method called pipeline. They are similar in the sense that they are both used in the collection pipeline. There is a difference betweentap
and . Allows you to use the data without modifying the original return value. On the other hand, modify the data based on the return value. E.g:pipe
tap
pipe
return collect($photos)
->where('validated', true)
->pipe(function ($validated) {
return $validated->where('extension', 'jpg')->pluck('file_name');
});
});
The output is
wallpaper
fruit
On the other hand, if we use the above code like this:
return collect($photos)
->where('validated', true)
->tap(function ($validated) {
return $validated->where('extension', 'jpg')->pluck('file_name');
});
});
It will return an array of all photos with validation set to true.
The result is
0: {
file_name: "wallpaper",
validated: true,
extension: "jpg"
},
1: {
file_name: "spring",
validated: true,
extension: "png"
},
3: {
file_name: "mac",
validated: true,
extension: "png"
},
7: {
file_name: "fruit",
validated: true,
extension: "jpg"
}
For more PHP knowledge, go to PHPCasts