Problem/Motivation
As discussed in #3060914: All new Drupal 8/9 code must use strict type hints where possible, declare(strict_types=1); should be implemented to ensure consistent typing. There's currently however no defined standard on how strict_types should be defined.
Benefits
To make sure we don't get a mess of styles we should define the pattern for strict_types.
Three supporters required
Option A
- @bbrala (2023-11-17)
- @larowlan (2023-11-18)
- @AaronMcHale (2023-11-17)
- @dww (2023-11-18)
Proposed resolution
Order
In the PHP landscape there's currently mostly 2 different ordering options:
Option A:
<?php
/**
* @file
* This is a file docblock.
*/
declare(strict_types=1);
Option A without docblock:
<?php
declare(strict_types=1);
Option B:
<?php declare(strict_types=1);
/**
* @file
* This is a file docblock.
*/
All implementations in core currently follow option A and contrib modules also seem to favor option A. PSR-12 declares the following in regards to the ordering, which also corresponds with option A:
- Opening <?php tag.
- File-level docblock.
- One or more declare statements.
- ...
Spaces
This is mostly where the current Drupal implementation differ, with implementations currently using declare(strict_types=1); and declare(strict_types = 1);
PSR-12 declares the following in regards to spaces in the declare statement:
Declare statements MUST contain no spaces and MUST be exactly
declare(strict_types=1)
Proposed changes
Adopt option A from above as follows:
1. https://www.drupal.org/docs/develop/standards/php/php-coding-standards
Current text
No text for strict types.
Proposed text
(Right after the section on PHP Code Tags):
Strict type declaration
If you define strict types for a PHP file, place the declare statement on a new line after the opening PHP tag surrounded by empty newlines. If the PHP file has a file level docblock the declare statement should be positioned after that. The declare statement is written without spaces around the equals sign.
<?php /** * @file * This is a file docblock. */ declare(strict_types=1);
Remaining tasks
Create this issue in the Coding Standards queue, using the defined templateList three supportersCreate a Change Recordhttps://www.drupal.org/node/3402544Review by the Coding Standards CommitteeCoding Standards Committee takes action as requiredTagged with 'Needs documentation updates' if Core is not affectedDiscussed by the Core Committer Committee, if it impacts Drupal Core- Documentation updates
Edit all pagesPublish change recordRemove 'Needs documentation updates' tag
If applicable, create follow-up issues for PHPCS rules/sniffs changes
For a fuller explanation of these steps see the Coding Standards project page
Comments
Comment #2
borisson_I agree this is a good idea, I'd love to follow PSR-12 here, since we seem to already be doing a lot of it?
Comment #3
drunken monkeyWhile I personally like the variant better where
declare()comes before any@filedoc block (not on the same line as<?php, though), I’m also in favor of just following PSR-12 here. (This is also getting less and less relevant, with most of our code now in classes without@filedoc.)However, it seems there is an error in the IS? PSR-12 is option A, right, not option B?
Comment #4
dwwComing here from #3376057: [META] Add declare(strict_types=1) to all tests. We're trying to move forward with strict typing in core, but are nearly blocked on deciding the standard for this. Core is already inconsistent.
Comment #5
dwwAt #3401994-13: Add declare(strict_types=1) to all test traits @xjm is in favor of spaces:
At first I agreed, but now I'm back on the fence and open to the PSR-12 argument that this shouldn't use spaces. /shrug
Anyway, we need to decide, ideally soon. 😅
Comment #6
mstrelan commentedIf it means anything, a Github code search for "declare(strict_types=1)" returns 2.9M results, whereas "declare(strict_types = 1)" returns only 247k results.
Comment #7
catchYes I think the issue summary is wrong?
It would be good to have a variant example of option A where there's no file level docblock, which is the case for nearly all of our classes now. I think that's what everyone uses in practice already.
Comment #8
bbralaUpdated IS added example.
Comment #9
xjmI think a critical factor would be what our standards for named arguments are (is there an issue for that yet?). I'd always assumed named arguments would be equivalent to method declarations and argument default values, with the space on either side of the equals sign. My primary concern is having two CS rules that disagree, and if we avoid that, also making it harder to remember because we have two similar standards that disagree.
Places Drupal already requires the space:
If we wanted to adopt more of PSR-12, that would be a far more massive undertaking (it has a cuddled else and all that). That said, it does appear PSR-12 uses spaces around comparison, assignment, and default value operators, but not in the specific case of a named argument for strict types, at least. That seems inconsistent, but if the standard can enforce those things without conflicts, I'm not too fussed if Drupal does or doesn't either way.
-1 on having anything on the same line as the
<?phptag; that way lies heartache. I don't care where anything is relative to the file docblock really.Comment #10
bbralaMy personal opinion is to follow PSR-12 (and largest part of the community) and put it on its own line.
Also as you mentioned in the linked issue, it is not a declaration. Another reason you could argue for no spaces is the error you get if you enforce strict types with phpcs:
The suggestion is without spaces. phpcbf will probably fix without spaces also. This will get confusing when checks are introduced and probably lead to more problems and extra feedback loops.
posted same time as xjm's post :x
Comment #11
bbralaIssue for names arguments: #3337834: Standards for PHP named arguments
Comment #12
larowlanI see this as a test of the coding standards process.
What matters is that we can get this through the process in as short as possible time. If we can't then the process needs to be more agile.
Comment #13
bbralaUpdate IS to codestyle issue template
Comment #14
larowlanAdded myself as supporter
Comment #15
bbralaThe linked page was wrong in the is.
Comment #16
bbralaComment #17
bbrala@xjm, not sure named arguments matter here much. Other pattern, other usage. Don't really see the direct relation.
Comment #18
aaronmchaleHappy to lend my support to this. I went back and forth a little, but I think there's value in aligning on PSR-12, as it will already be familiar to those new to Drupal and existing Drupal developers.
Proposal has received three supporters, change record exists, I believe this can now go to RTBC and committee stage (based on the process).
Comment #19
xjm@bbrala As @mstrelan documented, the rule can be configured either way and PHPCBF will fix things accordingly, so that's not a reason in either direction.
For me the most compelling point to not include the spaces is about the sheer magnitude of preference for the no-space version elsewhere on the internet.
Comment #20
dwwThe summary was still confusing what PSR-12 says with the two stated options. It seems that everything is aligning towards Option A. That's my understanding of the PSR-12 specs, and from my grep'ing, that's what core implementations are already doing (other than the inconsistency regarding spaces around the
=sign.Added myself as another supporter of option A, and made it explicit that the listed supporters are for option A. Also, fixed the date formatting on the supporters. https://xkcd.com/1179 😂
Moving to RTBC so that the standards committee can review. Even though most (all?) of the sponsors are on the committee, this is the formal process we're supposed to take. 😅
Onwards!
-Derek
Comment #21
bbralaSorry, I missed that, I dove into the rules. :)
Comment #22
catchNamed arguments are currently discouraged in core - i.e. we more or less tell people not to use them / be prepared for breakage if they do #3183180: [policy, no patch] Document named arguments BC policy.
Comment #23
jonathan1055 commentedFixed the Change Request link in IS checklist. The [# ] syntax did not create an active link.
Comment #24
larowlanThis was discussed at the coding standards committee meeting and it was agreed that we should proceed to the next step.
The consensus was for no spaces in alignment with PSR 12.
Tagging for announcement.
Comment #25
quietone commentedUpdated the remaining tasks in the Issue summary. The new process doesn't include the "Needs announcement for final discussion" but it is also not doing any harm so leaving that for now.
The issue for creating the post is #3403582: [2023-11-29] Draft blog
Comment #26
larowlanComment #27
dwwhttps://www.drupal.org/about/core/blog/coding-standards-proposals-for-fi... is now out, removing the tag for that.
This does impact core, so I can't immediately add "Needs documentation updates". But I'm not sure what to tag it with, instead. There is not yet a "Needs core committer approval". Is "Needs committer feedback" sufficient? Also explicitly tagging for release manager and framework manager review for now, but let's figure out exactly how we want this to work and update the project page accordingly.
Thanks,
-Derek
Comment #28
dwwI propose the new section should be added right after the section on PHP Code Tags. I already put that in the summary, but please comment if there are any objections.
Thanks,
-Derek
Comment #29
larowlanApproving from a FM POV
Comment #30
chi commentedI am against option A. It would add two extra lines to each PHP file. The option B (I call it PhpUnit style) seems to me more readable.
Also all code generated by `drush generate` use option B (with spaces around 1).
Comment #31
borisson_I think option A is the most widely used and the only one that will allow for php having another declare statement in the future in some kind of elegant way.
So I agree with the proposed resolution of accepting this into our standards.
Comment #32
kriboogh commentedI agree with @borisson_ on using Option A, putting declare on a separate line. Option B would create a mess if you would use multiple declare statements (in the future), which are part of PHP syntax. So besides a coding standard for just "declare(strict_types=1);" It would be better to look at the global picture and define a coding standard for using "declare" statements al together. (https://www.php.net/manual/en/control-structures.declare.php)
Comment #33
catchApproving for RM too.
Comment #34
larowlanThis was discussed at core committers meeting on Wed December 5th (UTC)
There were no objections
Completing steps 6 and 7.
Next step is the documentation edits and core issue for phpcs rule.
Comment #35
xjmWe're already working on a rule in the issues to add strict typing to tests, so that followup will not require any additional work beyond gradually expanding what parts of the codebase the rule applies to.
Thanks everyone!
Comment #36
quietone commentedI completed the documentation steps. I did change the change records, only to add a link to the documentation page.
According to #34 , this still needs a "core issue for phpcs rule".
Comment #37
mstrelan commentedThe "core issue for phpcs rule" is a bit tricky because we can't just enable it everywhere without breaking stuff. We have #3376057: [META] Add declare(strict_types=1) to all tests which is gradually adding it with various glob patterns in child issues, but perhaps need to add something to #3050720: [Meta] Implement strict typing in existing code for enabling it in runtime code.
Comment #38
quietone commented@mstrlen, thanks for the reminder.
I added #3407820: [Meta] Fix 'SlevomatCodingStandard.TypeHints.DeclareStrictTypes' coding standard which is postponed on #3050720: [Meta] Implement strict typing in existing code. That seems like the best step to take for now.
I think everything is completed here and this can be closed now.
Comment #39
pfrenssenReally great to see this. Just as a side note, in the past we've always aimed to rewrite any PSR-inspired rules to avoid strong all-caps wording such as "MUST" because it doesn't really fit in our coding standards style which is more friendly and conversational than the style used in PSR.
In our "friendly" style the proposed wording:
could be something like:
Comment #40
jonathan1055 commentedI think pfrenssen's style is an improvement and we should make the chnages suggested in #39. It has exactly the same technical outcome, but is written, as Pieter says, in a friendly style. I know this issue has already been through the final steps of approval, but if this "conversational" style is how Drupal standards should be written then we need to fix the recently updated page. Also we should check for this style of writing during the review process, so that we avoid late fixes like this next time.
The 'needs documentation updates' tag was already still there.
Comment #41
dww+1 to the "conversational" text in #39, and in us keeping an eye out for this style of writing for future issues.
I don't believe this needs another round of formal approval. The standard has already been approved and decided. We're only wordsmithing the docs on how to explain the standard. But I do think we need a few other folks to sign-off so it's not just a single person making edits. If a couple more of the active CS team members +1, let's make the edit.
Thanks!
-Derek
Comment #42
longwave+1 to the friendly text in #39.
Comment #43
quietone commented@pfrenssen, thank you providing the background and improving the text!
There is agreement here for changing the text to be friendly Drupal style and it does make this consistent with the rest of the coding standards. Therefor, I have made the change. And I updated the IS with the new paragraph.
This made me recall seeing #1795750: Revise coding standards to use IETF RFC 2119 standards so I added that as a related issue.
I think this can be set to 'Fixed' now.
Comment #44
pfrenssenThanks for updating the text!
This is done, I'm marking as fixed. Thanks to all involved for getting this in!
Comment #45
pfrenssenComment #46
jonathan1055 commentedI think pfrenssen accidentally submitted with stale form data. The issue summary updates from #43 have been reverted. I can fix it.
Comment #47
jonathan1055 commentedI have put back pfrenssen's unintended change from #44. This should match #43 now.
Comment #48
jonathan1055 commentedFixed missing 'if'
Also updated the Change Request with the same new text.
Comment #49
quietone commentedI have updated the remaining tasks and removed the last tag.
Thanks to @pfrenssen and @jonathan1055 for the prompt follow up.
Comment #50
jonathan1055 commentedAdded links to the Coder issue and Core issue.
Comment #52
jonathan1055 commentedThe Coder issue #3407995: Add sniff for declare(strict_types=1); has been committed and this sniff will be available in Coder 8.3.23 (or whatever the next release is).
The current Coder release is 8.3.22 from Oct 2023, which is the version being used in contrib testing on Gitlab pipelines using core 10.1 and 10.2, and also DrupalCI 10.2
Comment #53
xjmAmending attribution.