I have a class Account
which has a default constructor function:
class Account {
AccountType $type;
AccountLabel[] $labels;
AccountAttribute[] $attributes;
// Initializes a new account and assigns labels to the new account.
public function __construct(
AccountType $type,
AccountLabel[] $labels,
AccountAttribute[] $attributes)
{
$this->type = $type;
$this->labels = $labels;
$this->attributes = $attributes;
}
// Other parts of the class are omitted here.
}
I have a requirement to implement a copy constructor for this class so that a new account can be constructed by copying data from another account.
In other OOP languages, this could be done by creating an overload for the default constructor function to take in another instance of the account class for copying. However, PHP doesn't allow having two functions with the same name regardless of the arguments being different, including the __construct()
function.
I cannot make the $labels
argument as optional because it is actually required for creating a new account. Making it optional just to add a new argument could lead to many false positive test results. So, this implementation should be the last resort:
class Account {
AccountType $type;
AccountLabel[] $labels;
AccountAttribute[] $attributes;
// Initializes a new account and assigns labels to the new account;
// Or, copy from another account.
public function __construct(
AccountType $type,
AccountLabel[] $labels,
AccountAttribute[] $attributes,
Account $that)
{
if ($that === null) {
$this->type = $type;
$this->labels = $labels;
$this->attributes = $attributes;
} else
{
// Copy from another account.
$this->type = $that->type;
$this->labels = $that->labels;
$this->attributes = $that->attributes;
}
}
// Other parts of the class are omitted here.
}
I am also aware of the magic __clone
callback function. However, I am looking for ways to implement a copy constructor, not a work-around.
答案 0 :(得分:3)
PHP doesn't support methods overloading and one cannot create more than one constructor for a class.
A common way to achieve what you need is to implement a so-called "named constructor" which is just a static factory method:
class Account {
AccountType $type;
AccountLabel[] $labels;
AccountAttribute[] $attributes;
// The regular constructor
public function __construct(
AccountType $type,
AccountLabel[] $labels,
AccountAttribute[] $attributes,
{
$this->type = $type;
$this->labels = $labels;
$this->attributes = $attributes;
}
// A "named constructor" that works similar to a copy constructor
public static copyFrom(Account $account)
{
// Do not re-implement the constructor
return new self($account->type, $account->labels, $account->attributes);
}
// Other parts of the class are omitted here.
}
Read this article for more examples.
答案 1 :(得分:1)
You have 2 options:
I'd argue that #2 is better, because you still get the benefit of typing + you can make very intentionally phrased method names.
PHP does not support function overloading.
答案 2 :(得分:1)
Why the __clone
function don´t work for you?
You can clone an object like this, the default __clone
function copy all variables to the new instance.
$a = new Account(....);
$b = clone $a;
But if you don´t wont that all variable copied, than you can overwrite the __clone function in the class
class Account {
....
public function __clone() {
$this->type = null;
....
}
}