vscode-intelephense
vscode-intelephense copied to clipboard
Undefined constants will be reported in the Trait
a.php:
<?php
include __DIR__ . '/t.php';
class A{
const C = 123;
use T;
public function say(){
echo $this->xxx();
}
}
$a = new A;
$a->say();
t.php:
<?php
Trait T{
public function xxx(){
return self::C;
}
}
Intelephense will report that the self:: C constant on line 6 is undefined.
Your programming thought have a problem.
The trait that does not have a constant c
, an error is reasonable.
Use the following code to bypass the static analysis of Intelephense.
trait T
{
public function xxx()
{
if (!defined(static::class.'::C')) {
throw new \Exception('Please make sure the current object exists C constants');
}
return constant(static::class.'::C');
}
}
I'll look into turning this off inside traits considering traits cannot have constants
That's right, but because of the characteristics of PHP, we will inevitably use this situation.
I'll look into turning this off inside traits considering traits cannot have constants
Just to set the record straight: this is not entirely true - traits can have both properties and constants, problem is, they have to either NOT be defined on the classes using them (X)OR the classes using them must define them with the same values (which is obviously useless if the constant should differ between using classes).
So thank you for looking into this - but please look into both:
self::SOME_CONSTANT
self::$STATIC_PROPERTY
Any news on this ?
Prior to PHP 8.2 traits cannot have constants.
https://www.php.net/manual/en/language.oop5.traits.php#language.oop5.traits.constants
Also, even though PHP 8.2 allows constants, it is still very likely that the main class will have the constants that are shared by the trait. So this will still be a relevant issue.
And though in PHP 8.2 you could "copy" shared constants into the trait this goes against the DRY principle. It's not yet possible to have abstract constants.
So for earliet versions and typical usage even in later versions:
<?php
namespace app\validnamespace;
class SomeUsefulClass
{
use SomeUsefulTrait;
public const NOTFOUND = 'Not found';
...
}
<?php
namespace app\validnamespace;
trait SomeUsefulTrait
{
public function someUsefulMethod(): string
{
// this will _not_ pass intelephense
$var = static::NOTFOUND;
// this will _not_ pass intelephense
$var = self::NOTFOUND;
// this _will_ pass intelephense
// however, this is not practical since traits can be used in different classes
$var = SomeUsefulClass::NOTFOUND;
return $var;
}
}
Sorry for bringing this up again after a whole year but I wonder if anyone has found a solution to this?
Does PHP8.3 provide a better way so intelephense does not show this error?
Sorry for bringing this up again after a whole year but I wonder if anyone has found a solution to this?
Does PHP8.3 provide a better way so intelephense does not show this error?
In another similar problem they gave the answer, you need to use /** @disregard P1012 */