False positive PHP S2014 when using anonymous function (Closure) within static method

php:S2014 ("$this" should not be used in a static context) is issued when I use $this within a anonymous function which is used within a static method.

For example:

static function someStaticMethod()
{
    // Some code
    SomeClass::someStaticMethod(function() {
        return $this->getName(); // php:S2014 reported
    });
    // More code
}

This is possibly issued because someStaticMethod() is static, and thus the $this variable is believed to be unavailable. This message would normally be correct.

However, in this case, the $this variable appears within an anonymous function, which has the runtime type of a Closure class. $this bound when the closure is executed, rendering $this valid. This has been implemented since PHP 5.4.

The report can be reproduced with the following code.

<?php

class SonarTest {
    public static function phpS2014() {
        $person = new Person(7, 'Jack');
        return Utils::map($person, function() { // Closure
            return $this->name; // $this refers to a Person object, and
                                // not to anything from the SonarTest
                                // class
        });
    }
}

class Utils {
    public static function map(Person $p, \Closure $mappingFunction) {
        return $mappingFunction->call($p);
        // The passed Person object is the $newThis. That means that if
        // the given closure uses the $this variable, it refers to the
        // Person object passed to this map() function.
    }
}

class Person {
    public $id;
    public $name;
    public function __construct(int $id, string $name) {
        $this->id = $id;
        $this->name = $name;
    }
}

var_dump(SonarTest::phpS2014());

The above code will print

string(4) "Jack" 

I’m running on PHP 7.1.
I’m using SonarCloud.

You’re right, it’s a false positive.
I created a ticket to track it: SONARPHP-961

Thanks a lot for the very detailed feedback!

You’re welcome! I’m glad it helped.