vscode-intelephense icon indicating copy to clipboard operation
vscode-intelephense copied to clipboard

Undefined constants will be reported in the Trait

Open huye opened this issue 2 years ago • 8 comments

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.

huye avatar Nov 26 '21 04:11 huye

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');
    }
}

tianyiw2013 avatar Nov 29 '21 11:11 tianyiw2013

I'll look into turning this off inside traits considering traits cannot have constants

bmewburn avatar Dec 14 '21 09:12 bmewburn

That's right, but because of the characteristics of PHP, we will inevitably use this situation.

huye avatar Dec 15 '21 03:12 huye

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

realjjaveweb avatar Sep 13 '22 13:09 realjjaveweb

Any news on this ?

Kwaadpepper avatar Oct 19 '22 07:10 Kwaadpepper

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;
    }
}

nd4c avatar Apr 15 '23 16:04 nd4c

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?

Sotiris-k avatar May 07 '24 09:05 Sotiris-k

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 */

niriter avatar May 19 '24 17:05 niriter