Lastly, I've said that magic methods are slower... properties that are added using __set
(ie properties that are not part of the class definition) are slower, too. That's another reason to disable PHP's object overloading. See here for more details See here for more details
Lastly, I've said that magic methods are slower... properties that are added using __set
(ie properties that are not part of the class definition) are slower, too. That's another reason to disable PHP's object overloading. See here for more details
Lastly, I've said that magic methods are slower... properties that are added using __set
(ie properties that are not part of the class definition) are slower, too. That's another reason to disable PHP's object overloading. See here for more details
- Is it easy to test? AFAIKTAFAICT, with the code provided it's quite easy to test. If you follow the docs (and it looks like you did follow them rather closely) then it should be easy to test.
- Could I use magic-methods: In theory, you can, but I wouldn't. More on this later (there's a lot to be said on this matter)
- Should I be validating input in the setter: YES definitly. When some snippet of code passes the wrong value to your entity, that could mean there's a bug. If your setter just blindly accepts whatever value it gets, the line that actually sets the value won't throw up errors. If you later check if everything is as it should be, then you'll have to track back to see where the wrong value was passed... have fun debugging. Adding additional validation methods is fine, but the setter should at least check the type of the value.
- entity 2 array: The easiest (And dirtiest) approach would be
(array) $entity
. All in all, I feel as if this is a bad idea. If you miss your arrays that much usegetArrayResult
on the query object
- Is it easy to test? AFAIKT, with the code provided it's quite easy to test. If you follow the docs (and it looks like you did follow them rather closely) then it should be easy to test.
- Could I use magic-methods: In theory, you can, but I wouldn't. More on this later (there's a lot to be said on this matter)
- Should I be validating input in the setter: YES definitly. When some snippet of code passes the wrong value to your entity, that could mean there's a bug. If your setter just blindly accepts whatever value it gets, the line that actually sets the value won't throw up errors. If you later check if everything is as it should be, then you'll have to track back to see where the wrong value was passed... have fun debugging. Adding additional validation methods is fine, but the setter should at least check the type of the value.
- entity 2 array: The easiest (And dirtiest) approach would be
(array) $entity
. All in all, I feel as if this is a bad idea. If you miss your arrays that much usegetArrayResult
on the query object
- Is it easy to test? AFAICT, with the code provided it's quite easy to test. If you follow the docs (and it looks like you did follow them rather closely) then it should be easy to test.
- Could I use magic-methods: In theory, you can, but I wouldn't. More on this later (there's a lot to be said on this matter)
- Should I be validating input in the setter: YES definitly. When some snippet of code passes the wrong value to your entity, that could mean there's a bug. If your setter just blindly accepts whatever value it gets, the line that actually sets the value won't throw up errors. If you later check if everything is as it should be, then you'll have to track back to see where the wrong value was passed... have fun debugging. Adding additional validation methods is fine, but the setter should at least check the type of the value.
- entity 2 array: The easiest (And dirtiest) approach would be
(array) $entity
. All in all, I feel as if this is a bad idea. If you miss your arrays that much usegetArrayResult
on the query object
Another reason to implement individual getters/setters is to program by interface. Suppose you have a dozen of data models (which isn't a lot). A couple of these models share some data (like Client
and CurrentUser
or something). Let's, for example, assume they both have a property that contains the email address. Since these models are linked to a particular table, it's not unlikely that the properties have different names (eg email
and mailAddress
).
When using type-hints, which I hope you do, you can't just hint to the abstract model type (some models don't have the required property/method). Enter Interface
:
interface HasEmail
{
public function getEmail();
public function setEmail($email);
}
class Client extends AbsctractModel implements HasEmail
{
private $email = null;
public function getEmail()
{
return $this->email;
}
public function setEmail($email)
{
$this->email = $email;
return $this;
}
}
class CurrentUser extends AbsctractModel implements HasEmail
{
private $mailAddress = null;//no email property
public function getMailAddress()
{
return $this->mailAddress;
}
public function setMailAddress($mail)
{
if (!filter_var($mail, FILTER_VALIDATE_EMAIL))
{
throw new InvalidArgumentExcetion('invalid email address: '.$mail)
}
$this->mailAddress = $mail;
return $this;
}
public function getEmail()
{
return $this->mailAddress;
}
public function setEmail($email)
{
return $this->setMailAddress($email);
}
}
With this code, you can use a type-hint that assures you the argument has specific methods, that will return you the expected data:
public function updateEmail(HasEmail $instance)
{
$newAddress = $instance->getEmail();
}
A since a class can implement multiple Interfaces, and interfaces can extend eachother, they offer a very flexible, and solid way of assuring the correct objects are being passed to the right methods, at the right time.
Another reason to implement individual getters/setters is to program by interface. Suppose you have a dozen of data models (which isn't a lot). A couple of these models share some data (like Client
and CurrentUser
or something). Let's, for example, assume they both have a property that contains the email address. Since these models are linked to a particular table, it's not unlikely that the properties have different names (eg email
and mailAddress
).
When using type-hints, which I hope you do, you can't just hint to the abstract model type (some models don't have the required property/method). Enter Interface
:
interface HasEmail
{
public function getEmail();
public function setEmail($email);
}
class Client extends AbsctractModel implements HasEmail
{
private $email = null;
public function getEmail()
{
return $this->email;
}
public function setEmail($email)
{
$this->email = $email;
return $this;
}
}
class CurrentUser extends AbsctractModel implements HasEmail
{
private $mailAddress = null;//no email property
public function getMailAddress()
{
return $this->mailAddress;
}
public function setMailAddress($mail)
{
if (!filter_var($mail, FILTER_VALIDATE_EMAIL))
{
throw new InvalidArgumentExcetion('invalid email address: '.$mail)
}
$this->mailAddress = $mail;
return $this;
}
public function getEmail()
{
return $this->mailAddress;
}
public function setEmail($email)
{
return $this->setMailAddress($email);
}
}
With this code, you can use a type-hint that assures you the argument has specific methods, that will return you the expected data:
public function updateEmail(HasEmail $instance)
{
$newAddress = $instance->getEmail();
}
A since a class can implement multiple Interfaces, and interfaces can extend eachother, they offer a very flexible, and solid way of assuring the correct objects are being passed to the right methods, at the right time.