2

How can I pass an array as constructor parameters in class instantiation?

abstract class Person {

    protected function __construct(){

    }

    public static final function __callStatic($name, $arguments){
        return new $name($arguments);
    }

}

class Mike extends Person {

    protected function __construct($age, $hobby){
        echo get_called_class().' is '.$age.' years old and likes '.$hobby;
    }
}


// =============================================

Person::Mike(15, 'golf');

This should output

Mike is 15 years old and likes golf

But I get second parameter missing in Mike's constructor, because both parameters from __callStatic are sent as array into $age. My question is how can I send them as parameters instead of array?

1
  • 2
    It's been a while since I worked with PHP but shouldn't you be using 2x_ in the constructor instead of 1? Commented Sep 12, 2014 at 15:48

3 Answers 3

2

You can use Reflection for this:

public static function __callStatic($name, $arguments){
    $reflector = new ReflectionClass($name);
    return $reflector->newInstanceArgs($arguments);
}
Sign up to request clarification or add additional context in comments.

Comments

1

Use call_user_func_array(), https://www.php.net/manual/en/function.call-user-func-array.php and a factory method:

class Mike extends Person {

    public static function instantiate($age, $hobby) {
        return new self($age, $hobby);
    }
    protected function __construct($age, $hobby){
        echo get_called_class().' is '.$age.' years old and likes '.$hobby;
    }
}

And then make a Mike like so:

abstract class Person {

    protected function __construct(){

    }

    public static final function __callStatic($name, $arguments){
        return call_user_func_array(array($name, 'instantiate'), $args);
    }

}

3 Comments

I can't do that. I need to be able to call Person::Mike()
This does exactly that.
but then I have to implement instantiate into all classes, this is not smart.
0

You're using the static scope resolutor wrong

Person::Mike(15, 'golf');

That would mean you have a static method Mike inside the class Person and you're calling it statically.

Instead, you want to instantiate Mike

$mike = new Mike(15, 'golf');

If you want to call static things from Person, because Mike extends it, Mike can also call it statically.

Mike::staticMethod($args);

2 Comments

No I don't want to do that. I have a class Person that can return instances of people classes, I explicitly don't want to be able to call people classes constructors, that's why they are protected.
I added something to better deal with your static needs

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.