Php count()发出E_警告

Php count()发出E_警告,php,php-7.2,Php,Php 7.2,在PHP7.2之前,对标量值或不可数对象使用将返回1或0 例如: 在中,如上所示使用count()将发出警告消息 尝试计数()不可计数类型(包括sizeof()别名函数)时,将发出E_警告 警告:count():参数必须是实现可计数的数组或对象 因此,许多流行的框架将提升E_警告,并抛出异常 [ErrorException]count():参数必须是实现可计数的数组或对象 PHP开发人员还对错误提升行为进行了评论 显示警告或将其转换为更严重错误/异常的环境将受到影响,但这应该引起对代码中错误的

在PHP7.2之前,对标量值或不可数对象使用将返回
1
0

例如:

在中,如上所示使用
count()
将发出警告消息

尝试计数()不可计数类型(包括sizeof()别名函数)时,将发出E_警告

警告:count():参数必须是实现可计数的数组或对象

因此,许多流行的框架将提升
E_警告
,并抛出异常

[ErrorException]count():参数必须是实现可计数的数组或对象

PHP开发人员还对错误提升行为进行了评论

显示警告或将其转换为更严重错误/异常的环境将受到影响,但这应该引起对代码中错误的注意


在PHP7.2+中,如果不修改错误报告设置,也不使用
@count()
,那么如何在不发出
E_警告的情况下实现
count()
?问题是,对未实现可数接口的标量或对象调用
count()
,返回1,可以很容易地隐藏bug

鉴于以下情况:

function handle_records(iterable $iterable)
{
    if (count($iterable) === 0) {
        return handle_empty();
    }

    foreach ($iterable as $value) {
        handle_value($value);
    }
}
传递一个不产生任何结果的生成器不会调用
handle\u empty()
handle\u value()

此外,没有迹象表明两人都没有被调用

默认情况下,这仍将返回
1
,但会另外记录警告。如果有的话,这个警告会引起对代码中潜在错误的注意


有关更多信息,请参阅。

正如我们所讨论的,有多种方法可以实现
count()
的原始功能,并且不会发出
E\u警告

在PHP7.3中添加了一个新函数,专门用于解决
E_警告
问题,以及应用程序在其代码中普遍采用
is_数组($var)|$var instanceof\Countable

在PHP7.2中,尝试计数不可数时添加了警告 东西。在那之后,每个人都被迫搜索和更改他们的密码 代码,以避免它。通常情况下,下面的一段代码 标准:

if(是_数组($foo)| |$foo instanceof Countable){
//$foo是可数的
}


自定义函数替换 出于这个原因,解决这个问题的最佳方法似乎是执行与PHP使用的
is\u countable
相同的功能,并创建一个自定义函数以确保符合
count
的原始功能

示例

结果

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
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

垫片
是可计数的()
函数 使用上述替换函数,还可以在
PHP中填充
is_countable
,您可以使用“?”运算符解决该问题。如果左侧为空,则使用右侧。因此,当我们有一个空数组时,我们的结果将是零

计数(空???[])
另一种方法是将其类型转换为数组

计数((数组)null)

您传递字符串/数字时,首先要使用的函数是错误的。我要回滚到7.1。PHP开发人员应该把7.2变成8.0;普遍接受的版本号控制准则说,当更改破坏向后兼容性时,增加主(第一个)号。期望一个小补丁(增加到第二个数字)没有这样的中断不是不合理的。你实际上是在问“模仿count()的最佳方法是什么”,这对于SO来说不是一个有效的问题。因为它将获得多个答案,产生固执己见的结果。在您看来,
@
是不好的,尽管它产生了预期的结果,但这是由于您非常合理的考虑。长期可维护性也是主观的。归根结底,您希望继续以一种非预期的方式使用count,这一点自2013年以来就有了记录。IMO最好的方法是重构代码,使其与7.2+兼容,原因如下所述;我只是想知道stackoverflow发生了什么事。无论如何,谢谢你给我答案的链接。遗憾的是,它不能发布在这里,我很想得到这些解决方案的反馈,或者给出反馈。真的很遗憾。这就是为什么人们使用stackoverflow来寻找问题的解决方案,而不仅仅是批评一个对许多开发人员来说非常重要的问题。我很感激这个问题和所有的答案。嗯,你没有错。问题是,这就是这个函数的工作原理。如果你不了解这个函数是如何工作的,它可能会导致bug。他们现在所做的是,他们改变了一个核心函数,因为有人不喜欢旧函数。打破了很多库。我只是在像这样计数之前将变量设置为数组。如果(!is_array($arrayVariable)){$arrayVariable=array();}
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
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($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
\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;
}