1

After swapping some of my non-static vars to static vars, I ended up with some expressions similar to the one here. This throws a syntax error, but I can't figure out why.

Class Bar  {
    public static $name = "bar";
}

Class Foo {
    public function getParent(){
        $this->parentClass = new Bar();
        return $this;
    }
}

$foo = (new Foo())->getParent();
echo ($foo->parentClass)::$name; //this line is throwing a syntax error

//output:
PHP Parse error:  syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)

If I assign the object to a variable, then it doesn't throw the error:

$class = $foo->parentClass;
echo $class::$name;
//outputs "bar";

I could imagine possibly running into some unintended order of operations issues, but can't figure out why it's a syntax error, and I'm wondering if there is a way to do this in a single one line expression. (Since this issue was caused by a mass find/replace, it would be nice to keep it in one line)

Gisheri
  • 1,645
  • 2
  • 18
  • 27
  • Which php version? I got no syntax error with php 7.2. – steven Sep 06 '18 at 20:26
  • I'm using PHP 5.6, I've noticed that it works on PHP >7, but unfortunately our system is not on that yet – Gisheri Sep 06 '18 at 20:31
  • 1
    One way would be to create a method in `Bar` that returns the static variable instead of trying to access it directly. Something like this: https://3v4l.org/lKkZZ. Then you could even do it in one single line (just keep chaining after the instantiation) – M. Eriksson Sep 06 '18 at 20:47

2 Answers2

2

In fact this is only possible as of PHP 7.0. The changed behaviour is not well documentated. I think it's more of a bugfix than a new feature.

However the closest solution to a "one-liner" (working in 5.6) seems to be this one:

$bar = (new Foo())->getParent()->parentClass;
echo $bar::$name; 

Maybe that is not what you tried to achieve. The important thing is that the static class is only accessable by putting it into a single variable first.

I recommend a migration to PHP7 urgently.

steven
  • 4,868
  • 2
  • 28
  • 58
2

It's kinda ugly, but if you really need a one-liner:

echo get_class_vars(get_class($foo->parentClass))["name"];

Inspired by this answer

DEMO

Patrick Q
  • 6,373
  • 2
  • 25
  • 34
  • 1
    You're correct... it does the job _and_ is ugly :-p – M. Eriksson Sep 06 '18 at 21:03
  • 1
    @MagnusEriksson Yeah, I'd go the route of assigning to a variable first myself, but I'll leave that choice up to the OP. – Patrick Q Sep 06 '18 at 21:05
  • Y, that would probably perform a bit better as well. I haven't done any tests but I would guess that `get_class_vars()` would preform a bit worse. – M. Eriksson Sep 06 '18 at 21:09
  • 1
    And all other developers reading your code maybe want to hurt you. – steven Sep 06 '18 at 21:11
  • @steven - So it's ugly, bad for performance _and_ your well-being? That's a metric worth taking into account. However, it does give a solution to the OP's problem. :-) – M. Eriksson Sep 06 '18 at 21:12
  • 1
    Hey, don't shoot the messenger :-) – Patrick Q Sep 06 '18 at 21:16
  • Well, @PatrickQ, that is quite the one liner. haha. Thanks! I guess that's all we can do for now, until I get upgraded – Gisheri Sep 06 '18 at 21:24
  • @Gisheri - I would actually recommend that you store it in a variable instead. That would make it way more readable. In a few months/years when you or some other developer need to do some changes in that code, you will thank me. I also doubt that any IDE would properly handle that in regards to auto complete and such. – M. Eriksson Sep 06 '18 at 21:26
  • 1
    @MagnusEriksson, Thanks I did take the 2 line route. – Gisheri Sep 06 '18 at 22:51