php PHP在创建新对象时传递参数,为对象调用call_user_func_array

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2550354/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 06:55:03  来源:igfitidea点击:

PHP passing parameters while creating new object, call_user_func_array for objects

php

提问by Patrick

I would like to dynamically create a PHP object, and parameters would be optional.

我想动态创建一个 PHP 对象,参数是可选的。

For example, instead of doing this:

例如,不要这样做:

$test = new Obj($param);

I would like to do something like this (create new ob is fictional):

我想做这样的事情(创建新 ob 是虚构的):

$test = create_new_obj('Obj', $param);

Is there such function in php? Something similar to call_user_func_array, but for object instead.

php中有这样的功能吗?类似于 call_user_func_array 的东西,但用于对象。

回答by TimChandler

As of PHP 5.6, you can now achieve this with a single line of code by using the new Argument Unpacking operator (...).

从 PHP 5.6 开始,您现在可以使用新的 Argument Unpacking 运算符 (...) 用一行代码来实现这一点。

Here is a simple example.

这是一个简单的例子。

$className='Foo';
$args=['arg1','arg2','arg3'];

$newClassInstance=new $className(...$args);

See PHP Variable-length argument listsfor more information.

有关更多信息,请参阅PHP 可变长度参数列表

回答by goat

Since some constructors may take a variable number of arguments, the following method should be used to accommodate it.

由于某些构造函数可能采用可变数量的参数,因此应使用以下方法来适应它。

$r = new ReflectionClass($strClassName);
$myInstance = $r->newInstanceArgs($arrayOfConstructorArgs);

For example, if your Carconstructor took 3 args

例如,如果您的Car构造函数采用 3 个参数

$carObj = new Car($color, $engine, $wheels);

Then

然后

$strClassName = 'Car';
$arrayOfConstructorArgs = array($color, $engine, $wheels);
$r = new ReflectionClass($strClassName);
$carObj = $r->newInstanceArgs($arrayOfConstructorArgs);

http://php.net/manual/en/class.reflectionclass.php
http://php.net/manual/en/reflectionclass.newinstanceargs.php

http://php.net/manual/en/class.reflectionclass.php
http://php.net/manual/en/reflectionclass.newinstanceargs.php

回答by smoe

In such cases i use factory-methods. they can be easily defined in abstract classes:

在这种情况下,我使用工厂方法。它们可以很容易地在抽象类中定义:

class Foobar {

    public function __construct($foo, $bar) 
    {
        // do something
    }

    static public function factory($foo, $bar) 
    {
        return new self($foo, $bar);
    }
}

with this you can use call_user_func_array():

有了这个,你可以使用call_user_func_array()

$my_foobar_obj = call_user_func_array('Foobar::factory', array($foo, $bar));

回答by zombat

You can dynamically create an object as long as you know the class name:

只要知道类名,就可以动态创建对象:

$objName = 'myClass';
$test = new $objName($param);

You could easily define a __construct()function to take default argumentsas well if that was a requirement of your construction logic.

如果这是您的构造逻辑的要求,您也可以轻松定义一个__construct()函数来接受默认参数

[Edit note]: This is a concept known as variable variables, and there's some examples in the manual where the newcommand is introduced.

[编辑说明]:这是一个称为变量 variables的概念,手册中有一些示例介绍了命令。

回答by Dieter Gribnitz

Here is a clean version of what you wanted:

这是您想要的干净版本:

class ClassName {
    public static function init(){       
        return (new ReflectionClass(get_called_class()))->newInstanceArgs(func_get_args());        
    }

    public static function initArray($array=[]){       
        return (new ReflectionClass(get_called_class()))->newInstanceArgs($array);        
    }

    public function __construct($arg1, $arg2, $arg3){
        ///construction code
    } 
}

Normal ugly method of creating a new object instance using new

使用 new 创建新对象实例的普通丑陋方法

$obj = new ClassName('arg1', 'arg2', 'arg3');
echo $obj->method1()->method2();

Static call using init instead of new

使用 init 而不是 new 的静态调用

echo ClassName::init('arg1', 'arg2', 'arg3')->method1()->method2();

Static call using initArray instead of new

使用 initArray 而不是 new 的静态调用

echo ClassName::initArray(['arg1', 'arg2', 'arg3'])->method1()->method2();

回答by Lajos Meszaros

Based on @chris' answer( https://stackoverflow.com/a/2550465/1806628), here is a usage of reflection classes:

基于@chris 的回答(https://stackoverflow.com/a/2550465/1806628),这里是反射类的用法:

abstract class A{
    // the constructor writes out the given parameters
    public function __construct(){
        var_dump(func_get_args());
    }

    public function copy(){
        // find our current class' name, __CLASS__ would return A
        $thisClass = get_class($this);
        $tmp = new ReflectionClass($thisClass);
        // pass all the parameters recieved to the new object
        $copy = $tmp->newInstanceArgs(func_get_args());

        return $copy;
    }
}

class B extends A{}

// create a new B object, with no parameters
$b = new B();

// create another b, but with other parameters
$c = $b->copy('the parameter of the copied B');

This is useful, if you want to make an object copy function in an ancestor class and don't know, whether child classes need parameters in the future, or not.

这很有用,如果您想在祖先类中创建对象复制功能并且不知道子类将来是否需要参数。