Skip to content

Conversation

@mspirkov
Copy link

@mspirkov mspirkov commented Jan 7, 2026

@keradus suggested clarifying the situation with closures that have an empty body: PHP-CS-Fixer/PHP-CS-Fixer#9329 (comment)

I agree with him. I think the Closures section lacks an example with an empty body. It seems logical to add an example similar to the one in the Classes, Properties, and Methods section:

per-coding-style/spec.md

Lines 592 to 603 in c83ab63

If a function or method contains no statements or comments (such as an empty no-op implementation or when using
constructor property promotion), then the body SHOULD be abbreviated as `{}` and placed on the same
line as the previous symbol, separated by a space. For example:
```php
class Point
{
public function __construct(private int $x, private int $y) {}
// ...
}
```

What do you think about this?

spec.md Outdated
};
```

If a closure contains no statements or comments then the body SHOULD be abbreviated
Copy link

Choose a reason for hiding this comment

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

would recommend MUST
(but happy with both)

Copy link
Author

Choose a reason for hiding this comment

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

I think it should be similar to the Classes, Properties, and Methods section:

per-coding-style/spec.md

Lines 592 to 593 in c83ab63

If a function or method contains no statements or comments (such as an empty no-op implementation or when using
constructor property promotion), then the body SHOULD be abbreviated as `{}` and placed on the same

Copy link

Choose a reason for hiding this comment

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

would recommend MUST in both places then ;)

Copy link

@keradus keradus left a comment

Choose a reason for hiding this comment

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

would love this to be explicitly clarified ! 🎉

@KorvinSzanto
Copy link
Contributor

KorvinSzanto commented Jan 7, 2026

This isn't so much a clarification as it is a change to requirements. Closures currently have the following requirement:

The opening brace MUST go on the same line, and the closing brace MUST go on
the next line following the body.

And abbreviated {} style is explicitly limited to classes, methods, and functions: #44

I think it'd be okay to make this change, but it's important to be clear that it's not just a clarification.

That said, when would someone actually want to do this instead of using a short function which already allows single line declaration?

IE:

$noOpClosure = fn() => null;

@jrfnl
Copy link
Contributor

jrfnl commented Jan 7, 2026

This isn't so much a clarification as it is a change to requirements.

Agreed, so this would need a new major release.

@mspirkov
Copy link
Author

mspirkov commented Jan 7, 2026

This isn't so much a clarification as it is a change to requirements.

From the outside, it seems that this case was simply forgotten to be described, since it is written explicitly for class methods and functions. But I agree with you - this is actually a new requirement.

@mspirkov
Copy link
Author

mspirkov commented Jan 7, 2026

That said, when would someone actually want to do this instead of using a short function which already allows single line declaration?

I think this is a real case, because:

  1. In PHP versions lower than 7.4, we cannot use fn
  2. I think it's a matter of taste. I mean using the fn() => null or function () {}

@Crell
Copy link
Collaborator

Crell commented Jan 7, 2026

For context, the reason we went with a SHOULD for classes was to avoid it being a hard BC break. It allowed existing code to continue to be legal, while formatters changed their defaults gradually to single-line it.

Would a SHOULD here be safe enough to only trigger a 3.1, not a 4.0, since it leaves existing code still legal? I'd prefer to not tag a 4.0 if possible, though I agree the same logic should apply to anything with a body.

That said, @KorvinSzanto is correct that the use case in practice seems weird, when short closures are even nicer and have no such concerns. To @mspirkov's point, 7.4 is long-since abandoned so we don't really care about its limitations at this point. 😄

@keradus
Copy link

keradus commented Jan 7, 2026

so this would need a new major release

I was seeing this as forgotten case, as examples were not mentioning it.
If that would be concluded to be bc breaker, please let's documment the status quo for empty body for closures, it would be already better than no explicit description of such case.

and potential breaking change could go to new major, separately, if aligned

@keradus
Copy link

keradus commented Jan 7, 2026

when would someone actually want to do this instead of using a short function which already allows single line declaration?

this was actually coming as request to PHP CS Fixer from PHP community.
ie, 264 usages in Symfony v8 (git grep function | grep ") {}" | wc -l)

If usage of given syntax is allowed, it's great to document style for it explicitly. If you believe it's better to recommend avoiding using function () {} and recommend to use fn() => null instead, totally valid - yet same here, please let's have it documented ;)

@Crell
Copy link
Collaborator

Crell commented Jan 8, 2026

Let's go with "if a closure contains no statements, MUST use the short-hand syntax" (with an example). That neatly sidesteps the BC issue on braces, and gives a clear standard of behavior. Also, we already have a clause somewhere that says "ignore things that don't apply to your PHP version", so anyone who cares about <7.4 for some reason has nothing to do.

@mspirkov
Copy link
Author

mspirkov commented Jan 8, 2026

Do I understand correctly that we are talking about fn() => null?

@Crell
Copy link
Collaborator

Crell commented Jan 8, 2026

Yes, that.

@keradus
Copy link

keradus commented Jan 8, 2026

@Crell , if I understand idea of MUST vs SHALL in BC break context for PER-CS, I believe your suggestion is same BC as defining spaces/newline for function () {}
so far, function () {\n} is valid according to PER-CS, and your suggestion would make it invalid - so also BC break, no?

it is not that its reserved for PHP <7.4 only, as function () {} is valid syntax on PHP 8.5 and can be used as is, no?

Copy link
Collaborator

@Crell Crell left a comment

Choose a reason for hiding this comment

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

Let's go with "if a closure contains no statements, MUST use the short-hand syntax" (with an example). That neatly sidesteps the BC issue on braces, and gives a clear standard of behavior. Also, we already have a clause somewhere that says "ignore things that don't apply to your PHP version", so anyone who cares about <7.4 for some reason has nothing to do.

By shorthand, we mean fn() => null.

@jrfnl
Copy link
Contributor

jrfnl commented Jan 9, 2026

By shorthand, we mean fn() => null.

May I suggest making that explicit in the text ? I.e. "if a closure contains no statements, it MUST be declared as an arrow function"

@mspirkov mspirkov requested a review from Crell January 15, 2026 08:19
@mspirkov
Copy link
Author

@Crell Please take a look

Co-authored-by: Larry Garfield <[email protected]>
@mspirkov mspirkov requested a review from Crell January 16, 2026 07:20
@Crell Crell mentioned this pull request Jan 16, 2026
5 tasks
Copy link
Collaborator

@Crell Crell left a comment

Choose a reason for hiding this comment

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

I will merge this in a few days if no members of the WG speak up in opposition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants