3

I found some strange PHP behaviour, I'm interested if someone could explain me why some parts of this code works, while others don't.

PHP can create new classes dynamically when class names are stored in variables. And it works fine since I'm using a modern version of PHP (5.5.28). But I found some strange behaviour that I don't really understand.

The problem occurs when the class name is stored in a property of some object. In this case, static functions cannot be called on the dynamic class: $this->dynClass::SomeFunction() fails and ($this->dynClass)::SomeFunction() fails as well. However $instance = new $this->dynClass works. So if I need to call a static method on $this->dynClass, I have to create a local variable storing the same string: $tmp = $this->dynClass. And then, I can call $tmp::SomeFunction()

I really don't understand this. Could this be a bug? Please someone explain me.

Here's my example code:

<?php
    class MyClass {
        static function SomeFunction($name){
            echo "Hello $name\n";
        }
    }

    MyClass::SomeFunction("World"); //Works fine as it should, prints Hello World

    $firstInstance = new MyClass;
    $firstInstance::SomeFunction("First"); //prints hello first, no problem

    //here comes the interesting part

    $dynClass = "MyClass";

    $dynClass::SomeFunction("Dynamic"); //Yeah, it works as well

    $secondInstance = new $dynClass;
    $secondInstance::SomeFunction("Second"); //Hello Second. Fine.

    //And here comes the part that I don't understand

    class OtherClass {
        private $dynClass = "MyClass";

        public function test(){

            $thirdInstance = new $this->dynClass; //WORKS!
            $thirdInstance::SomeFunction('Third'); //Hello Third

            //BUT

            $this->dynClass::SomeFunction("This"); //PHP Parse error:  syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)

            //OK, but then this one should work:

            ($this->dynClass)::SomeFunction("This"); //same error. WHY??

            //The only solution is creating a local variable:
            $tmp = $this->dynClass;
            $tmp::SomeFunction("Local"); //Hello Local

        }
    }

    $otherInstance = new OtherClass;
    $otherInstance->test();

?>
1

1 Answer 1

1

Before the Uniform Variable Syntax, php's variable parsing was basically a big lump of corner cases.

In particular, certain operations, like ::, where not supported on (...) expressions.

The two errors you encountered are examples of this loosely defined and inconsistent variable parser.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.