Syntax error when trying to access static method on object saved in property!

Asked

Viewed 126 times

3

In another of my tests, I noticed that in PHP there is a problem when trying to access the static method of a class, when that class is instantiated in a property of another class;

More specifically, I’m having trouble with the :: - Operator of scope resolution.

This is the Example class:

class Stack
{

    public $overflow;

    public static function overflow()
    {
       return 'overflow';
    }
}

In the case below, I can access the static method through the T_PAAMAYIM_NEKUDOTAYIM normally.

$stack = new Stack;

$stack::overflow();

However, in the case below, I can no longer do that:

$object = new stdClass;

$object->stack = $stack = new Stack;

$object->stack::overflow();

For it creates error:

Parse error: syntax error, Unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)

I would not like to do something like the examples below:

$object = new stdClass;

$object->stack = $stack = new Stack;

// Copia para aceitar a sintaxe

$stack = $object->stack;

$stack::overflow();

// usa uma função para chamar o método estático   
forward_static_call($object->stack, 'overflow');

Is there a simpler way to do this in PHP (without having to resort to methods or copies of variables)?

  • What is the purpose of this is to accomplish something specific or just curiosity? my suggestion is to create a new method in Stack to make the call to overflow(), something like: public function auxiliar(){ echo self::overflow; }

  • I already have the answer to this question, @rray. As I always do, I ask things that I penetrated to learn (to help the community)

  • 1

    Actually, just do that $object->stack->overflow(). Static methods are accessed as common methods when you instantiate a class :)

2 answers

5

This happens because the PHP interpreter has some inconsistencies and does not support some semantic combinations.

Fortunately these inconsistencies have been corrected in PHP 7, as you can see in this example. Some other combinations that have been corrected include:

// support missing combinations of operations
$foo()['bar']()
[$obj1, $obj2][0]->prop
getStr(){0}

// support nested ::
$foo['bar']::$baz
$foo::$bar::$baz
$foo->bar()::baz()

// support nested ()
foo()()
$foo->bar()()
Foo::bar()()
$foo()()

// support operations on arbitrary (...) expressions
(...)['foo']
(...)->foo
(...)->foo()
(...)::$foo
(...)::foo()
(...)()

// two more practical examples for the last point
(function() { ... })()
($obj->closure)()

// support all operations on dereferencable scalars (not very useful)
"string"->toLower()
[$obj, 'method']()
'Foo'::$bar

Source

2


In fact, the solution to this problem is simpler than it seems.

Contrary to what is imagined, static methods are not only accessible by means of the "double two-point" ::. When it comes to properties that contain a class instance, we can access the static methods of the instantiated class with the "separator Object" ->.

Behold:

$object = new stdClass;
$object->stack = new Stack;
$object->stack->overflow();
  • I must say, it’s at least curious behavior. I spent the day trying to understand why this, but I can only assume that it is some of those "accidental features" that still work due to some retro-compatibility.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.