# Resolution of static variables in the function scope not using forwarded calling information?

- Thread: https://externals.io/message/85977
- Original archive: https://news-web.php.net/php.internals/85977
- Started by php@lvl.fastmail.com on 2015-04-27T21:12:17+00:00
- Messages: 3
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #85977 — php@lvl.fastmail.com — 2015-04-27T21:12:17+00:00

URL: https://externals.io/message/85977#85977

Hello all,

I ran into some very strange behavior while experimenting with static
function variables. It looks like a bug to me, but I couldn't find any
previous reports or discussions about the subject, so I wanted to gather
your input before submitting it as such.

Static variables in the function scope appear to be resolved using late
static binding: the content of the variable in that function is shared
amongst all instances of a class, though each subclass gets its own
separate variable space.

This is pretty logical and works fine. As an example, let's create
classes Base => Animal => {Cat,Dog}. Base has a function that describes
the class, and caches the result in a static function variable
$description. Calling describe() on the three different classes
correctly gives us three different results: http://3v4l.org/Qldve

However, once you override the describe function in Animal and call
parent::describe() from within, it looks like all calling information is
lost: the resolution of $description in Base's function scope now always
points to Animal's variable space. For example: http://3v4l.org/qWrvf

Overriding the function in one of the childmost classes like Dog gives
an even stranger result: $description is now correctly a separate value
in Cat vs Dog, but calling Animal::describe() now uses the value left by
its child class Cat?! See: http://3v4l.org/61P72

Any thoughts?

Thanks,
Laszlo

---

## #85982 — Levi Morrison — 2015-04-28T04:14:46+00:00

URL: https://externals.io/message/85977#85982 · In reply to: #85977

> Hello all,
>
> I ran into some very strange behavior while experimenting with static
> function variables. It looks like a bug to me, but I couldn't find any
> previous reports or discussions about the subject, so I wanted to gather
> your input before submitting it as such.
>
> Static variables in the function scope appear to be resolved using late
> static binding: the content of the variable in that function is shared
> amongst all instances of a class, though each subclass gets its own
> separate variable space.
>
> This is pretty logical and works fine. As an example, let's create
> classes Base => Animal => {Cat,Dog}. Base has a function that describes
> the class, and caches the result in a static function variable
> $description. Calling describe() on the three different classes
> correctly gives us three different results: http://3v4l.org/Qldve
>
> However, once you override the describe function in Animal and call
> parent::describe() from within, it looks like all calling information is
> lost: the resolution of $description in Base's function scope now always
> points to Animal's variable space. For example: http://3v4l.org/qWrvf
>
> Overriding the function in one of the childmost classes like Dog gives
> an even stranger result: $description is now correctly a separate value
> in Cat vs Dog, but calling Animal::describe() now uses the value left by
> its child class Cat?! See: http://3v4l.org/61P72

This last is the only one that seems to be a bug to me; I think if you
step through the others you'll see why they are fine. Maybe the last
isn't a bug either; I'll try to think about this more but it does
appear to be a bug.

> Any thoughts?
>
> Thanks,
> Laszlo

---

## #85984 — php@lvl.fastmail.com — 2015-04-28T07:35:56+00:00

URL: https://externals.io/message/85977#85984 · In reply to: #85982

> This last is the only one that seems to be a bug to me; I think if you
> step through the others you'll see why they are fine. Maybe the last
> isn't a bug either; I'll try to think about this more but it does
> appear to be a bug.

FWIW, an example that makes the second situation slightly more clear:
http://3v4l.org/CcrL8

I would have expected the static function variable and
 `get_called_class()` to always refer to the same class/variable space,
parent:: or not.

Oddly enough, referring to static class variables with "static::" never
seems to use late static binding at all? http://3v4l.org/G9nCE

Thanks,
Laszlo
