Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Symbol declared but not used for members read by variable name #3167

Open
sfsaccone opened this issue Jan 23, 2025 · 6 comments
Open

Symbol declared but not used for members read by variable name #3167

sfsaccone opened this issue Jan 23, 2025 · 6 comments
Labels

Comments

@sfsaccone
Copy link

Describe the bug

A "symbol is declared but not used" error/warning is given for class members that are accessed in the code by using a variable for the member name where the variable is from a hard-coded array. I often do this in __get() methods to make private members readable. So, I get lots of these errors/warnings. Normally, these are very useful for cleaning up code. It would be great if they could be suppressed in this situation.

To Reproduce

<?php

class MyClass {
    private string $readOnlyMember;
    private string $otherReadOnlyMember;
    private string $totallyPrivateMember;

    public function __construct() {
        $this->readOnlyMember = 'a'; // Symbol '$readOnlyMember' is declared but not used
        $this->otherReadOnlyMember = 'b'; // Symbol '$otherReadOnlyMember' is declared but not used
        $this->totallyPrivateMember = 'c';
    }

    public function privateData() : string {
        return $this->totallyPrivateMember;
    }

    public function __get($name): mixed
    {
        $allowed = [
            'myReadOnlyMember',
            'otherReadOnlyMember'
        ];
        if (in_array($name, $allowed)) {
            return $this->$name;
        }
        throw new \Exception("Attempt to read private or unknown member $name");
    }
}

Expected behavior

No error messages or warnings.

Screenshots

The error messages/warnings shown in the inline comments.

Platform and version

  • Windows 11
  • Visual Studio Code 1.96.4
  • Intelephense 1.12.6
@sfsaccone
Copy link
Author

sfsaccone commented Jan 23, 2025

Oh, I see PHP 8.1 introduced the readonly keyword for this. There are no errors/warnings for the code below. Yay.

class MyClass {
    public readonly string $readOnlyMember;
    public readonly string $otherReadOnlyMember;
    private string $totallyPrivateMember;

    public function __construct() {
        $this->readOnlyMember = 'a';
        $this->otherReadOnlyMember = 'b';
        $this->totallyPrivateMember = 'c';
    }

    public function privateData() : string {
        return $this->totallyPrivateMember;
    }
}

@bmewburn
Copy link
Owner

You can suppress this on a case by case basis with an annotation above the statement /** @disregard P1003 */ . I'll close this as it seems like an edge case with a workaround or alternate way of implementing.

@sfsaccone
Copy link
Author

Makes sense, thanks!

@sfsaccone
Copy link
Author

My bad. The readonly keyword does not provide the same functionality as __get(). With the second class definition above using readonly, I can only assign readOnlyMember in the constructor. That's not what I want. Therefore, I'm back to the first class example using __get(). I tried @disregard but I still get the errors:

<?php

class MyClass {

    /** @disregard P1003 */
    private string $readOnlyMember; // Symbol '$readOnlyMember' is declared but not used
...

It would great if you could add a new feature that suppresses P1003 for a member declaration when the class has a __get() method returns a value rather than throws an exception when that member is given as the argument to the __get() method. If the @disregard would work that would be ok, but not ideal.

Sorry for the confusion.

@bmewburn bmewburn reopened this Jan 24, 2025
@sfsaccone
Copy link
Author

Alternatively, I could write the __get() like this (a Codeium suggestion):

public function __get($name): mixed
    {
        $allowed = [
            'readOnlyMember' => $this->readOnlyMember,
            'otherReadOnlyMember' => $this->otherReadOnlyMember,
        ];

        if (isset($allowed[$name])) {
            return $allowed[$name];
        }

        throw new \Exception("Attempt to read private or unknown member $name");
    }

It's just as readable as in the first block above and there are no P1003 errors. Works for me.

@bmewburn
Copy link
Owner

That looks like a good solution. I'll keep this ticket open to fix the @disregard.

@bmewburn bmewburn added the bug label Jan 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants