0

I'm registering a custom Carbon macro in my Laravel's AppServiceProvider

Carbon::macro('itFormat', static function () { return ucwords(self::this()->translatedFormat('l d/m/Y')); }); 

But PHPStan insists that, in this code, self is referred to the AppServiceProvider itself

Call to an undefined static method App\Providers\AppServiceProvider::this() 

An easy solution (found here) should be to use a non-static function and a PHPDoc annotation targetting $this, such as

Carbon::macro('itFormat', function () { /** @var Carbon $this */ return ucwords($this->translatedFormat('l d/m/Y')); }); 

But this is in contrast to the Carbon's documentation itself, saying:

Note that the closure is preceded by static and uses self::this() (available since version 2.25.0) instead of $this. This is the standard way to create Carbon macros, and this also applies to macros on other classes

Which may be the proper PHPDoc annotation for the "self in static function" way?

3
  • 1
    Sounds like that should be an issue reported to PHPStan? Commented Jan 26 at 0:41
  • I'm pretty sure this can be solved with a PHPDoc annotation, but probably I'm not able to query Google in the right way about this topic... Commented Jan 26 at 1:23
  • @madbob: Hmm, I do not think it can be solved with a PHPDoc annotation because for self::this() Phpstan resolves self already and that causes the first error. But for self no PHPDoc annotation exists IIRC. Would be delighted to learn something new, however even if it would, it would require that the annotation would make self $this and :: '->' like so that Phpstans flawed assumption about the binding of self can be circumvented. As outlined in my answer, I'd suggest you report this upstream (also what Paul T wrote). Commented Jan 26 at 14:06

1 Answer 1

0

[What is the] PHPDoc annotation for the "self in static function" way?

There is no such thing AFAIK, but you can use a different annotation:

Carbon::macro('itFormat', static function () { // @phpstan-ignore-next-line return ucwords(self::this()->translatedFormat('l d/m/Y')); }); 

Then create a bug report similar to Closure defined in static method errors on $this, even if rebound later. #9765 (github.com).

Alternatively define your macro to mix-in a trait, it can simplify to $this that has PHPDoc annotations (source (nesbot.com)):

Since Carbon 2.23.0, it's also possible to shorten the mixin syntax using traits:

trait BeerDayCarbonTrait { public function nextBeerDay() { return $this->modify('next wednesday'); } public function previousBeerDay() { return $this->modify('previous wednesday'); } } Carbon::mixin(BeerDayCarbonTrait::class); 
Sign up to request clarification or add additional context in comments.

2 Comments

Better to ignore specific error: // @phpstan-ignore staticMethod.notFound phpstan.org/error-identifiers/staticMethod.notFound
@cetver yes, normally I would say so as well (or perhaps create a baseline), but in this case it is a flaw in Phpstan because the analysis that self belongs to App\Providers\AppServiceProvider is wrong, the closure can be re-bound. See the similar report for $this in a closure.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.