php - count() 发出 E_WARNING

标签 php php-7.2

PHP 7.2 之前使用 count()在标量值或不可数对象上将返回 10

例如:https://3v4l.org/tGRDE

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,不修改错误报告设置,也不使用 @count()?

最佳答案

正如我们所讨论的,有多种方法可以实现 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 }

https://wiki.php.net/rfc/is-countable


自定义函数替换

因此,解决该问题的最佳方法似乎是执行 PHP 使用 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

垫片 is_countable()功能

使用上面的替换函数,也可以填充is_countablePHP <= 7.2 ,因此它仅在需要时使用,开销最小。

示例 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()的功能没有改变,过去通常不会发出警告。使用自定义函数的替代方法是使用 @ 完全忽略警告。 Error Control Operator

Warning: This approach has the impact of treating undefined variables as NULL and not displaying Notice: Undefined variable: message.

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

替换count()使用 APD 扩展

至于替换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;
}

关于php - count() 发出 E_WARNING,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49662029/

相关文章:

php - Homebrew 软件在 Mac High Sierra 上的哪里安装 PHP?

php - PHP 7 中静默 "Declaration ... should be compatible"警告

windows - Docker xDebug 未连接到 VSCode

php - 试图从 php 脚本 : returns a pid but doesn't execute 运行 python 脚本

php - Symfony 不处理并发请求

php - 使用 Magento 重新索引刚刚以编程方式更改的产品

phpunit - 如何在 phpunit 测试中伪造 DateTime?

php - CKEditor <p> 标签和删除填充

php - 我正在寻找英语单词列表

PHP DateTime 差异返回错误的天数