rfc:null_coercion_consistency

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
rfc:null_coercion_consistency [2022/05/11 11:45] – Move the open issue "Scalar Types" to it's own section craigfrancisrfc:null_coercion_consistency [2022/10/16 07:37] – Note that Rector can now "help" with this problem. craigfrancis
Line 106: Line 106:
 </code> </code>
  
-Arrays, Resources, and Objects (without //__toString()//) cannot be coerced (for fairly obvious reasons).+Arrays, Resources, and Objects (without toString) cannot be coerced (for fairly obvious reasons).
  
 String/Int/Float/Bool can be coerced. String/Int/Float/Bool can be coerced.
Line 210: Line 210:
 It is possible to use very strict Static Analysis, to follow every variable from source to sink (to check if a variable could be NULL), but most developers are not in a position to do this (i.e. not using static analysis, or not at a high enough level, or they are using a baseline to ignore). It is possible to use very strict Static Analysis, to follow every variable from source to sink (to check if a variable could be NULL), but most developers are not in a position to do this (i.e. not using static analysis, or not at a high enough level, or they are using a baseline to ignore).
  
-In the last JetBrains developer survey (with 67% regularly using Laravel), **only 33% used Static Analysis** ([[https://www.jetbrains.com/lp/devecosystem-2021/php/#PHP_do-you-use-static-analysis|source]]); where it's fair to many still would still not be identify these possible NULL values (too low level, and/or using a baseline).+In the last JetBrains developer survey (with 67% regularly using Laravel), **only 33% used Static Analysis** ([[https://www.jetbrains.com/lp/devecosystem-2021/php/#PHP_do-you-use-static-analysis|source]]); where it's fair to say many of these developers would //still// not identify these possible NULL values (too low level, and/or using a baseline).
  
 As an example, take this simple script: As an example, take this simple script:
Line 222: Line 222:
 </code> </code>
  
-Even that is considered fine today by the relevant tools: +This is considered fine by these tools:
- +
-<code cli> +
-composer require --dev rector/rector +
-./vendor/bin/rector init +
-./vendor/bin/rector process ./src/ +
-[OK] Rector is done! +
-</code>+
  
 <code cli> <code cli>
Line 294: Line 287:
 </code> </code>
 Note: Psalm can detect this at [[https://psalm.dev/docs/running_psalm/error_levels/|levels 1, 2, and 3]] (don't use a baseline). Note: Psalm can detect this at [[https://psalm.dev/docs/running_psalm/error_levels/|levels 1, 2, and 3]] (don't use a baseline).
 +
 +==== One Solution ====
 +
 +Since [[https://github.com/rectorphp/rector-src/pull/2543|21st June 2022]], Rector can modify 362 function arguments via //NullToStrictStringFuncCallArgRector//:
 +
 +<code cli>
 +mkdir -p rector/src;
 +
 +cd rector/;
 +
 +composer require --dev rector/rector;
 +
 +echo '<?= htmlspecialchars($var) ?>' > src/index.php;
 +
 +echo '<?php
 +
 +use Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector;
 +use Rector\Config\RectorConfig;
 +
 +return static function (RectorConfig $rectorConfig): void {
 +    $rectorConfig->paths([__DIR__ . "/src"]);
 +    $rectorConfig->rule(NullToStrictStringFuncCallArgRector::class);
 +};
 +' > rector.php;
 +
 +./vendor/bin/rector process;
 +</code>
 +
 +This will litter the code with the use of //(string)// type casting, e.g.
 +
 +<code diff>
 +-<?= htmlspecialchars($var) ?>
 ++<?= htmlspecialchars((string) $var) ?>
 +</code>
 +
 +For a typical project (which won't be using strict_types), expect thousands of changes to be made; and note how this does not improve code quality.
  
 ==== Temporary Solutions ==== ==== Temporary Solutions ====
Line 329: Line 358:
 </code> </code>
  
-As noted above - PHPCompatibility, CodeSniffer, Rector, etc are unable to find or update these cases.+As noted above - Rector can add //(string)// type casting automaticallybut I have no idea how this improves code quality.
  
 ===== Proposal ===== ===== Proposal =====
Line 392: Line 421:
   - //$method// in [[https://php.net/method_exists|method_exists()]]   - //$method// in [[https://php.net/method_exists|method_exists()]]
   - //$json// in [[https://php.net/json_decode|json_decode()]]   - //$json// in [[https://php.net/json_decode|json_decode()]]
 +
 +It might be appropriate for coercion and explicit casting/converting to work in the same way, even if they were to become stricter in the values they accept; e.g. //intval("")// and //((int) "")// currently return int(0), whereas //(5 + "")// results in a TypeError.
  
 ===== Voting ===== ===== Voting =====
rfc/null_coercion_consistency.txt · Last modified: 2023/10/18 11:57 by craigfrancis