[Aside: please don't use "reply" when starting a new thread. Although
GMail and its imitators frequently ignore it, a reply contains a header
telling clients where to add it to an existing thread. I've pasted your
full text into a new e-mail rather than replying, so it reliably shows
as its own thread.]
substr_replace()
has the following signature:substr_replace(
array|string $string,
array|string $replace,
array|int $offset,
array|int|null $length = null
): string|arrayWas it deliberate to not allow a null value as the third parameter?
If permitted to amend this signature, I think it would be sensible to
set null as the default value for $offset and adopt the same logic as
the $length parameter.I have recently stumbled upon what I assume is a code smell in
multiple SO scripts that use:$prefixed = preg_filter('/^/', 'prefix_', $array);
It smells because regardless of the passed in array values' types,
there will always be a starting position of each values which are
coerced to strings. In other words, the destructive feature of
preg_filter()
is never utilized.This means that for this task,
preg_filter()
can be unconditionally
replaced withpreg_replace()
.$prefixed = preg_replace('/^/', 'prefix_', $array);
But wait, regex isn't even needed for this task. It can be coded
more efficiently as:$prefixed = substr_replace($array, 'prefix_', 0, 0)
Next, my mind shifted to suffixing/postfixing. By using $ in the pattern.
$prefixed = preg_replace('/$/', 'prefix_', $array);
However, there isn't a convenient way to append a string to each
value usingsubstr_replace()
with the current signature.If the $offset parameter worked like the $length parameter, then the
language would provide a native, non-regex tool for appending a static
string to all array elements.$suffixed = substr_replace($array, '_suffix');
Finally, I wish to flag the observation that null values inside of an
array are happily coerced to strings inside of the aforementioned
functions, but null is not consumable if singularly passed in.Some examples for context: https://3v4l.org/ENVip
I look forward to hearing feedback/concerns.
Not being familiar with the variations supported by substr_replace, it
took me a while to understand what was being proposed here.
In case anyone else is similarly lost, a null $length is equivalent to
strlen($string), meaning "replace to the end"; so a null $offset having
the same meaning would give "append to the end". On its own, this would
be pretty pointless:
$foo = substr_replace('abc', 'xyz', null);
// a long-winded way of writing
$foo = 'abc' . 'xyz';
But the function also has built-in mapping over arrays, so it could be
used to append the same string to multiple inputs:
$foo = substr_replace(['hello', 'goodbye'], '!', null);
Or append each entry from one list onto each entry in the other:
$foo = substr_replace(['one', 'two'], [' - uno', ' - dos'], null);
Demo: https://3v4l.org/6eEIG
While I can see the logic, it would never occur to me to use any of the
functions mentioned for this task, rather than using array_map and a
regular concatenation:
$foo = array_map(fn($string) => $string . '!', ['hello', 'goodbye']);
$foo = array_map(fn($string, $suffix) => $string . $suffix, ['one',
'two'], [' - uno', ' - dos']);
Which of course extends to more complex cases:
$foo = array_map(fn($english, $spanish) => "'$english' en Español es
'$spanish'", ['one', 'two'], ['uno', 'dos']);
$foo = array_map(fn($english, $spanish, $german) => "$english - $spanish
- $german", ['one', 'two'], ['uno', 'dos'], ['ein', 'zwei']);
So, I'm not opposed to the change, but its value seems marginal.
Regards,
--
Rowan Tommins
[IMSoP]