Skip to content

Updated PHPStan to 2.2.6 and fixed the new unnecessary null-coalesce errors - #1159

Merged
fballiano merged 1 commit into
mainfrom
fix/phpstan-2.2.6-null-coalesce
Jul 27, 2026
Merged

Updated PHPStan to 2.2.6 and fixed the new unnecessary null-coalesce errors#1159
fballiano merged 1 commit into
mainfrom
fix/phpstan-2.2.6-null-coalesce

Conversation

@fballiano

@fballiano fballiano commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Updating PHPStan to 2.2.6 broke composer lint:phpstan in two ways.

The fatal

PHPStan 2.2.6 added getPureUnlessCallableIsImpureParameters() to ExtendedMethodReflection. maho-phpstan-plugin's PublicMethodReflection did not implement it, so every run died as soon as that class was autoloaded — which happens via BindThisScopeResolverExtension, i.e. any phtml template or install script calling a protected method on $this:

Child process error (exit code 255): PHP Fatal error: Class Maho\PHPStanPlugin\Reflection\PublicMethodReflection
contains 1 abstract method and must therefore be declared abstract or implement the remaining method
(PHPStan\Reflection\ExtendedMethodReflection::getPureUnlessCallableIsImpureParameters)

Fixed upstream in MahoCommerce/maho-phpstan-plugin#28 and released as v4.3.0, which this lockfile picks up.

The new check

2.2.6 also adds nullCoalesce.unnecessary, which flags ?? null on an expression that is always set. Five call sites tripped it:

  • Mage_Admin_Model_Session::login() — initialize $user = null before the try and return it directly. PHPStan considers the variable always set after the block, but only because it treats getModel() as a non-throw point; Mage::throwException() from an invalid model would leave $user undefined at runtime. Initializing up front makes the guard explicit instead of inferred, so the behaviour does not depend on that inference being right.
  • Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Datetime, Mage_Payment_Model_Restriction_Rule_Condition_Product::getRule(), Mage_Sales_Helper_Guest::_loadOrderByCookie() — drop a genuine no-op ?? null: explode() always yields index 0, and an untyped $_rule property already defaults to null. The ?? null on $cookieData[1] stays, since that index really can be missing.
  • Maho_Ai_Helper_Data::submitTask() — default a missing message role to '' rather than null. PHPStan trusts the array{role: string, ...} docblock, but the parameter is a plain array at runtime, so the fallback has to stay: dropping it would let a payload without role silently skip the prompt-injection check, which is exactly the bypass that guard exists to close.

Verification

composer lint is clean: PHPStan 5261/5261 with no errors, php-cs-fixer 0 of 4769 fixable, Rector OK.

Note

Developed with the help of AI.
As part of our commitment to GenAI transparency, we flag pull requests produced with AI assistance alongside human work. As with every change in Maho, a maintainer reviews and validates it before merge, we never merge purely AI-generated changes. See the GenAI transparency section for details.

PHPStan 2.2.6 adds the nullCoalesce.unnecessary check, which flags "?? null"
on an expression that is always set. Five call sites tripped it:

- Mage_Admin_Model_Session::login() initializes $user to null before the try
  block instead of relying on "?? null" after it, keeping the guard against
  a throw before the assignment explicit rather than inferred.
- The datetime column renderer, the payment restriction condition and
  Mage_Sales_Helper_Guest drop a no-op "?? null": explode() always yields
  index 0 and $_rule defaults to null. The guard on $cookieData[1] stays.
- Maho_Ai_Helper_Data::submitTask() defaults a missing message role to ''
  rather than null. The parameter is a plain array at runtime, so the
  fallback has to stay or a malformed payload would silently skip the
  prompt-injection check.

Also picks up maho-phpstan-plugin v4.3.0, which implements the method
ExtendedMethodReflection gained in PHPStan 2.2.6; without it every analysis
run fatals.
@fballiano
fballiano merged commit b743ba9 into main Jul 27, 2026
27 checks passed
@fballiano
fballiano deleted the fix/phpstan-2.2.6-null-coalesce branch July 27, 2026 08:39
@fballiano fballiano added this to the 26.9.0 milestone Jul 27, 2026
@fballiano fballiano added the ✨ ai-assisted Developed with the help of AI label Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ ai-assisted Developed with the help of AI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant