Как мы уже говорили, есть несколько способов добиться исходной функциональности 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 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_countable
на PHP <= 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 Оператор управления
Предупреждение. Этот подход приводит к тому, что неопределенные переменные рассматриваются как 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
Замените count()
, используя расширение APD
Что касается замены внутренней функции PHP count()
. Существует расширение PECL APD
(Advanced PHP Debugger), которое позволяет выполнять override_function
< /a>, который работает с основными функциями 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;
}
person
Will B.
schedule
21.09.2018
countLegacy()
самостоятельно и выполните простой поиск и замену в своей кодовой базе. - person Scuzzy   schedule 05.04.2018echo
? python вот-вот оправятся от своих страданий, мы направляемся прямо туда, откуда они пришли. Это шутка - person Toskan   schedule 05.04.2018An E_WARNING will now be emitted
верно? Предупреждение, а не фатальное, что дает разработчикам время отреагировать. - person Scuzzy   schedule 05.04.2018Everyone does it. Why not do it?
Отсутствие охвата передового опыта приведет к нежелательным/неожиданным результатам, что вы и видите сейчас при переходе на 7.2 и использованииcount()
в непреднамеренная мода, зарегистрированная с 2013 года сarray_or_countable
. Вместо этого я предлагаю форсировать ожидаемый тип данных, используя преобразование типовcount((array) $value)
, что приведет к нежелательному результату преобразованияstdClass
в массив и получить 0 вместо 1. - person Will B.   schedule 05.04.2018print
функцию? зачем менять основную функциюcount
через какие 15 лет? теперь все либы выдают предупреждения и мне нужно откатиться на 7.1. Не могу дождаться, когда они изменят и все остальные основные функции. Лучшей практикой является совместимость, если для этого нет очень-очень веской причины. - person Toskan   schedule 05.04.2018mcrypt
,mysql_*
поддерживались в PHP 4 и 5, но не в 7 и т. д. Все это было средством оптимизации основного движка, чтобы он работал быстрее или был более безопасным. - person Will B.   schedule 05.04.2018@count($value)
в кодовой базе. Поскольку count будет работать одинаково независимо от любого типа данных. Однако это не будет учитывать какие-либо библиотеки поставщиков, которые вы используете, и должно действительно использоваться только при подготовке к обновлению функциональности. - person Will B.   schedule 05.04.2018count
, без повышенияwarning
, что он делает в PHP 7.2+. Поскольку нет окончательного способа выполнить это, и можно НЕ учитывайте использованиеcount()
в ваших сторонних пакетах, это даст только самоуверенные ответы. Например: 3v4l.org/UFieo — это три разных способа, с помощью которых можно получить альтернативу подсчету. Существуют и другие важные методы. Но в конечном итоге способ, которым вы используете count, не поддерживается и должен быть реорганизован. - person Will B.   schedule 06.09.2018@
может быть нежелательным. В дополнение к вашему случаю Framework, который также используетcount
в своем базовом коде. Ни один из примеров не решит вашу проблему сcount
в Framework. Это приведет к другим ответам на решение проблемы с фреймворком. Например, переопределениеcount
из базовой библиотеки PHP и многие другие, которые не являются окончательными. - person Will B.   schedule 06.09.2018@
плохо, потому что оно не будет поддерживать долгосрочную поддержку. Возможно, однажды они выдадут ошибку вместо предупреждения. По какой-то причине вы просто пытаетесь избежать очень правильного вопроса. Нет лучше и хуже, есть только черное и белое. Я думаю, это глупо. Это действительно так. Боты для голосования в Stackoverflow должны быть остановлены. - person Toskan   schedule 06.09.2018@
это плохо, несмотря на то, что оно дает желаемый результат из-за ваших очень обоснованных опасений. Долгосрочная ремонтопригодность также субъективна. Все сводится к тому, что вы хотите продолжать использовать count непреднамеренным образом, который был задокументирован с 2013 года. Лучшим подходом, IMO, было бы реорганизовать ваш код, чтобы он был совместим с 7.2+, по причинам, которые вы отметили; что в будущем это может вызвать исключение - person Will B.   schedule 06.09.2018