Skip to content

Squiz.Scope.StaticThisUsage false positive for Closure::bind closure inside static method #1357

@janedbal

Description

@janedbal

Describe the bug

Squiz.Scope.StaticThisUsage reports $this used inside a closure defined within a static method, even when that closure is explicitly bound to an object via Closure::bind() before being invoked.

At runtime, $this in the closure refers to the bound object ($newThis), so no runtime error occurs. The sniff appears to treat $this inside the nested closure as if it was used in the static method scope.

Code sample

  <?php declare(strict_types=1);

  final class Target
  {
      public $x = 2;
  }

  final class Repro
  {
      public static function run(): void
      {
          $target = new Target();

          \Closure::bind(
              function (): void {
                  $this->x = 1; // Usage of "$this" in static methods will cause runtime errors 
              },
              $target,
              Target::class,
          )();
      }
  }

Custom ruleset

  <?xml version="1.0"?>
  <ruleset name="Repro">
    <rule ref="Squiz.Scope.StaticThisUsage"/>
  </ruleset>

To reproduce

  1. Create test.php with the code sample above
  2. Create ruleset.xml with the custom ruleset above
  3. Run phpcs -s --standard=ruleset.xml test.php
  4. See error message displayed
  ----------------------------------------------------------------------
  FOUND 1 ERROR AFFECTING 1 LINE
  ----------------------------------------------------------------------
   16 | ERROR | Usage of "$this" in static methods will cause runtime errors (Squiz.Scope.StaticThisUsage.Found)
  ----------------------------------------------------------------------

Expected behavior

No error

Versions

Operating System Ubuntu 24.04.3 LTS
PHP version 8.4.15
PHP_CodeSniffer version 4.0.1
Standard Squiz
Install type Composer (local dev dependency)

Please confirm

  • I have searched the issue list and am not opening a duplicate issue.
  • I have read the Contribution Guidelines and this is not a support question.
  • I confirm that this bug is a bug in PHP_CodeSniffer and not in one of the external standards.
  • I have verified the issue still exists in the 4.x branch of PHP_CodeSniffer.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions