Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Conversation

kaplanlior
Copy link

No description provided.

Copy link
Member

@weierophinney weierophinney left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've noted changes; we need a solution that does not use error suppression.

Also, if possible, please provide either unit tests that prove the fix, or data we can use to try and reproduce, to ensure we don't break this in the future.

@@ -241,7 +241,7 @@ protected function createSqlFromSpecificationAndParameters($specifications, $par
if (isset($paramSpecs[$position]['combinedby'])) {
$multiParamValues = [];
foreach ($paramsForPosition as $multiParamsForPosition) {
$ppCount = count($multiParamsForPosition);
$ppCount = @count($multiParamsForPosition);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our coding guidelines have a preference for NOT using error suppression. In this case, I'd do one of the following:

  • See if $multiParamsForPosition is an array, and, if so, return count($multiParamsForPosition)
  • If $multiParamsForPosition is an object, test if it is Countable, and, if so, return $multiParamsForPosition->count()
  • Otherwise, raise an exception (invalid data is present!)

@trasher
Copy link

trasher commented Jul 18, 2017

I had to patch for one of my projects; you've also missed some ocurrences. Attached the patch I've applied (zend-db 2.8.2), if that can help :)

zend-db-php7.2.zip

trasher added a commit to galette/galette that referenced this pull request Jul 18, 2017
Calling the count function triggers warning message: "count(): Parameter
must be an array or an object that implements Countable".

More info at https://wiki.php.net/rfc/counting_non_countables
@sgchris
Copy link

sgchris commented Jul 19, 2017

Raising an exception breaks backward compatibility - if beforehand we passed a string to the function everything worked fine, now, after the fix it will fail.
(PHP's "count" with string raises a warning, but doesn't break the application)

@weierophinney
Copy link
Member

(PHP's "count" with string raises a warning, but doesn't break the application)

What does it return in such cases? Is it usable?

@sgchris
Copy link

sgchris commented Jul 19, 2017

It returns 1, and starting from v7.2 it raises a warning.

@weierophinney
Copy link
Member

It returns 1, and starting from v7.2 it raises a warning.

Right, and the warning is what the original patch was trying to eliminate. The question I have is: is 1 an appropriate return for this? If so, instead of raising an exception for such uncountable values, we could return 1. But if it's not, the exception is essentially fixing incorrect behavior.

@sgchris
Copy link

sgchris commented Jul 26, 2017

I think it's best to be stick to PHP's behavior, and it tells us kindly to use "count" in a proper way (with notice or warning), but it doesn't break the functionality of existing applications.

It would be very wrong and unpleasent situation when someone will upgrade his ZF minor version, and discover that something is broken.

I assume that in further PHP versions, this issue will become an error, than we should fix it in ZF too. But now it gives some time to breathe, reconsider "count" usage and fix the running apps.

So - yes, we should return 1 for "string" var (for other types we should check "count" behavior)

@alextech
Copy link
Contributor

Exception is a proper way to be kindly notified that something needs fixing. Framework throwing new exception is something I can fix. Framework raising a notice or warning is not something I can deal with. If I do not want to take a hit at engine level for having notice rasied, AND cannot realistically deal with production logging now filled with warnings and CI build system that inspects code for engine message break the build, framework raising messages is something i cannot fix.

@sgchris
Copy link

sgchris commented Jul 26, 2017

  1. Initially, I raised this issue in order to keep backwards compatibility. However, in the updated file I noticed even more significant change - the declaration of the method changed. According to the old PHPDoc the parameter was of type "string|array", but now it's just "array". That's a big issue.

  2. Much simpler solution would be to wrap the string parameter in an array. A simple "if" statement in the beginning of the method, and we aren't dealing here with log messages and exceptions.

@alextech
Copy link
Contributor

Sorry, can you please point at the declaration of method you refer to? I can't find it in the changelist.

@sgchris
Copy link

sgchris commented Jul 26, 2017

The one I meant is related to commit eb6cb76, in which the "string" word was removed from the phpdoc. There is a "count" applied on that parameter too.

@trasher
Copy link

trasher commented Aug 15, 2017

I've just get an issue using something like $select->group('myfield'): the parameter in that case is a string; and the exception is raised... This is not expected.

I do not know enough the framework to be sure we really want a string in that case; but since we got one; calling an exception is probably not the way to go.
Actual behavihor (count equals to 1) does not seems correct. What about just taking the verbatim value when this is not an array? Instead of the exception; we could simply do a $multiParamValues[] = $multiParamsForPosition; I guess.

trasher added a commit to galette/galette that referenced this pull request Aug 16, 2017
} else {
throw new Exception\UnexpectedValueException(sprintf(
'Parameters must be an array or a countable object, %s given',
gettype($multiParamsForPosition)
Copy link
Contributor

@remicollet remicollet Oct 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should not raise an exception, as this may break some other code, for the string case

At least in zend-paginator test suite

1) ZendTest\Paginator\Adapter\DbTableGatewayTest::testGetItemsWithWhereAndOrderAndGroup
count(): Parameter must be an array or an object that implements Countable
/usr/share/php/Zend/Db/Sql/AbstractSql.php:244
/usr/share/php/Zend/Db/Sql/AbstractSql.php:72
/usr/share/php/Zend/Db/Sql/AbstractPreparableSql.php:34
/usr/share/php/Zend/Db/Sql/Platform/Platform.php:100
/usr/share/php/Zend/Db/Sql/Sql.php:130
/builddir/build/BUILDROOT/php-zendframework-zend-paginator-2.7.0-3.fc28.noarch/usr/share/php/Zend/Paginator/Adapter/DbSelect.php:100
/builddir/build/BUILD/zend-paginator-42211f3e1e8230953c641e91fec5aa9fe964eb95/test/Adapter/DbTableGatewayTest.php:121
2) ZendTest\Paginator\Adapter\DbTableGatewayTest::testGetItemsWithWhereAndOrderAndGroupAndHaving
count(): Parameter must be an array or an object that implements Countable
/usr/share/php/Zend/Db/Sql/AbstractSql.php:244
/usr/share/php/Zend/Db/Sql/AbstractSql.php:72
/usr/share/php/Zend/Db/Sql/AbstractPreparableSql.php:34
/usr/share/php/Zend/Db/Sql/Platform/Platform.php:100
/usr/share/php/Zend/Db/Sql/Sql.php:130
/builddir/build/BUILDROOT/php-zendframework-zend-paginator-2.7.0-3.fc28.noarch/usr/share/php/Zend/Paginator/Adapter/DbSelect.php:100
/builddir/build/BUILD/zend-paginator-42211f3e1e8230953c641e91fec5aa9fe964eb95/test/Adapter/DbTableGatewayTest.php:143

@remicollet remicollet mentioned this pull request Oct 31, 2017
@ezimuel
Copy link
Contributor

ezimuel commented Nov 28, 2017

Fixed in #276

@ezimuel ezimuel closed this Nov 28, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants