Problem/Motivation

As per the PHP documentation at https://www.php.net/manual/en/language.types.declarations.php#language.t...

By default, PHP will coerce values of the wrong type into the expected scalar type declaration if possible. For example, a function that is given an int for a parameter that expects a string will get a variable of type string.

It is possible to enable strict mode on a per-file basis. In strict mode, only a value corresponding exactly to the type declaration will be accepted, otherwise a TypeError will be thrown. The only exception to this rule is that an int value will pass a float type declaration.

This is already used in core across the CKEditor5 module, and also in an unrelated test (\Drupal\KernelTests\Core\ParamConverter\EntityConverterTest).

This issue proposes that it should be used for all new files added to core to improve type safety. This only really takes effect if #3154762: [policy, no patch] All new Drupal 10 code should use appropriate type hints wherever possible is accepted as well.

Steps to reproduce

Proposed resolution

Start using declare(strict_types=1); in all new code.
Documentation discussion in Coding Standards #3630579: Use declare(strict_types=1) in new code
Implementation at #3529705: Enforce strict types in new code

Remaining tasks

Decide whether this is a good idea.
Decide on a standard for adding declare(strict_types=1); to files.
Decide about documentation

User interface changes

API changes

Data model changes

Release notes snippet

Issue fork drupal-3250827

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

longwave created an issue. See original summary.

longwave’s picture

It might also be worth a test patch that changes this across all of core in one go, and seeing what breaks.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

chi’s picture

+1

Re #2. I guess many tests will be broken because of passing null values to string functions.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

bbrala’s picture

StatusFileSize
new2.99 MB

Sometimes you just want to create a fun patch hehe.

wim leers’s picture

+1 — existing code won't be affected if we start doing this for new files only for now.

bbrala’s picture

StatusFileSize
new2.99 MB

rebased, moving files confused it.

bbrala’s picture

StatusFileSize
new3.29 MB

Whitespace.

pfrenssen’s picture

+1

bbrala’s picture

+1 here also.

Bit unfrotunate cspell fails, locallty it doesnt :/

chi’s picture

Remaining tasks
Decide whether this is a good idea.
Decide on a standard for adding declare(strict_types=1); to files

So far no one objected, so the first part of the issue can be considered as completed. Right?

As of coding standard it actually consists of two independent rules.
1. Whether or not put spaces around =.
2. Where to place the declaration. On the same line as opening php tag or on a new line below.

chi’s picture

I like the way it is placed in PhpUnit.
https://github.com/sebastianbergmann/phpunit/blob/9.5/src/Exception.php#L1
Though I would prefer it having spaces around =.
Example:
<?php declare(strict_types = 1);

longwave’s picture

I would also prefer it on the opening line, it just wastes vertical space if we had it on line 3 (presumably line 2 is always blank). I have no preference over the spacing around the equals.

Interestingly this was also raised with Symfony some time ago and they turned down the idea: https://github.com/symfony/symfony/issues/28423

There is an argument that if we use PHPStan we should not need PHP's strict typing, as PHPStan can do all this and more.

bbrala’s picture

That issue is an interesting read. Would recommend.

sweetchuck’s picture

There is an argument that if we use PHPStan we should not need PHP's strict typing, as PHPStan can do all this and more.

Not exactly.
PHPStan is a static code analyzer.
declare(strict_types = 1) works on runtime.

In most of the cases PHPStan can give a warning, but not all the time.

sweetchuck’s picture

I know that, a lot of library (PHPUnit was mentioned before) puts the declare statement in the same line.
<?php declare(...);

I am not fun of that style.
strict_types is not the only thing that can be declared.
https://www.php.net/manual/en/control-structures.declare.php

Right now there is only three of them, maybe more to come in the future.
ticks and encoding won't be used in core and contrib any time soon,
but I would like to use a one statement per line style.

<?php

declare(strict_types = 1);
declare(encoding = 'ISO-8859-1');
?>
chi’s picture

Re #17. In reality, strict_types is the only declare statement in use.

andypost’s picture

This declares can go away in PHP 9.0 https://externals.io/message/112230#112233

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone made their first commit to this issue’s fork.

quietone’s picture

Came across this and I decided to create an MR to see the failures.

mstrelan’s picture

Good idea @quetone, I had thought about doing the same. I think fixing most of #3404246: [META] Fix strict type errors detected by phpstan would go a long way to getting this green. From memory there were no reported errors in core/lib/Drupal/Component, so maybe we could try limit to just that area first.

quietone’s picture

Seems I didn't do Components in the MR, so I have added that now.

quietone’s picture

Issue summary: View changes
Status: Active » Needs review

There is consensus here that this is a good idea and the standard for adding the declaration has also been agreed to. So, the policy has been agreed to.

Does this require documentation? If so, where?

FYI, the latest MR added strict types to Components and that is failing. The MR is information only and is not needed to resolve this policy issue.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

quietone’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: +no-needs-review-bot

As stated in #26, the MR is for information only.

There is one remaining question, where to document?

dww’s picture

I don't know of any docs specific to "how to write good code for Core" anywhere. 😅 Here are some of the spots I found while searching for a home:

https://www.drupal.org/community/contributor-guide/skill/php-codingprogr...
https://www.drupal.org/community/contributor-guide/task/create-a-merge-r...

Neither of those are particularly discoverable or exactly relevant.

Probably more likely to be found if we considered this a "Coding standard" not a core-only policy, but that's a bit of a slippery slope.

Maybe we want a new child page under https://www.drupal.org/about/core/policies for stuff like this. Something like "Core coding policies". Would also be somewhere to document the outcome of #3488476: [policy, no patch] Allow using @final when a class is not considered as an extension point vs. #3019332: Use final to define classes that are NOT extension points. We could write up #3154762: [policy, no patch] All new Drupal 10 code should use appropriate type hints wherever possible there, too.

mstrelan’s picture

While we're discussing if we want to do this, I figured we could do this fairly simply with a git diff in a gitlab ci job. Opened #3529705: Enforce strict types in new code with a proof of concept.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

nicxvan’s picture

Status: Needs review » Reviewed & tested by the community

I think the easiest thing is to just place it in the coding standards.

We already do this in practice, we should document this and make it a standard.

quietone’s picture

Created a follow up in Coding standards to discuss making this a requirement for all new code. #3630579: Use declare(strict_types=1) in new code

quietone’s picture

Issue summary: View changes
Status: Reviewed & tested by the community » Fixed

catch brought this up in committer channels where I and @mstrelan participated in the discussion. There is agreement to do this, and it is already being done in core. There is now a follow up in Coding Standards to discuss implementing in the standards, and there #3529705: Enforce strict types in new code to implement this for core.

Therefor, closing this policy issue as fixed.

Thanks everyone for helping to resolve this.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.