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

What steps will reproduce the problem?

A lot of tests on PHP 7.2 are failing with

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

count() throws a warning since PHP 7.2 in case a scalar or non-countable object is passed. We rely on this behavior in many places so code needs to be adjusted.

Need to check how many places are affected and whether its easy to fix. If its hard to fix in a BC way, PHP 7.1 may be the last version that Yii 1.1 runs on.

More info

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 26 (15 by maintainers)

Commits related to this issue

Most upvoted comments

Partly fixed.

Not a good idea for now.

Hope having it soon. We have 7.2 tests now and these are passing.

There is another issue in CActiveFinder in queryOneMany in line if(count($fks)!==count($pkTable->primaryKey)) If primaryKey is string the count() doesn’t work. It can be easy fixed with: if(count($fks)!==count(array($pkTable->primaryKey)))

There is another one on framework/gii/generators/model/ModelCode.php:371 Fixed it with

...
$pk=$table->primaryKey;
$count=is_array($pk) ? count($pk) : 1;
return ($count === 2 // we want 2 columns
...

I’ve checked trunk version and it looks it is already fixed with https://github.com/yiisoft/yii/commit/05d2c67555e8b67ef54906148775997acf018840. The latest version 1.1.19 is not. What are plans regarding 7.2 compatibility? When the next release that is 7.2 compatible will be released?

If you pass a scalar value as $values the count() will return 1, which gets you into the elseif($n===1) branch. There you have $value = reset($values), which would fail because reset() expects an array.

So I do not see how your code runs fine in other PHP versions < 7.2: https://3v4l.org/nHrpA

Thank you @cebe and @rob006 for this feedback.

I have taken this opportunity to audit all our application code that uses CDbCriteria::addInCondition() and ::addNotInCondition(). All instances except one pass an array as the $value parameter. The one case where a non-array is (sometimes) passed, it’s always empty. I will fix the application code in this one case.