【问题标题】:Is there a special object initializer construct in PHP like there is now in C#?PHP 中是否有像现在 C# 中那样的特殊对象初始化器构造?
【发布时间】:2011-04-19 18:30:20
【问题描述】:

我知道在 C# 中你现在可以这样做:

var a = new MyObject
{
    Property1 = 1,
    Property2 = 2
};

PHP 中也有类似的东西吗?或者我应该通过构造函数还是通过多个语句来完成;

$a = new MyObject(1, 2);

$a = new MyObject();
$a->property1 = 1;
$a->property2 = 2;

如果有可能,但每个人都认为这是一个糟糕的主意,我也想知道。

PS:对象无非是一堆属性。

【问题讨论】:

标签: php oop constructor initialization


【解决方案1】:

从 PHP7 开始,我们有 Anonymous Classes,它允许您在运行时扩展类,包括设置其他属性:

$a = new class() extends MyObject {
    public $property1 = 1;
    public $property2 = 2;
};

echo $a->property1; // prints 1

在 PHP7 之前,没有这样的东西。如果想法是用任意属性实例化对象,你可以这样做

public function __construct(array $properties)
{
    foreach ($properties as $property => $value) 
    {
        $this->$property = $value
    }
}

$foo = new Foo(array('prop1' => 1, 'prop2' => 2));

添加您认为合适的变体。例如,将检查添加到 property_exists 以仅允许设置已定义的成员。我发现向对象抛出随机属性是一种设计缺陷。

如果你不需要特定的类实例,但你只想要一个随机的对象包,你也可以这样做

$a = (object) [
    'property1' => 1,
    'property2' => 2
];

然后会给你一个 StdClass 的实例,你可以访问它

echo $a->property1; // prints 1

【讨论】:

  • 谢谢。这个想法不是要建立任意属性。无论如何,谢谢你的想法。我将使用我的第一个替代方案:构造函数。
  • 简单而精彩,感谢您的启发。至于它是一个“设计缺陷”:如果一个程序可以工作,并且其他程序员可以快速轻松地理解它,那么无论编程书籍怎么说,这个设计都是好的。
  • @mojuba - 我认为 Gordon 是正确的。向对象抛出随机属性的设计缺陷。许多 PHP 存在缺陷:坦率地说,它是一种可怕的语言,它使细微的错误很容易潜入您的程序(这需要很长时间才能追踪和修复)。使用具有已定义属性的类的全部意义在于,不可能通过在代码中错误键入属性名称而造成混乱(IDE 会立即捕获它,否则会出现大的运行时错误发生)。与访问不存在的数组元素相比:PHP 悄悄地将值视为 null/empty/whatever。
  • @DanielScott 您完全有可能根据从 JSON、SQL 等接收到的数据创建对象。许多库都利用了动态语言中可用的这种 hack(不只是 PHP 顺便说一句)。动态语言无论如何都是危险且容易出错的,因此您至少可以学会利用动态性来发挥自己的优势。
  • @mojuba 与使用数组或无类型对象相比,使用任意属性填充类实例有什么好处?
【解决方案2】:

我建议您在初始化对象时使用构造函数并设置所需的变量。

【讨论】:

    【解决方案3】:

    我也从 c# 转到 PHP,所以我在 PHP 中工作:

    $this->candycane = new CandyCane(['Flavor' => 'Peppermint', 'Size' => 'Large']);
    

    我的对象有一个基类,它检查是否有一个参数以及它是否是一个数组。如果是这样,它会这样称呼:

    public function LoadFromRow($row){
        foreach ($row as $columnname=>$columnvalue)
            $this->__set($columnname, $columnvalue);
    }
    

    它也适用于从数据库行加载对象。因此得名。

    【讨论】:

      【解决方案4】:

      另一种方式,这不是正确的方式,但在某些情况下可以:

      class Dog
      {
          private $name;
          private $age;
      
          public function setAge($age) {
              $this->age = $age;
              return $this;
          }
      
          public function getAge() {
              return $this->age;
          }
      
          public function setName($name) {
              $this->name = $name;
              return $this;
          }
      
          public function getName() {
              return $this->name;
          }
      }
      
      $dogs = [
          1 => (new Dog())->setAge(2)->setName('Max'),
          2 => (new Dog())->setAge(7)->setName('Woofer')
      ];
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-10
        • 2020-07-30
        • 2010-12-16
        • 2010-12-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多