I have this class Product with a few properties like Name, Description etc. An object of class Product can only be created through a static method 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;
}
}
I now have a class ProductVariant, (containing extra information like size and/or colour for a product) which should extend this class. If I simply do parent::fromArray($productVariantArr)
in this class' fromArray() method I will end up with an object of type Product and not of type ProductVariant, which is obviously not what I want.
So I found a way to work around this, but I am not convinced at all it is the right way to do it. This is what I did:
I changed the fromArray() method of Product to the following, making it possible to pass in an object of the extending class
public static function fromArray($productArr, $object = null) {
if ($object !== null) {
$productObj = $object;
} else {
$productObj = new static();
}
....
}
And the ProductVariant class
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;
}
}
But as I said, this doesn't seem right. Any help on how to extend the Product class is very welcome
How about making the fromArray
method pretty simple and generalized, so that it could be used in all the child classes easily in an abstract way.
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, just do this:
// Now create instances
$product = Product::fromArray([
'Name' => 'something',
'ProductId' => 234
]);
$productVariant = ProductVariant::fromArray([
'Size' => '15px',
'Zier' => null
]);
print_r($product);
print_r($productVariant);
Hope, this solves your problem. Not sure, what exactly you are looking for.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.