count() 发出一个 E_WARNING
count() emitting an E_WARNING
在 PHP 7.2 之前,在标量值或不可数对象上使用 count()
会 return 1
或 0
.
var_dump(count(123)); //int(1)
var_dump(count(new stdclass)); //int(1)
var_dump(count('hello world')); //int(1)
var_dump(count(null)); //int(0)
在 updates to PHP 7.2+ 中,如上所示使用 count()
将发出警告消息。
An E_WARNING will now be emitted when attempting to count() non-countable types (this includes the sizeof() alias function).
Warning: count(): Parameter must be an array or an object that implements Countable
[sic]
因此,许多流行的框架将提升 E_WARNING
并抛出异常。
[ErrorException] count(): Parameter must be an array or an object that implements Countable
PHP 开发人员也评论了错误提升行为。
Environments that display warnings or convert them to more severe errors/exceptions would be affected, but this should just bring attention to a bug in the code.
如何在 PHP 7.2+ 中实现 count()
的先前行为,即不发出 E_WARNING
,不修改错误报告设置且不使用 [=19] =]?
问题是在未实现 Countable 接口的标量或对象上调用 count()
returns 1,这很容易隐藏错误。
鉴于以下情况:
function handle_records(iterable $iterable)
{
if (count($iterable) === 0) {
return handle_empty();
}
foreach ($iterable as $value) {
handle_value($value);
}
}
传递一个不产生任何结果的生成器不会调用 handle_empty()
也不会 handle_value()
。
此外,没有任何迹象表明两者都没有被调用。
默认情况下,这仍将 return 1
,但会另外记录警告。如果有的话,这个警告将引起人们对代码中潜在错误的注意。
有关详细信息,请参阅 Counting Non-Countables。
正如我们所讨论的,有多种方法可以实现 count()
的原始功能而不发出 E_WARNING
。
在 PHP 7.3 中添加了一个新函数 is_countable
,专门用于解决 E_WARNING
问题以及在其代码中采用 is_array($var) || $var instanceof \Countable
的应用程序的普遍性。
In PHP 7.2, a Warning was added while trying to count uncountable
things. After that, everyone was forced to search and change their
code, to avoid it. Usually, the following piece of code became
standard:
if (is_array($foo) || $foo instanceof Countable) {
// $foo is countable
}
自定义函数替换
因此,解决问题的最佳方法似乎是执行 PHP 对 is_countable
执行的相同功能,并创建自定义函数以确保符合原始功能count
.
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
,所以只在需要的时候使用,开销最小。
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()
的功能没有改变,而且过去通常不会发出警告。使用自定义函数的另一种方法是使用 @
Error Control Operator
完全忽略警告
Warning: This approach has the impact of treating undefined variables as NULL
and not displaying Notice: Undefined variable:
message.
@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
(高级 PHP 调试器),允许 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;
}
你可以用“??”运算符来解决。如果左侧为空,则使用右侧。因此,由于我们有一个空数组,我们的结果将为零。
count(null ?? [])
另一种方法是将其转换为数组。
count((array) null)
在 PHP 7.2 之前,在标量值或不可数对象上使用 count()
会 return 1
或 0
.
var_dump(count(123)); //int(1)
var_dump(count(new stdclass)); //int(1)
var_dump(count('hello world')); //int(1)
var_dump(count(null)); //int(0)
在 updates to PHP 7.2+ 中,如上所示使用 count()
将发出警告消息。
An E_WARNING will now be emitted when attempting to count() non-countable types (this includes the sizeof() alias function).
Warning: count(): Parameter must be an array or an object that implements Countable [sic]
因此,许多流行的框架将提升 E_WARNING
并抛出异常。
[ErrorException] count(): Parameter must be an array or an object that implements Countable
PHP 开发人员也评论了错误提升行为。
Environments that display warnings or convert them to more severe errors/exceptions would be affected, but this should just bring attention to a bug in the code.
如何在 PHP 7.2+ 中实现 count()
的先前行为,即不发出 E_WARNING
,不修改错误报告设置且不使用 [=19] =]?
问题是在未实现 Countable 接口的标量或对象上调用 count()
returns 1,这很容易隐藏错误。
鉴于以下情况:
function handle_records(iterable $iterable)
{
if (count($iterable) === 0) {
return handle_empty();
}
foreach ($iterable as $value) {
handle_value($value);
}
}
传递一个不产生任何结果的生成器不会调用 handle_empty()
也不会 handle_value()
。
此外,没有任何迹象表明两者都没有被调用。
默认情况下,这仍将 return 1
,但会另外记录警告。如果有的话,这个警告将引起人们对代码中潜在错误的注意。
有关详细信息,请参阅 Counting Non-Countables。
正如我们所讨论的,有多种方法可以实现 count()
的原始功能而不发出 E_WARNING
。
在 PHP 7.3 中添加了一个新函数 is_countable
,专门用于解决 E_WARNING
问题以及在其代码中采用 is_array($var) || $var instanceof \Countable
的应用程序的普遍性。
In PHP 7.2, a Warning was added while trying to count uncountable things. After that, everyone was forced to search and change their code, to avoid it. Usually, the following piece of code became standard:
if (is_array($foo) || $foo instanceof Countable) { // $foo is countable }
自定义函数替换
因此,解决问题的最佳方法似乎是执行 PHP 对 is_countable
执行的相同功能,并创建自定义函数以确保符合原始功能count
.
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
,所以只在需要的时候使用,开销最小。
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()
的功能没有改变,而且过去通常不会发出警告。使用自定义函数的另一种方法是使用 @
Error Control Operator
Warning: This approach has the impact of treating undefined variables as
NULL
and not displayingNotice: Undefined variable:
message.
@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
(高级 PHP 调试器),允许 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;
}
你可以用“??”运算符来解决。如果左侧为空,则使用右侧。因此,由于我们有一个空数组,我们的结果将为零。
count(null ?? [])
另一种方法是将其转换为数组。
count((array) null)