In Object Orientation getters and setters participate in the Information Concealment Principle , which ensures that a property is available for reading or recording only under certain circumstances:
-
Private: Only those who have defined
-
Protected: Who defined and who extends it
-
Public: Everyone
However, both getters and setters are optional. And this allows you to simulate read-only and even just-write properties (if there is any practical application for that) which, so far, can not be done automatically at the interpretation level:
In your example, setting url property visibility to private ensures no one can change their value directly.
If it had public visibility, this could occur:
$url = new Url;
$url -> url = 'Oi, eu sou Goku!';
And anything that depends on a valid URL would fail.
So, you have to ensure that only URLs are entered as value for this argument because through a setter , you can validate.
If this value needs to be read in the context of the instance, you must add a getter . But if this argument can not be changed in the same context, you do not need and should not have a setter because once you set the URL it should be maintained until the object is destroyed manually or at the end of the Request.
However, although the constructor of an object serves to construct the object (doh) it should not do everything by itself.
The ideal is to delegate the task of validating and assigning the property value through a setter .
But you're contradicting yourself!
Yes, it may look like this, but just as properties have configurable visibility, so are they for methods, so you can instead have a method specifically designed to validate and set a value for this property but not externally available:
class Url {
private $url;
public function __construct( $url ) {
$this -> setUrl( $url );
}
private function setUrl( $url ) {
if( filter_var( $url, FILTER_VALIDATE_URL ) === FALSE ) {
throw new InvalidArgumentException(
sprintf( '%s is not a valid URL', $url )
);
}
$this -> url= $url;
}
public function getUrl(){
return $this -> url;
}
}
Notice, too, the difference in this code in relation to yours. You accept an invalid URL which forces you to manually check if this value is a valid URL when your class needs to use the value of that property, again, again, and again.
And this defeats the purpose of a setter which is to ensure that the information passed is reliable.
In this example, if the URL does not pass validation I trigger a InvalidArgumentException , a specific natively available exception to be used when a given argument is invalid for the purpose of whoever defined it.
Good studies:)