Consider this code here:
final class TinkerWithMe {
protected $key1 = 19;
private $key2 = 88;
}
$class = new TinkerWithMe();
$getKeys = function() {
return array($this->key1, $this->key2);
};
$oldKeys = $getKeys->call($class);
$newKey1 = 96;
$newKey2 = 42;
$setKeys = function() use ($newKey1, $newKey2) {
$this->key1 = $newKey1;
$this->key2 = $newKey2;
};
$setKeys->call($class);
Why bother with OOP visibility when you can get around it so easily with Closures or Reflections?
Is there a way of blocking this kind of thing that I am missing?
Visibility is declared using a visibility keyword to declare what level of visibility a property or method has. The three levels define whether a property or method can be accessed outside of the class, and in classes that extend the class.
PHP has three visibility keywords - public, private and protected. A class member declared with public keyword is accessible from anywhare. A protected member is accessible from within its class and by inheriting class.
Default is public. Class methods may be defined as public, private, or protected. Methods declared without any explicit visibility keyword are defined as public.
Protected :: A protected variable or method cannot be accessed by users of the class but can be accessed inside a subclass that inherits from the class. Private :: A private variable or method can only be accessed internally from the class in which it is defined.
Visibility modifiers aren't iron clad protection or ensure any sort of security or anything of that sort. They're markers for how a piece of code is intended to be used.
When writing a piece of code like a class, other pieces of code are going to couple with it; meaning you will write other code that calls methods of that class or accesses properties of that class. In order to minimise coupling to the absolute necessary, you will want to keep the public interface of the class as small as possible. When you designate something as public
, you're marking it "for general use". That public piece should then be rather stable and not change, or you risk breaking a lot of coupled code if you do change it.
Marking something as protected
or private
marks these parts as not for general consumption; it clarifies that these implementation details might change in the future or are not supposed to be used by other code "not in the know". This allows you to easier refactor those parts later as necessary and having a better idea of what other parts might break as a result. It also helps to ensure the internal state of the class is consistent when external code won't directly modify internal values without completely understanding how it should do so.
PHP will help you honour those markers in the general case by throwing errors when naïvely trying to access protected
or private
properties "from the outside"; that prevents most accidental usage and unwanted coupling. PHP is not going to bend over backwards to ensure those properties stay inaccessible under all possible circumstances. If you're really bent on shooting your own foot, so be it. Perhaps you need to do so for testing purposes; it would be counter productive to absolutely prevent you from doing so.
In the mantra of Python:
We're all consenting adults here.
Great question! I would like to add few more points
The purpose of specifying visibility in OOP languages is:
The Purpose of Closures is to throw a piece of function into a variable or another function to perform some activity once in a while. Instead of dedicating a separate section code in global scope for performing an action once in a while and not look at it later you can use closures.
Reflections are meant to introspect objects to know its properties, methods, class etc. It is useful to identify dependencies. Larvel uses reflection to perform dependency injection of objects.
Yes as you said you can use Closures and Reflection to work around visibility but it should be viewed as a language feature rather than a design flaw as no language can secure data 100%
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With