count(): Parameter must be an array or an object that implements Countable (Параметр должен быть массивом или объектом, который реализует счет в)

208
05 октября 2018, 12:30

Дорогие коллеги объясните пожалуйста мне одну вещь, в метод count() передаю объект (мне это так казалось, а как оказалось там был Json ответ гугл аналитики). Значит мне выпало предупреждение

count(): Parameter must be an array or an object that implements Countable

Сначала я ему как он и хотел сунул массив но он мне не выдал результата и соответственно предупреждения, далее я ему скормил уже объект, а теперь показался и результат и предупреждение тоже.

Мне эти предупреждения с роду не нравились (не покажешь же ты их конечному пользователю), ну я ему и подсунул собаку. вот собственно и пример кода

if (@count((object)$results->getRows()) > 0) {

Так вот хотелось бы услыхать возможно ли такое делать в принципе? А если нет то по каким причинам. Благодарю за ответы.

Answer 1

Так вот хотелось бы услыхать возможно ли такое делать в принципе?

Ну с массивом все и так ясно

<?php
$a[0] = 1;
$a[1] = 3;
$a[2] = 5;
var_dump(count($a));

А вот с объектами тут другая история, но тоже всё легко. Нужно всего-то имплементировать интерфейс Countable, у которого есть одноименный метод count.

Вот пример с офф. сайта:

class CountMe implements Countable 
{ 
    protected $_myCount = 3; 
    public function count() 
    { 
        return $this->_myCount; 
    } 
} 
$countable = new CountMe(); 
echo count($countable); //result is "3" as expected 

Так как в вашем примере ни того ни другого, вы получаетет ошибку.

  • Countable
  • count
Answer 2

Ну как всегда, выскажу свое мнение:

Итак, нашего бульдога ставят на охрану только в случаях неопределенности, таких случаев очень мало, например раньше часто использовали при удалении файлов, инклудов. Сейчас реже и реже. Смысл в том что ваш код по дефолту должен работать без каких либо ошибок, если вам нужно засунуть в count объект, то можно использовать типа:

count(get_object_vars($OBJECT))

Делать такое можно, НО вы должны понимать, что вызывая собаку вы замедляете работу скрипта. На глазок самым долгим будет count с генерацией ошибки (вообще любая генерация ошибки очень ресурсоемкая и долгая, поэтому и избегают), потом будет идти @count и самый быстрый вариант count без ошибки.

Теперь осталось определить, к чему ближе @ к первому варианту(самому долгому) или к последнему (самому быстрому). Скорей к первому, почему, потому-что собака подавляет не все виды ошибок, а лишь некоторые, например ParseError будет и с собакой приводить к критической ошибке. В двух словах схема такова: возникает ошибка, вызывается генератор ошибок, он определяет ошибку (это уже ресурсоемкий процесс), дальше проверяет может ли собака его подавить, если да то заканчиваем дело, если нет - выбиваем критулю.

Я под юбку интерпретатору не заглядывал, но вроде как так. Сама концепция - одинаковая, собаки - плохо, кошки лучше, особено британские либо шотландские :)

Answer 3

if (@count((object)$results->getRows()) > 0)

Так вот хотелось бы услыхать возможно ли такое делать в принципе? А если нет то по каким причинам. Благодарю за ответы.

Варианты :

if (count((array)$results->getRows()))
  1. Убеждаемся что $results->getRows() точно массив через приведение типов ((array)$results->getRows()). Поскольку там по сути может быть любой тип.
  2. Ваш класс от которого был создан экземпляр объекта $results имплементировать от интерфейса Countable и реализовать собственный метод count.Классы, реализующие интерфейс Countable, могут быть использованы с функцией count().

Если сложен 2 вариант то выбирайте 1.Хотя на всякий случай знайте что агрегирование объектов в массив и наоборот всегда ресурсозатратная работа.

Собака (@) это медленный оператор,так не надо делать, поскольку вы вредите себе дважды.Это тоже самое что если бы вы выключили вывод ошибок (error_reporting(0)), произвели бы что либо и обратно его включили бы (error_reporting(E_ALL)).

И помните тоже что нету смысла на всякий проверять на больше нуля в логических конструкциях (if), так как любое выражение в PHP приводятся к булеву типу (TRUE или False). 0 = FALSE, а > 0 это TRUE.

READ ALSO
В теме Motors почему-то не работает 404.php

В теме Motors почему-то не работает 404.php

Сайт создан на теме вордпресс МоторсУрл несуществующей ссылки выдает:

153
Как найти Альт символ?

Как найти Альт символ?

Из вк надо спарсить контент где встречается зеленая галочка, по сути альт код вроде бы нашел ✅ но он не находится, такое ощущение как будто...

173
не подключается к БД SQLSTATE[3D000]

не подключается к БД SQLSTATE[3D000]

Перенес сайт с одного хостинга на другой, на первом хостинге была одна БД, а на новом двеподключение к БД происходит, но при запросе к БД выдается...

171
Работа со списком и запись его в файл

Работа со списком и запись его в файл

Наподобие такого наверное (правда Вам это не поможет скорее всего, написал за два часа - куча багов, разве что примерно как делать) :

178