Skip to main content
Code Review

Return to Answer

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link
  • More readable code. If someone is to use your class, and wants to set a distinct property to a given value, there's no need for him to write setProperties(array('bar' => 'new value'));. He can simply write $instance->setBar('new value'); which is easier to understand, and less error prone if you ask me. (upon reviewing my answer, I actually noted I made a typo, and wrote setProperties(array(); by mistake, missing the second closing )... case in point :-P)
  • A setter means that property was predefined. Read my answer to this SO question Read my answer to this SO question to get a better understanding as to why this is important. Bottom line: it's faster to get that property and set it, because the lookup is -in theory- an O(1) operation.
  • Accidental typo's make for O(n) lookups, so they're almost always going to be slower. A typo like setProperties(array('bat' => 'new value')); won't throw up errors, but when, later on, you attemt a getProperty('bar'); call, and it returns null you may find debugging is a bit of a nightmare, the more complex your code becomes.
    Compare that to setBat('new Value');, which will throw an error (method undefined)... you will, I think, agree that the latter scenario is a tad easier to debug.
  • Types. I know PHP isn't all too strict with its types. A string can be converted to an int at runtime, should the need arrive. Though it can sometimes come in handy if you know what type a property, or var holds. Again, take data-models. If a model, representing a database record has a property id, that id is likely to be an integer. The setter, then, could contain a cast ($this->id = (int) $idParameter;). The example class below illustrates some other tricks you might consider using, like passing the $_POST['password'], which will be converted to a hash on the fly.
  • Programming by interface. A number of classes might share one or two methods/properties. It could well be that this is the only bit of data a given method requires to work. Rather than leaving out the type-hints, and chekcing with method_exists() or property_exists(), or even worse: @$instance->property, you could implement an interface with getters and setters for those properties, and use a type-hint for that interface
  • Access modifiers per property: This is might seem too obvious, but is important to keep in mind. When objects inherit from one another, they gain access to their parents/eachother's __get and __set methods. By using individual properties, you can use the access modifiers to hide certain properties, even from any child classes that might extend from your current classes, and with it any other classes that follow suit.
  • More readable code. If someone is to use your class, and wants to set a distinct property to a given value, there's no need for him to write setProperties(array('bar' => 'new value'));. He can simply write $instance->setBar('new value'); which is easier to understand, and less error prone if you ask me. (upon reviewing my answer, I actually noted I made a typo, and wrote setProperties(array(); by mistake, missing the second closing )... case in point :-P)
  • A setter means that property was predefined. Read my answer to this SO question to get a better understanding as to why this is important. Bottom line: it's faster to get that property and set it, because the lookup is -in theory- an O(1) operation.
  • Accidental typo's make for O(n) lookups, so they're almost always going to be slower. A typo like setProperties(array('bat' => 'new value')); won't throw up errors, but when, later on, you attemt a getProperty('bar'); call, and it returns null you may find debugging is a bit of a nightmare, the more complex your code becomes.
    Compare that to setBat('new Value');, which will throw an error (method undefined)... you will, I think, agree that the latter scenario is a tad easier to debug.
  • Types. I know PHP isn't all too strict with its types. A string can be converted to an int at runtime, should the need arrive. Though it can sometimes come in handy if you know what type a property, or var holds. Again, take data-models. If a model, representing a database record has a property id, that id is likely to be an integer. The setter, then, could contain a cast ($this->id = (int) $idParameter;). The example class below illustrates some other tricks you might consider using, like passing the $_POST['password'], which will be converted to a hash on the fly.
  • Programming by interface. A number of classes might share one or two methods/properties. It could well be that this is the only bit of data a given method requires to work. Rather than leaving out the type-hints, and chekcing with method_exists() or property_exists(), or even worse: @$instance->property, you could implement an interface with getters and setters for those properties, and use a type-hint for that interface
  • Access modifiers per property: This is might seem too obvious, but is important to keep in mind. When objects inherit from one another, they gain access to their parents/eachother's __get and __set methods. By using individual properties, you can use the access modifiers to hide certain properties, even from any child classes that might extend from your current classes, and with it any other classes that follow suit.
  • More readable code. If someone is to use your class, and wants to set a distinct property to a given value, there's no need for him to write setProperties(array('bar' => 'new value'));. He can simply write $instance->setBar('new value'); which is easier to understand, and less error prone if you ask me. (upon reviewing my answer, I actually noted I made a typo, and wrote setProperties(array(); by mistake, missing the second closing )... case in point :-P)
  • A setter means that property was predefined. Read my answer to this SO question to get a better understanding as to why this is important. Bottom line: it's faster to get that property and set it, because the lookup is -in theory- an O(1) operation.
  • Accidental typo's make for O(n) lookups, so they're almost always going to be slower. A typo like setProperties(array('bat' => 'new value')); won't throw up errors, but when, later on, you attemt a getProperty('bar'); call, and it returns null you may find debugging is a bit of a nightmare, the more complex your code becomes.
    Compare that to setBat('new Value');, which will throw an error (method undefined)... you will, I think, agree that the latter scenario is a tad easier to debug.
  • Types. I know PHP isn't all too strict with its types. A string can be converted to an int at runtime, should the need arrive. Though it can sometimes come in handy if you know what type a property, or var holds. Again, take data-models. If a model, representing a database record has a property id, that id is likely to be an integer. The setter, then, could contain a cast ($this->id = (int) $idParameter;). The example class below illustrates some other tricks you might consider using, like passing the $_POST['password'], which will be converted to a hash on the fly.
  • Programming by interface. A number of classes might share one or two methods/properties. It could well be that this is the only bit of data a given method requires to work. Rather than leaving out the type-hints, and chekcing with method_exists() or property_exists(), or even worse: @$instance->property, you could implement an interface with getters and setters for those properties, and use a type-hint for that interface
  • Access modifiers per property: This is might seem too obvious, but is important to keep in mind. When objects inherit from one another, they gain access to their parents/eachother's __get and __set methods. By using individual properties, you can use the access modifiers to hide certain properties, even from any child classes that might extend from your current classes, and with it any other classes that follow suit.
added 428 characters in body
Source Link
  • More readable code. If someone is to use your class, and wants to set a distinct property to a given value, there's no need for him to write setProperties(array('bar' => 'new value'));. He can simply write $instance->setBar('new value'); which is easier to understand, and less error prone if you ask me. (upon reviewing my answer, I actually noted I made a typo, and wrote setProperties(array(); by mistake, missing the second closing )... case in point :-P)
  • A setter means that property was predefined. Read my answer to this SO question to get a better understanding as to why this is important. Bottom line: it's faster to get that property and set it, because the lookup is -in theory- an O(1) operation.
  • Accidental typo's make for O(n) lookups, so they're almost always going to be slower. A typo like setProperties(array('bat' => 'new value')); won't throw up errors, but when, later on, you attemt a getProperty('bar'); call, and it returns null you may find debugging is a bit of a nightmare, the more complex your code becomes.
    Compare that to setBat('new Value');, which will throw an error (method undefined)... you will, I think, agree that the latter scenario is a tad easier to debug.
  • Types. I know PHP isn't all too strict with its types. A string can be converted to an int at runtime, should the need arrive. Though it can sometimes come in handy if you know what type a property, or var holds. Again, take data-models. If a model, representing a database record has a property id, that id is likely to be an integer. The setter, then, could contain a cast ($this->id = (int) $idParameter;). The example class below illustrates some other tricks you might consider using, like passing the $_POST['password'], which will be converted to a hash on the fly.
  • Programming by interface. A number of classes might share one or two methods/properties. It could well be that this is the only bit of data a given method requires to work. Rather than leaving out the type-hints, and chekcing with method_exists() or property_exists(), or even worse: @$instance->property, you could implement an interface with getters and setters for those properties, and use a type-hint for that interface
  • Access modifiers per property: This is might seem too obvious, but is important to keep in mind. When objects inherit from one another, they gain access to their parents/eachother's __get and __set methods. By using individual properties, you can use the access modifiers to hide certain properties, even from any child classes that might extend from your current classes, and with it any other classes that follow suit.
  • More readable code. If someone is to use your class, and wants to set a distinct property to a given value, there's no need for him to write setProperties(array('bar' => 'new value'));. He can simply write $instance->setBar('new value'); which is easier to understand, and less error prone if you ask me. (upon reviewing my answer, I actually noted I made a typo, and wrote setProperties(array(); by mistake, missing the second closing )... case in point :-P)
  • A setter means that property was predefined. Read my answer to this SO question to get a better understanding as to why this is important. Bottom line: it's faster to get that property and set it, because the lookup is -in theory- an O(1) operation.
  • Accidental typo's make for O(n) lookups, so they're almost always going to be slower. A typo like setProperties(array('bat' => 'new value')); won't throw up errors, but when, later on, you attemt a getProperty('bar'); call, and it returns null you may find debugging is a bit of a nightmare, the more complex your code becomes.
    Compare that to setBat('new Value');, which will throw an error (method undefined)... you will, I think, agree that the latter scenario is a tad easier to debug.
  • Types. I know PHP isn't all too strict with its types. A string can be converted to an int at runtime, should the need arrive. Though it can sometimes come in handy if you know what type a property, or var holds. Again, take data-models. If a model, representing a database record has a property id, that id is likely to be an integer. The setter, then, could contain a cast ($this->id = (int) $idParameter;). The example class below illustrates some other tricks you might consider using, like passing the $_POST['password'], which will be converted to a hash on the fly.
  • Programming by interface. A number of classes might share one or two methods/properties. It could well be that this is the only bit of data a given method requires to work. Rather than leaving out the type-hints, and chekcing with method_exists() or property_exists(), or even worse: @$instance->property, you could implement an interface with getters and setters for those properties, and use a type-hint for that interface
  • More readable code. If someone is to use your class, and wants to set a distinct property to a given value, there's no need for him to write setProperties(array('bar' => 'new value'));. He can simply write $instance->setBar('new value'); which is easier to understand, and less error prone if you ask me. (upon reviewing my answer, I actually noted I made a typo, and wrote setProperties(array(); by mistake, missing the second closing )... case in point :-P)
  • A setter means that property was predefined. Read my answer to this SO question to get a better understanding as to why this is important. Bottom line: it's faster to get that property and set it, because the lookup is -in theory- an O(1) operation.
  • Accidental typo's make for O(n) lookups, so they're almost always going to be slower. A typo like setProperties(array('bat' => 'new value')); won't throw up errors, but when, later on, you attemt a getProperty('bar'); call, and it returns null you may find debugging is a bit of a nightmare, the more complex your code becomes.
    Compare that to setBat('new Value');, which will throw an error (method undefined)... you will, I think, agree that the latter scenario is a tad easier to debug.
  • Types. I know PHP isn't all too strict with its types. A string can be converted to an int at runtime, should the need arrive. Though it can sometimes come in handy if you know what type a property, or var holds. Again, take data-models. If a model, representing a database record has a property id, that id is likely to be an integer. The setter, then, could contain a cast ($this->id = (int) $idParameter;). The example class below illustrates some other tricks you might consider using, like passing the $_POST['password'], which will be converted to a hash on the fly.
  • Programming by interface. A number of classes might share one or two methods/properties. It could well be that this is the only bit of data a given method requires to work. Rather than leaving out the type-hints, and chekcing with method_exists() or property_exists(), or even worse: @$instance->property, you could implement an interface with getters and setters for those properties, and use a type-hint for that interface
  • Access modifiers per property: This is might seem too obvious, but is important to keep in mind. When objects inherit from one another, they gain access to their parents/eachother's __get and __set methods. By using individual properties, you can use the access modifiers to hide certain properties, even from any child classes that might extend from your current classes, and with it any other classes that follow suit.
added 2826 characters in body
Source Link
  • More readable code. If someone is to use your class, and wants to set a distinct property to a given value, there's no need for him to write setProperties(array('bar' => 'new value'));. He can simply write $instance->setBar('new value'); which is easier to understand, and less error prone if you ask me. (upon reviewing my answer, I actually noted I made a typo, and wrote setProperties(array(); by mistake, missing the second closing )... case in point :-P)
  • A setter means that property was predefined. Read my answer to this SO question to get a better understanding as to why this is important. Bottom line: it's faster to get that property and set it, because the lookup is -in theory- an O(1) operation.
  • Accidental typo's make for O(n) lookups, so they're almost always going to be slower. A typo like setProperties(array('bat' => 'new value')); won't throw up errors, but when, later on, you attemt a getProperty('bar'); call, and it returns null you may find debugging is a bit of a nightmare, the more complex your code becomes.
    Compare that to setBat('new Value');, which will throw an error (method undefined)... you will, I think, agree that the latter scenario is a tad easier to debug.
  • Types. I know PHP isn't all too strict with its types. A string can be converted to an int at runtime, should the need arrive. Though it can sometimes come in handy if you know what type a property, or var holds. Again, take data-models. If a model, representing a database record has a property id, that id is likely to be an integer. The setter, then, could contain a cast ($this->id = (int) $idParameter;). The example class below illustrates some other tricks you might consider using, like passing the $_POST['password'], which will be converted to a hash on the fly.
  • Programming by interface. A number of classes might share one or two methods/properties. It could well be that this is the only bit of data a given method requires to work. Rather than leaving out the type-hints, and chekcing with method_exists() or property_exists(), or even worse: @$instance->property, you could implement an interface with getters and setters for those properties, and use a type-hint for that interface

As you can see, I've also implemented a setPassword method, even though these isn't a password method. This method serves as an alias for setHash, in case you pass the contents of the entire $_POST array to the constructor (when processing a register or login form, for example). This'll cause the setter to do its job, while at the same time, not creating any issues with overloading the class properties, and it doesn't require you to call setHash($_POST['password']); separatly.

Like I said before: programming by interface:
Methods like these aliases are also useful when you're implementing your own interfaces. For example: clients can have an email property, whereas co-workers might have an internal office-link address or something. Create a Contactable interface, and implement a getEmail and setEmail method in the Coworker class, that servers as an alias of the getOfficeLink and setOfficeLink methods respectively.

interface Contactable
{
 public function getEmail();
 public function setEmail($email);
}
//Client class:
class Client implements Contactable
{
 private $email = null;
 public function getEmail()
 {
 return $this->email;
 }
 public function setEmail($email)
 {
 if (!filter_var($email, FILTER_VALIDATE_EMAIL))
 {//sanitize email!
 $email = null;
 }
 $this->email = $email;
 }
}
//Coworker class:
class Client implements Contactable
{
 private $officeLink = 1;
 public function setOfficeLink($link)
 {
 $link = (int) $link;
 if ($link > 1000 || $link < 1)
 {
 $link = 1;
 }
 $this->officeLink = 1;
 return $this;
 }
 public function getOfficeLink()
 {
 return $this->link;
 }
 public function getEmail()
 {
 return $this->getOfficeLink();
 }
 public function setEmail($email)
 {
 $this->setOfficeLink((int) $email);
 }
}

As you see here, it would be impossible to move the email getters and setters to an abstract class, because the validation for the values differs too much (clients should provide a valid email, whereas coworkers require a number ranging from 1 to 999). An interface is ideal for the job here, because it ensures the methods exist, but the implementation depends almost entirely on the class which implements that interface. Anyway, you can now use type-hints by interface:

public function notifyPerson(Contactable $entity)
{
 $daemon = $this->getMailer();
 $deamon->setMessage('Your request has been processed')
 ->from('[email protected]')
 ->to($entity->getEmail())
 ->send();
}

This, of course, assumes that the deamon has been programmed to recognize both emails and officeLink numbers. In any case, it's clean code, easy to read and doesn't require you to create a new instance of Client, and assign it a officeLink in email drag, just for one method call, which would make for messy code.

  • More readable code. If someone is to use your class, and wants to set a distinct property to a given value, there's no need for him to write setProperties(array('bar' => 'new value'));. He can simply write $instance->setBar('new value'); which is easier to understand, and less error prone if you ask me. (upon reviewing my answer, I actually noted I made a typo, and wrote setProperties(array(); by mistake, missing the second closing )... case in point :-P)
  • A setter means that property was predefined. Read my answer to this SO question to get a better understanding as to why this is important. Bottom line: it's faster to get that property and set it, because the lookup is -in theory- an O(1) operation.
  • Accidental typo's make for O(n) lookups, so they're almost always going to be slower. A typo like setProperties(array('bat' => 'new value')); won't throw up errors, but when, later on, you attemt a getProperty('bar'); call, and it returns null you may find debugging is a bit of a nightmare, the more complex your code becomes.
    Compare that to setBat('new Value');, which will throw an error (method undefined)... you will, I think, agree that the latter scenario is a tad easier to debug.
  • Types. I know PHP isn't all too strict with its types. A string can be converted to an int at runtime, should the need arrive. Though it can sometimes come in handy if you know what type a property, or var holds. Again, take data-models. If a model, representing a database record has a property id, that id is likely to be an integer. The setter, then, could contain a cast ($this->id = (int) $idParameter;). The example class below illustrates some other tricks you might consider using, like passing the $_POST['password'], which will be converted to a hash on the fly

As you can see, I've also implemented a setPassword method, even though these isn't a password method. This method serves as an alias for setHash, in case you pass the contents of the entire $_POST array to the constructor (when processing a register or login form, for example). This'll cause the setter to do its job, while at the same time, not creating any issues with overloading the class properties, and it doesn't require you to call setHash($_POST['password']); separatly.
Methods like these aliases are also useful when you're implementing your own interfaces. For example: clients can have an email property, whereas co-workers might have an internal office-link address or something. Create a Contactable interface, and implement a getEmail and setEmail method in the Coworker class, that servers as an alias of the getOfficeLink and setOfficeLink methods respectively.

  • More readable code. If someone is to use your class, and wants to set a distinct property to a given value, there's no need for him to write setProperties(array('bar' => 'new value'));. He can simply write $instance->setBar('new value'); which is easier to understand, and less error prone if you ask me. (upon reviewing my answer, I actually noted I made a typo, and wrote setProperties(array(); by mistake, missing the second closing )... case in point :-P)
  • A setter means that property was predefined. Read my answer to this SO question to get a better understanding as to why this is important. Bottom line: it's faster to get that property and set it, because the lookup is -in theory- an O(1) operation.
  • Accidental typo's make for O(n) lookups, so they're almost always going to be slower. A typo like setProperties(array('bat' => 'new value')); won't throw up errors, but when, later on, you attemt a getProperty('bar'); call, and it returns null you may find debugging is a bit of a nightmare, the more complex your code becomes.
    Compare that to setBat('new Value');, which will throw an error (method undefined)... you will, I think, agree that the latter scenario is a tad easier to debug.
  • Types. I know PHP isn't all too strict with its types. A string can be converted to an int at runtime, should the need arrive. Though it can sometimes come in handy if you know what type a property, or var holds. Again, take data-models. If a model, representing a database record has a property id, that id is likely to be an integer. The setter, then, could contain a cast ($this->id = (int) $idParameter;). The example class below illustrates some other tricks you might consider using, like passing the $_POST['password'], which will be converted to a hash on the fly.
  • Programming by interface. A number of classes might share one or two methods/properties. It could well be that this is the only bit of data a given method requires to work. Rather than leaving out the type-hints, and chekcing with method_exists() or property_exists(), or even worse: @$instance->property, you could implement an interface with getters and setters for those properties, and use a type-hint for that interface

As you can see, I've also implemented a setPassword method, even though these isn't a password method. This method serves as an alias for setHash, in case you pass the contents of the entire $_POST array to the constructor (when processing a register or login form, for example). This'll cause the setter to do its job, while at the same time, not creating any issues with overloading the class properties, and it doesn't require you to call setHash($_POST['password']); separatly.

Like I said before: programming by interface:
Methods like these aliases are also useful when you're implementing your own interfaces. For example: clients can have an email property, whereas co-workers might have an internal office-link address or something. Create a Contactable interface, and implement a getEmail and setEmail method in the Coworker class, that servers as an alias of the getOfficeLink and setOfficeLink methods respectively.

interface Contactable
{
 public function getEmail();
 public function setEmail($email);
}
//Client class:
class Client implements Contactable
{
 private $email = null;
 public function getEmail()
 {
 return $this->email;
 }
 public function setEmail($email)
 {
 if (!filter_var($email, FILTER_VALIDATE_EMAIL))
 {//sanitize email!
 $email = null;
 }
 $this->email = $email;
 }
}
//Coworker class:
class Client implements Contactable
{
 private $officeLink = 1;
 public function setOfficeLink($link)
 {
 $link = (int) $link;
 if ($link > 1000 || $link < 1)
 {
 $link = 1;
 }
 $this->officeLink = 1;
 return $this;
 }
 public function getOfficeLink()
 {
 return $this->link;
 }
 public function getEmail()
 {
 return $this->getOfficeLink();
 }
 public function setEmail($email)
 {
 $this->setOfficeLink((int) $email);
 }
}

As you see here, it would be impossible to move the email getters and setters to an abstract class, because the validation for the values differs too much (clients should provide a valid email, whereas coworkers require a number ranging from 1 to 999). An interface is ideal for the job here, because it ensures the methods exist, but the implementation depends almost entirely on the class which implements that interface. Anyway, you can now use type-hints by interface:

public function notifyPerson(Contactable $entity)
{
 $daemon = $this->getMailer();
 $deamon->setMessage('Your request has been processed')
 ->from('[email protected]')
 ->to($entity->getEmail())
 ->send();
}

This, of course, assumes that the deamon has been programmed to recognize both emails and officeLink numbers. In any case, it's clean code, easy to read and doesn't require you to create a new instance of Client, and assign it a officeLink in email drag, just for one method call, which would make for messy code.

Source Link
Loading
lang-php

AltStyle によって変換されたページ (->オリジナル) /