可以在一个操作中构造PHP对象并设置它们的变量吗?

时间:2013-05-30 23:59:59

标签: php oop object constructor

在perl我习惯做

my $foo = new WhatEver( bar => 'baz' );

现在我想弄清楚PHP对象是否可以这样构造。我只看到这个:

my $foo = new WhatEver();
$foo->{bar} = 'baz';

是否可以一步完成?

4 个答案:

答案 0 :(得分:3)

您可以按如下方式布置构造函数:

 class MyClass {
     public function __construct($obj=null) {
         if ($obj && $obj instanceof Traversable || is_array($obj)) {
             foreach ($obj as $k => $v) {
                if (property_exists($this,$k)) {
                    $this->{$k} = $v;
                }
             }
         }
     }
 }

这有一系列的缺点:

  • 效率低下
  • 您创建的变量不会显示在您使用的任何文档软件上
  • 这是对所有形式的懒散的敞开大门

但是,它还具有以下好处:

  • 这可以非常安全地扩展
  • 它允许你懒惰实现变量
  • 它还允许您设置私有变量,前提是您知道它们的名称。如果不被滥用,那就非常好。

答案 1 :(得分:1)

在括号中传递的参数(顺便说一句,如果没有,可以省略)转到构造函数方法,在那里你可以随心所欲地做任何事情。如果定义了一个类,例如,如下所示:

class WhatEver
{
    public $bar;

    public function __construct($bar)
    {
        $this -> bar = $bar;
    }
}

然后你可以给它任何你需要的值。

$foo = new WhatEver('baz');

答案 2 :(得分:1)

有几种方法可以实现这一目标,但每种方法都有其自身的缺点。

如果你的setter返回一个对象本身的实例,你可以链接你的方法。

my $foo = new WhatEver();
$foo->setBar("value")->setBar2("value2");

class WhatEver
{
    public $bar;
    public $bar2;

    public function setBar($bar)
    {
        $this->bar = $bar;
        return $this;
    }

    public function setBar2($bar2)
    {
        $this->bar2 = $bar2;
        return $this;
    }
}

但是,这并没有将其简化为一步,只是在实例化后缩小每一步。

请参阅:PHP method chaining?

您也可以在构造函数中声明属性,然后将它们传递给创建时设置。

my $foo = new WhatEver($bar1, $bar2, $bar3);
然而,这具有不能明显可扩展的缺点。在一些参数之后,它变得难以管理。

更简洁但效率更低的方法是传递一个作为关联数组的参数,并迭代设置每个属性。

答案 3 :(得分:1)

这里隐含的假设是对象具有有意义的,可能是公共的属性,由调用代码提供值。这绝不是给定的--OOP的一个关键方面是封装,因此对象的主要访问是通过其方法。

初始化对象状态的“正确”机制是它的构造函数,而不是一系列属性赋值。构造函数采用的参数取决于类定义。

现在,构造函数可能有一长串命名参数,因此您可以编写$foo = new WhatEver(1, "hello", false, null)但如果您希望这些参数像选项一样,那么它可能需要一个哈希 - 用PHP术语,一个数组 - 作为其论点。

所以,回答这个问题,是的,如果您的构造函数的格式为function __construct(Array $options),然后迭代或检查$options。但这取决于构造函数如何处理这些选项;例如,传递[ 'use_safe_options' => true ]可能会触发一整套私有变量设置为记录的“安全”值。

从PHP 5.4开始(引入[ ... ]作为array( ... )的替代),它只需要比Perl版本多一些字符笔划:

$foo = new WhatEver( ['bar' => 'baz'] );