I've got the following code:
preg_match('/^[a-zA-Z0-9]+$/', $value);
And the plugin reports:
ctype_alnum((string) $value) can be used instead
But this is not entirely true, they are not strictly equivalent. Unlike preg_match(), ctype_alnum() is sensitive to the default locale, making the code behave differently depending on the current context.
Take the following code:
$char = "\xe9"; // LATIN SMALL LETTER E WITH ACUTE (ISO-8859-1)
var_export(ctype_alnum($char)); // false
var_export(preg_match('/^[a-zA-Z0-9]+$/', $char)); // 0
All good, they behave as expected.
Now add the following line at the top:
setlocale(LC_ALL, 'fr_FR');
Now ctype_alnum() returns true!
I think it's very misleading that the plugin suggests to replace the original code with ctype_alnum(). IMHO, this inspection should either be removed, or a big warning should be added in the description, stating that the code becomes sensitive to the default locale.
I personally try to avoid, whenever possible, writing code that depends on some configuration or global status, especially when writing libraries. That's why I would never use ctype_alnum(), and was very surprised to see this inspection pop up.
Make sense for me when it treats languages that not uses accents (like english). In this case, I vote to disable this inspection by default, or it should consider a more flexible regexp (but it will reduce drastically the inspection usefully).
@BenMorel has a very good point here, the plugin should actually warn about every and any function that is locale dependent. Note that this affects function like basename as well!
Good point and difficult to quickly determine which functions are those locale dependent. Php docs are not so explicit with this. We need to rely on people knowledge/experience for a list.
ctype_alnum for example doesn't pronounce anything, only setlocale in the "See Also".basename does warn about it clearly.By grepping docs (looking for: "locale aware" or "locale dependent") few explicit references are found
dirnamepathinfoOne can infer though from previous results that most of functions accepting/returning strings (patterns or modifiers) for its work are affected.
Most of them time it affects those that simply forward to their C counterparts. You could extend your grep by searching for setlocale in the see also list of functions (than you'll find ctype_* stuff as well).
Lots of good points and even more fun when I dug dipper: suggestions for ctype_alpha, ctype_alnum will be removed completely.
@BenMorel: thank you very much for pointing this out!
And I'll make a bug-fix release today, so set your belts - we are taking off =)
Fixed, releasing today
Most helpful comment
Lots of good points and even more fun when I dug dipper: suggestions for ctype_alpha, ctype_alnum will be removed completely.
@BenMorel: thank you very much for pointing this out!