7

在 perl 我习惯做

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

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

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

是否可以一步完成?

4

4 回答 4

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;
                }
             }
         }
     }
 }

这有一系列缺点:

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

但是,它也带来了以下好处:

  • 这可以非常安全地扩展
  • 它允许您延迟实现变量
  • 它还允许您设置私有变量,前提是您知道它们的名称。如果不被滥用,这在这方面是相当不错的。
于 2013-05-31T00:03:40.517 回答
1

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

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

现在,构造函数可能具有一长串命名参数,以便您可以编写$foo = new WhatEver(1, "hello", false, null),但如果您希望这些参数像选项一样,那么它可以采用单个散列 - 用 PHP 术语来说,一个数组 - 作为其参数。

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

从 PHP 5.4([ ... ]作为array( ... ).

$foo = new WhatEver( ['bar' => 'baz'] );
于 2013-05-31T00:13:56.547 回答
1

括号中传递的参数(顺便说一下,如果没有的话,可以省略)转到构造函数方法,您可以对它们做任何您想做的事情。例如,如果定义了一个类,如下所示:

class WhatEver
{
    public $bar;

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

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

$foo = new WhatEver('baz');
于 2013-05-31T00:06:32.363 回答
1

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

如果您的设置器返回对象本身的实例,您可以链接您的方法。

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 方法链接?

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

my $foo = new WhatEver($bar1, $bar2, $bar3);

然而,这具有不能公开扩展的缺点。在少数参数之后,它变得难以管理。

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

于 2013-05-31T00:09:00.433 回答