8

I'm getting this strange error. You'll say: "Why strange? You just don't have such property". No. Problem is there are property.

There I'm getting an error.

// PHP Notice:  Undefined property: stdClass::$roles in
$canWrite = $this->session->isLoggedIn() ? $this->page->canWrite($this->session->user->roles) : false;

This is the class.

class User {
    protected $roles;

    function getRoles() {
        if (!$this->roles)
        {
            // Get them!
        }

        return $this->roles;
    }
}

So this method is called when I'm trying to access property in this line. Everything works fine but I don't want to increase my error log. What's happening?

UPD1

$this->user->session is an User object

function getUser() {
    if (!$this->user) {
        $u = new User();
                    // Logic
        $this->user = $u;
    }
    return $this->user;
}
User Object
(
    [roleId:protected] => 1
    [roles:protected] => Array
        (
            [root] => Role Object
                (
                    [id:protected] => 1
                    [hrefname:protected] => root
                )

        )
)

UPD2

All properties are accessed via magic __get()

public function __get($var) {
    if ($this->__isset($var)) {
        $method = 'get'.ucfirst($var);
        if (method_exists($this, $method)) {
            return $this->$method();
        } else {
            return $this->$var;
        }
    }
    throw new Exception("Unrecognized attribute '$name'");
}

UPD3

var_dump($this->session->user)

object(User)#370 (30) {
  ["roles":protected]=>
  array(1) {
    ["root"]=>
    object(Role)#372 (2) {
      ["id":protected]=>
      string(1) "1"
      ["hrefname":protected]=>
      string(4) "root"
    }
  }
}

Explanation

In one place I accidentally wrote $this->session->user->id = $user->id in place where $this->session->user is not created yet. So null->id actually was (new stdClass())->id. Well, thank you, PHP.

efpies
  • 3,625
  • 6
  • 34
  • 45
  • 2
    Your error message indicates that `$this->session->user` is _NOT_ a `User` object though. It is a generic `stdClass` object that doesn't have a `$roles` property. Post the code where the `$this->session->user` is set... – Michael Berkowski Oct 07 '12 at 19:29
  • 2
    How is `$this->session->user` created? PHP is recognizing it as a `stdClass` object, not a `User` object. – Cat Oct 07 '12 at 19:29
  • 1
    Secondly, `User::$roles` is `protected`, so you would not be able to access it publicly via `$something->user->roles`. That would be the point of the `User::getRoles()` method. – Michael Berkowski Oct 07 '12 at 19:31
  • @MichaelBerkowski Have look at upd1 and upd2. – efpies Oct 07 '12 at 19:45
  • @Eric Have look at upd1 and upd2. – efpies Oct 07 '12 at 19:46
  • That *is not* the class. Your question is already wrong in the very beginning. Then *"All properties are accessed via magic __get()"* that means you have got magic access here, we *all* know that this is hard to debug (and we warn our kids about that early), so you have decided to use that which is fine, however, do the debugging properly. Fire up your step-debugger, step through your code and inspect when the error comes. – hakre Oct 07 '12 at 20:01
  • 2
    @efpies: Install yourself XDebug, use a compatible Editor/IDE, run to that line and *look inside on your own*. On SO we can only do statical code-analysis with the little chunks of code you provide peu-a-peu as if you've got a secret to hide (and your utterly bad, ranting, non-constructive descriptions) nothing more and nothing less. – hakre Oct 07 '12 at 20:05
  • @hakre Ok, it really wasn't `User` class and with XDebug I've determined that in one case it writed one property to null before `User` is created so that's the place where `stdClass` is created. – efpies Oct 07 '12 at 21:37
  • I just had similar problem, turned out it was caused by `unset`. I was "unseting" properties instead of clearing them ... – Buksy Mar 21 '16 at 09:57

2 Answers2

5

Since it says the undefined property is in stdClass, this means that the object in question is not actually the User class that you think it is.

This would generally imply that something went wrong with the creation of the object. So therefore the actual bug in your code that is leading to this error is earlier in the program than the line of code you've given us.

Look for where the object is being created. That's where the problem is likely to be.

I can't be of much more help than that without seeing the rest of the code, but hope that helps.

[EDIT]

The object that is throwing the error is $this->session->user (this is the one you're trying to access the ->roles property for).

As much as you want to say it's definitely a User object, the fact is that PHP says otherwise. Do a var_dump($this->session->user) immediately before the error and you should be able to see what I'm saying.

As for how come it isn't what you expect, I still can't give any better answer. Using a debugger like xDebug to trace through the program one line at a time might help.

Spudley
  • 166,037
  • 39
  • 233
  • 307
  • @efpies - re UPD1 You say it's a `User` object, but PHP says it's a `stdClass` that is throwing the error. Somewhere along the line, you're not accessing the object you think you are. See my edit. – Spudley Oct 07 '12 at 19:51
  • In upd3 I've posted `var_dump`. It says that it an `User` object. – efpies Oct 07 '12 at 19:56
  • @efpies - and that's coming from the line immediately before the line with the error? In that case, I would suggest checking the `isLoggedIn()` function; it might be doing something unexpected to the user object. Maybe turn your ternary condition into a standard `if else` block and add a `var_dump` inside it. – Spudley Oct 07 '12 at 20:07
  • No, `isLoggedIn()` is only checking cookies. So `var_dump` after `isLoggedIn()` is printing the same info. I'm trying to use debugger now... – efpies Oct 07 '12 at 20:14
2

The obvious explanation would be that the property is defined, but is protected. This means that it is only accessable to this and extended classes.

However, the error message does suggest some other error. The class is a User class, but the error suggest it is a property of stdClass.

JvdBerg
  • 21,777
  • 8
  • 38
  • 55
  • All properties are accessed via magic `__get()` method. So even if it is `protected`, it works. And method is called when I'm accessing it. – efpies Oct 07 '12 at 19:40
  • -1: You edited your question after I gave my answer. But my answer still stands – JvdBerg Oct 07 '12 at 19:45
  • 1
    So what? You posted your answer while I had updating my question for other comments. So I notified you about this. What's the problem? All properties in my code is `protected` but there are no other errors. And `get_class($this->session->user)` returns `User`. – efpies Oct 07 '12 at 19:52