PHP扩展类,只能通过调用new static()的静态方法构造

时间:2016-02-24 14:13:58

标签: php oop

我有这个类Product有一些属性,如Name,Description等。类Product的对象只能通过静态方法fromArray()创建

$product = Product::fromArray($arr);


class Product 
{
    // getters and setters
    ...

    public static function fromArray($productArr) {
        $productObj = new static();

        if (isset($productArr['ProductId'])) {
            $productObj->setProductId($productArr['ProductId'];
        } else {
            $productObj->setProductId(null)
        }
        if (isset($productArr['Name'])) {
            $productObj->setName($productArr['Name'];
        } else {
            $productObj->setName(null)
        }
        ...

        return $productObj;
    }
}

我现在有一个ProductVariant类,(包含产品的大小和/或颜色等额外信息),应该扩展此类。 如果我只是在这个班级parent::fromArray($productVariantArr)做{&#39}。 fromArray()方法我最终会得到一个Product类型的对象而不是ProductVariant类型的对象,这显然不是我想要的。

所以我找到了解决这个问题的方法,但我完全不相信它是正确的方法。这就是我所做的:

我将Product的fromArray()方法更改为以下内容,从而可以传入扩展类的对象

public static function fromArray($productArr, $object = null) {
    if ($object !== null) {
        $productObj = $object;
    } else {
        $productObj = new static();  
    }
    ....
}

和ProductVariant类

class ProductVariant extends Product 
{
    // getters and setters 
    ...

    public static function fromArray($productVariantArr, $object = null) {
        $productVariantObj = new static();
        $productVariantObj = parent::fromArray($productVariantArr, $productVariantObj);

        if (isset($productVariantArr['Size'])) {
            $productVariantObj->setSize($productVariantArr['Size']);
        } else {
            $productVariantObj->setSize(null);
        }
        ....

        return $productVariantObj;
    }
}

但正如我所说,这似乎并不合适。任何有关如何扩展Product类的帮助都是非常受欢迎的

1 个答案:

答案 0 :(得分:0)

如何使fromArray方法非常简单和通用化,以便可以以抽象的方式轻松地在所有子类中使用它。

 class Product
 {

     ...

     public static function fromArray(array $attrs)
     {
         $instance = new static();

         foreach($attrs as $key => $value) {
             $setter = 'set'.$key;

             // Check if the setter method exists
             if (method_exists($instance, $setter)) {
                 // Invoke that method dynamically
                 call_user_func(array($instance, $setter), $value);
             } else {
                 // You might want to throw an exception here
             }
         }

         return $instance;
     }
 }

 // Child class
 class ProductVariant extends Product
 {
     ...     
 }

现在,只需这样做:

 // Now create instances
 $product = Product::fromArray([
     'Name' => 'something',
     'ProductId' => 234
 ]);

 $productVariant = ProductVariant::fromArray([
     'Size' => '15px',
     'Zier' => null
 ]);

 print_r($product);
 print_r($productVariant);

希望,这可以解决您的问题。不确定,你究竟在寻找什么。