#5594 - Consider declare(strict_types=1) in codebase (rolling)
| Identifier | #5594 |
|---|---|
| Issue type | Feature request or suggestion |
| Title | Consider declare(strict_types=1) in codebase (rolling) |
| Status | Completed |
| Tags |
Roadmap: Over the horizon (custom) Roadmap: v11 partial implementation (custom) Type: Standards compliance (custom) |
| Handling member | PDStig |
| Addon | core |
| Description | Since it is not possible at this time to maintain the special ocp PHP (much less compile it on certain machines), we should consider adding declare(strict_types=1) at the top of every PHP file in the v11 codebase.
Be cautious about its implementation; it must also be explicitly included in eval code (unless we're pulling code from a file that already has it declared). |
| Steps to reproduce | |
| Related to | |
| Funded? | No |
The system will post a comment when this issue is modified (e.g., status changes). To be notified of this, click "Enable comment notifications".
Comments
if (@strlen(cms_file_get_contents_safe($_SERVER['SCRIPT_NAME'], FILE_READ_LOCK)) > 4500) {
Even though strlen is suppressed, this still throws a TypeError when cms_file_get_contents_safe evaluates to false. Type checking must happen before the strlen call. There are many cases of things like this throughout the code.
So a better approach is to implement this gradually.
If we can no longer maintain/deploy ocProducts PHP, I think it makes more sense to reassess what we were trying to achieve with it and how important that is given new realities.
You are right. TypeErrors are fatal. They can, however, be handled, at least I assume they can because Composr's critical error handling handled them when I gave it a try.
PHP's implementation of strict_types is not very intuitive. It's runtime-level. It has to be defined on every file you want it to run. It must also be defined in eval code if you want eval code to be strict type checked. It must be defined top-level. You can't dynamically turn it off/on. Etc. This means we can't simply implement it just for DEV_MODE.
"If we can no longer maintain/deploy ocProducts PHP, I think it makes more sense to reassess what we were trying to achieve with it and how important that is given new realities."
I still think XSS checking and type strict checking is very important and should still be strong considerations. XSS attacks are on the rise, I believe, in general (especially with WordPress). But you're right. We can't maintain / deploy it anymore.
The PHP community had an extremely rough time agreeing on strict typing. The Zend developers, who were stewarding the project at the time, were vehemently against it at all. I would have preferred an ini setting, but the issue there is that it forces all third party code to support strict types too - which many PHP core devs could never get behind as it was such a fundamental changing in the expectations for PHP developers and compatiblity.
The XSS issue is almost entirely mitigated by CSP, which did not exist when I implemented the XSS functionality for ocProducts PHP.
Strict type checking should mainly be done at the development / IDE level, not runtime, as runtime checks make for very fragile code (since Type Errors are fatal).
We have CQC which helps with this. And some IDEs can check for it as well, although ultimately only CQC is able to type-check Composr types. I think that's good enough though couple with PHP's type support as of 7 and 8.
I think for now it would be fine to not force Composr devs to run ocProducts PHP, would be good to add publicly-supported strictness in dynamically, but also not erase the possibility of using ocProducts PHP as a bridge out of PHP in the future if we consider it appropriate.
I modified the Composr system to use bootstrap.php instead of global.php as the initial entry point. bootstrap.php contains the bare minimal code necessary to load up global.php or minikernel.php with strict_types if in DEV_MODE. All entry-point scripts have been modified to use bootstrap.php instead of global.php and then call up global from there.
This ensures we can get strict type checks on global / minikernel as well.
So far so good; the code is working as expected, and I'm getting a lot of strict type errors that need fixed (e.g. passing in false when we shouldn't, floats where ints should go, and so on).
This issue will take a while to complete as I essentially need to spider through the sitemap to find any type errors we missed all these months not using ocp PHP. But that's fine; the good news is we have strict type checking again despite not having ocp PHP.
There may still be some bugs because essentially, I had to also incorporate what was once planned for v12 (#5473) in this issue (otherwise stack traces in dev mode are completely borked). I will also be making a post there because I decided not to implement it as the original issue indicated.