We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
I'm quite a fan of using PHP first class callables, but combining them with Laravel collections can be a bit tricky.
Imagine you have a collection with header names you want to convert to snake case.
<?php
$headers = collect(["First Name", "Last Name", "Zip Code", "City"]);
With first class callables, you would do something like this:
<?php
$headers->map(Str::snake(...);
Very concise if you ask me, but it won't give you the expected result. What you get is:
<?php
$headers->map(Str::snake(...))
// Illuminate\Support\Collection {#9590
// all: [
// "firsname",
// "lasname",
// "zicode",
// "city",
// ],
// }
What you would have expected is (when you are not using first class callables):
<?php
$headers->map(fn ($header) => Str::snake($header));
// Illuminate\Support\Collection {#9583
// all: [
// "first_name",
// "last_name",
// "zip_code",
// "city",
// ],
// }
What is happening here and how can this be explained? First, let's take a look at the signature of the
Str::snake
method:
<?php
static string snake(string $value, string $delimiter = '_')
As you can see, the Str::snake
method expects
a string as the first argument and an optional delimiter as the second argument.
If we then look at the signature of the map
callback method,
you'll see that for each iteration, the first argument will be the item from the collection, the second one is the key
of the item in the collection. This translates to the following being executed:
<?php
$headers->map(
fn (string $header, int $key): string => Str::snake($header, $key)
);
As you can see, it's trying to use the key as the delimiter, which is not what we want.
So, for these type of situations, you cannot use the first class callables and should use a regular closure instead.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.