To address your first question:
Is the callable type hint here preferred as opposed to closure?
There is a very similar question on StackOverflow: PHP: Type hinting - Difference between
Callable. It has three answers.
The first line of the answer by Xorifelse explains:
The main difference between them is that a
closure is a class and
callable a type.
And the last line of the accepted answer by Rizier123 has this suggestion:
So if you only want to type hint anonymous function use:
Closure and if you want also to allow normal functions use
callable as type hint.
And now, for
something completely different general code review comments:
$k is a little too brief...
$key isn't very long and describes what the variable is.
Simplifying ternary expressions
Correct me if I am mistaken but as long as PHP 5.3+ is used then this line:
$serialize = $serialize ? $serialize : 'serialize';
could be shortened using the fact that:
(expr1) ? (expr2) : (expr3) evaluates to expr2 if expr1 evaluates to TRUE, and expr3 if expr1 evaluates to FALSE.
Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression
expr1 ?: expr3 returns expr1 if expr1 evaluates to
TRUE, and expr3 otherwise.1
to the following:
$serialize = $serialize ?: 'serialize';
If PHP 7+ is used (which hopefully is the case, since at the time of writing, 7.2+ are actively maintained2) then the null coalescing operator i.e.
?? could also be used to simplify cases where a fallback should be used if a non-null value does not exist - e.g. :
return isset($cache[$k]) ? $cache[$k] : ($cache[$k] = $fn(...$args));
return $cache[$k] ?? ($cache[$k] = $fn(...$args));