Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid warning in PHP 7.2 because of non-countable data #20859

Merged
merged 1 commit into from Dec 26, 2016

Conversation

wouterj
Copy link
Member

@wouterj wouterj commented Dec 10, 2016

Q A
Branch? 2.7
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets -
License MIT
Doc PR -

Recently, the "Counting of non-countable objects" RFC was merged in PHP 7.2-dev. This means count() now causes a warning when passing anything that's not countable (e.g. null or '').

As PHP does not lazily execute conditions, FormUtil::isEmtpy($data) || 0 === count($data) will cause both conditions to be executed. This means count($data) errors when $data is empty.

Splitting it up in 2 statements avoids the warning being triggered in PHP 7.2.

See https://travis-ci.org/symfony-cmf/content-bundle/jobs/181815895 for a failing test caused by this bug.

@ogizanagi
Copy link
Member

As PHP does not lazily execute conditions, FormUtil::isEmtpy($data) || 0 === count($data) will cause both conditions to be executed. This means count($data) errors when $data is empty.

I'm quite surprised by your statement and the fact it solves your issue, because AFAIK php does execute lazily expressions (short circuit evaluation): https://3v4l.org/V4H6E.
So it should execute 0 === count($data) only when FormUtil::isEmtpy($data) is false.

See also http://php.net/manual/en/language.operators.logical.php#example-103

Am I missing something?

}

// arrays, countables
return 0 === count($this->modelData) ||
// traversables that are not countable
($this->modelData instanceof \Traversable && 0 === iterator_count($this->modelData));
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't it check this before 0 === count($this->modelData)?

Copy link
Member Author

Choose a reason for hiding this comment

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

With the latest update, it doesn't have to be done before the count.

@wouterj
Copy link
Member Author

wouterj commented Dec 10, 2016

Oh, indeed. You're completely correct, I interpreted the erroring build incorrectly. The problem is actually when counting non-empty strings or the like.

Updated the PR with the correct change.

@ogizanagi
Copy link
Member

👍

Status: Reviewed.

@@ -748,7 +748,7 @@ public function isEmpty()

return FormUtil::isEmpty($this->modelData) ||
// arrays, countables
0 === count($this->modelData) ||
((is_array($this->modelData) || $this->modelData instanceof \Countable) && 0 === count($this->modelData)) ||
Copy link
Member

Choose a reason for hiding this comment

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

what about:

array() === $this->modelData ||
($this->modelData instanceof \Countable && 0 === count($this->modelData) ||

Copy link
Member Author

Choose a reason for hiding this comment

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

This is to avoid calling count() on an array? If that's the case, shouldn't we fix this throughout all 0 === count() calls in the code base?

Copy link
Member

Choose a reason for hiding this comment

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

I find it more readable :)

Copy link
Contributor

Choose a reason for hiding this comment

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

creating an empty array to test if some var is also an empty array seems a bit much for syntax sugar?

Copy link
Contributor

@ro0NL ro0NL Dec 16, 2016

Choose a reason for hiding this comment

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

Shouldnt this be covered by FormUtils::isEmpty (or maybe add isEmptyCollection)?

Ie. what about https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php#L98?

@xabbuh
Copy link
Member

xabbuh commented Dec 25, 2016

What is the state here?

@wouterj
Copy link
Member Author

wouterj commented Dec 25, 2016

@xabbuh PR is ready to merge imo. @nicolas-grekas's comment seems to be more related to a change in coding standard (array() === $var instead of 0 === count($var)). This should be moved into a separate issue, to discuss it and fix it throughout the code base consistently.

@fabpot
Copy link
Member

fabpot commented Dec 26, 2016

Thank you @wouterj.

@fabpot fabpot merged commit 94253e8 into symfony:2.7 Dec 26, 2016
fabpot added a commit that referenced this pull request Dec 26, 2016
…uterj)

This PR was merged into the 2.7 branch.

Discussion
----------

Avoid warning in PHP 7.2 because of non-countable data

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

Recently, the "[Counting of non-countable objects][1]" RFC was merged in PHP 7.2-dev. This means `count()` now causes a warning when passing anything that's not countable (e.g. `null` or `''`).

As PHP does not lazily execute conditions, `FormUtil::isEmtpy($data) || 0 === count($data)` will cause *both* conditions to be executed. This means `count($data)` errors when `$data` is empty.

Splitting it up in 2 statements avoids the warning being triggered in PHP 7.2.

See https://travis-ci.org/symfony-cmf/content-bundle/jobs/181815895 for a failing test caused by this bug.

 [1]: https://wiki.php.net/rfc/counting_non_countables

Commits
-------

94253e8 Only count on arrays or countables to avoid warnings in PHP 7.2
@nicolas-grekas
Copy link
Member

nicolas-grekas commented Dec 26, 2016

@wouterj note that I'm a bit disappointed here. In https://speakerdeck.com/nicolasgrekas/go-beyond-composer-update-contribue, you'll find a slide saying: "When you don't care, follow the suggestions".
Why? Because it saves everyone's time, and gratifies reviewers for their contribution. I could elaborate but enough time on this, merging was indeed required now.
Note that I added this slide by thinking of my own experience resisting to suggestions. The human brain is lazy and resisting is often the default behavior. Yet, I learned that this is making everyone loose their time, so that when I don't care enough, I'd better do the change than start another bike-shading.

@ro0NL
Copy link
Contributor

ro0NL commented Dec 26, 2016

4-1 against should be followed, i like your point here 👍

Note that the opposite is also true, reviewers not always know about inner details, so if it's ignored they dont care as well (we dont want to say anything (more) stupid do we). Sometimes it's just a brainfart, or a what if suggestion.

Problem is.. if we all start ignoring and stop caring the codebase will suffer.

@wouterj wouterj deleted the patch-18 branch December 26, 2016 12:16
fabpot added a commit that referenced this pull request Jan 8, 2017
…ytrase)

This PR was squashed before being merged into the 2.7 branch (closes #21155).

Discussion
----------

[Validator] Check cascasdedGroups for being countable

Prevents notice for PHP 7.2

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        |

Just repeated for this place #20859
Waiting travis to fill in the `Tests pass` field

`cascasdedGroups` can be null at this point (according to failures and phpdoc)

Commits
-------

8fa45a1 [Validator] Check cascasdedGroups for being countable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants