PHP:如何使用另一个类中的参数实例化一个类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1858254/
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 04:05:24  来源:igfitidea点击:

PHP: How to instantiate a class with arguments from within another class

phpoopclassobjectinstantiation

提问by Sarfraz

I am in a situations where i need to instantiate a class with arguments from within an instance of another class. Here is the prototype:

我处于需要使用另一个类的实例中的参数实例化一个类的情况。这是原型:

//test.php

class test
{
    function __construct($a, $b, $c)
    {
        echo $a . '<br />';
        echo $b . '<br />';
        echo $c . '<br />';
    }
}

Now, i need to instantiate above class using below class's clsfunction:

现在,我需要使用下面类的cls函数实例化上面的类:

class myclass
{
function cls($file_name, $args = array())
{
    include $file_name . ".php";

    if (isset($args))
    {
        // this is where the problem might be, i need to pass as many arguments as test class has.
        $class_instance = new $file_name($args);
    }
    else
    {
        $class_instance = new $file_name();
    }

    return $class_instance;
}
}

Now when i try to create an instance of test class while passing arguments to it:

现在,当我尝试在向其传递参数的同时创建测试类的实例时:

$myclass = new myclass;
$test = $myclass->cls('test', array('a1', 'b2', 'c3'));

It gives error: Missing argument 1 and 2; only first argument is passed.

它给出了错误:缺少参数 1 和 2;只传递第一个参数。

This works fine if i instantiate a class which has no arguments in it's constructor function.

如果我实例化一个在其构造函数中没有参数的类,这很好用。

For experienced PHP developers, above should not be much of a problem. Please help.

对于有经验的 PHP 开发人员来说,上面应该不是什么大问题。请帮忙。

Thanks

谢谢

回答by user187291

you need Reflection http://php.net/manual/en/class.reflectionclass.php

你需要反射http://php.net/manual/en/class.reflectionclass.php

if(count($args) == 0)
   $obj = new $className;
else {
   $r = new ReflectionClass($className);
   $obj = $r->newInstanceArgs($args);
}

回答by mauris

You can:

你可以:

1) Modify test class to accept an array, which contains the data you wish to pass.

1) 修改测试类以接受一个数组,其中包含您希望传递的数据。

//test.php

class test
{
        function __construct($a)
        {
                echo $a[0] . '<br />';
                echo $a[1] . '<br />';
                echo $a[2] . '<br />';
        }
}

2) initiate using a user method instead of the constructor and call it using the call_user_func_array()function.

2) 使用用户方法而不是构造函数启动并使用call_user_func_array()函数调用它。

//test.php

class test
{
        function __construct()
        {

        }

        public function init($a, $b, $c){
                echo $a . '<br />';
                echo $b . '<br />';
                echo $c . '<br />';
        }

}

In your main class:

在您的主要课程中:

class myclass
{
function cls($file_name, $args = array())
{
        include $file_name . ".php";

        if (isset($args))
        {
                // this is where the problem might be, i need to pass as many arguments as test class has.
                $class_instance = new $file_name($args);
                call_user_func_array(array($class_instance,'init'), $args);
        }
        else
        {
                $class_instance = new $file_name();
        }

        return $class_instance;
}
}

http://www.php.net/manual/en/function.call-user-func-array.php

http://www.php.net/manual/en/function.call-user-func-array.php

Lastly, you can leave your constructor params blank and use func_get_args().

最后,您可以将构造函数参数留空并使用func_get_args().

//test.php

class test
{
        function __construct()
        {
                $a = func_get_args();
                echo $a[0] . '<br />';
                echo $a[1] . '<br />';
                echo $a[2] . '<br />';
        }
}

http://sg.php.net/manual/en/function.func-get-args.php

http://sg.php.net/manual/en/function.func-get-args.php

回答by alex

You could use call_user_func_array()I believe.

我相信你可以使用call_user_func_array()

or you could leave the arguments list of the constructor, and then inside the constructor use this

或者你可以留下构造函数的参数列表,然后在构造函数中使用这个

$args = func_get_args();

回答by Cristian

class textProperty
{
    public $start;
    public $end;
    function textProperty($start, $end)
    {
        $this->start = $start;
        $this->end = $end;
    }

}

$object = new textProperty($start, $end);

$object = new textProperty($start, $end);

don't work?

不工作?

回答by Thomas Decaux

The easiest way I have found:

我发现的最简单的方法:

if ($depCount === 0) {
            $instance = new $clazz();
        } elseif ($depCount === 1) {
            $instance = new $clazz($depInstances[0]);
        } elseif ($depCount === 2) {
            $instance = new $clazz($depInstances[0], $depInstances[1]);
        } elseif ($depCount === 3) {
            $instance = new $clazz($depInstances[0], $depInstances[1], $depInstances[2]);
        }

Sorry a bit raw, but you should understand the idea.

抱歉有点生硬,但你应该理解这个想法。

回答by Alexis Peters

We're in 2019 now and we have php7 now... and we have the spread-operator (...) . We can now simply call

我们现在在 2019 年,我们现在有 php7 ......我们有 spread-operator (...) 。我们现在可以简单地调用

<?php

class myclass
{
    function cls($file_name, $args = array())
    {
        include $file_name . ".php";

        if (isset($args))
        {
            $class_instance = new $file_name(...$args); // <-- notice the spread operator
        }
        else
        {
            $class_instance = new $file_name();
        }

        return $class_instance;
    }
}