正如我们所讨论的,有多种方法可以实现count()
的原始功能而不发出E_WARNING
。
在PHP 7.3中添加了一个新函数is_countable
,专门解决E_WARNING
问题和应用程序在其代码中采用is_array($var) || $var instanceof \Countable
的普遍性。
在PHP 7.2中,尝试计算不可计数的事物时会出现警告。之后,每个人都被迫搜索并更改他们的代码以避免这种情况。通常,下面的代码成为标准:
if (is_array($foo) || $foo instanceof Countable) {
// $foo是可计数的
}
https://wiki.php.net/rfc/is-countable
自定义函数替代
因此,似乎解决该问题的最佳方法是执行与is_countable
相同的功能,并创建自定义函数以确保符合count
的原始功能。
例子 https://3v4l.org/8M0Wd
function countValid($array_or_countable, $mode = \COUNT_NORMAL)
{
if (
(\PHP_VERSION_ID >= 70300 && \is_countable($array_or_countable)) ||
\is_array($array_or_countable) ||
$array_or_countable instanceof \Countable
) {
return \count($array_or_countable, $mode);
}
return null === $array_or_countable ? 0 : 1;
}
结果
array: 3
string: 1
number: 1
iterator: 3
countable: 3
zero: 1
string_zero: 1
object: 1
stdClass: 1
null: 0
empty: 1
boolt: 1
boolf: 1
Notice: Undefined variable: undefined in /in/8M0Wd on line 53
undefined: 0
Shim is_countable()
函数
使用上述替代函数,可以在 PHP <= 7.2
中为 is_countable
进行 shimming,以便在需要时仅使用一次,并带有最小的开销。
示例:https://3v4l.org/i5KWH
if (!\function_exists('is_countable')) {
function is_countable($value)
{
return \is_array($value) || $value instanceof \Countable;
}
}
function countValid($array_or_countable, $mode = \COUNT_NORMAL)
{
if (\is_countable($array_or_countable)) {
return \count($array_or_countable, $mode);
}
return null === $array_or_countable ? 0 : 1;
}
忽略 count()
的警告
由于 count()
的功能没有改变,且通常在过去不会发出警告。一个替代使用自定义函数的方法是通过使用 @
错误控制运算符 来直接忽略警告。
注意:这种方法的影响是将未定义的变量视为 NULL
,并且不显示 Notice: Undefined variable:
消息。
示例 https://3v4l.org/nmWmE
@count($var);
结果
array: 3
string: 1
number: 1
iterator: 3
countable: 3
zero: 1
string_zero: 1
object: 1
stdClass: 1
null: 0
empty: 1
boolt: 1
boolf: 1
---
Undefined: 0
使用APD扩展替换count()
要替换内部的PHP函数count()
,可以使用PECL扩展APD
(Advanced PHP Debugger),该扩展允许使用override_function
来覆盖核心PHP函数。正如扩展名所示,它技术上是用于调试,但它是替换所有实例的count
为自定义函数的可行替代方案。
示例
\rename_function('count', 'old_count');
\override_function('count', '$array_or_countable,$mode', 'return countValid($array_or_countable,$mode);');
if (!\function_exists('is_countable')) {
function is_countable($value)
{
return \is_array($value) || $value instanceof \Countable;
}
}
function countValid($array_or_countable, $mode = \COUNT_NORMAL)
{
if (\is_countable($array_or_countable)) {
return \old_count($array_or_countable, $mode);
}
return null === $array_or_countable ? 0 : 1;
}
@
是不好的,尽管它能够产生期望的结果,但这是基于您非常合理的担忧。长期可维护性也是主观的。这一切归结为您希望继续使用自2013年以来已经记录的不受预期方式中的count。在我看来,最好的方法是重构您的代码以兼容7.2+,原因就是像您指出的那样,将来它可能会抛出异常。 - Will B.