Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the point of OOP visibility in PHP when Closures and Reflections are available?

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?

like image 215
Nathan Jackson Avatar asked Jan 20 '18 04:01

Nathan Jackson


People also ask

What is the importance of class visibility in OOP PHP?

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.

What is visibility mode in PHP?

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.

When creating a class in PHP the default visibility of a method is?

Default is public. Class methods may be defined as public, private, or protected. Methods declared without any explicit visibility keyword are defined as public.

Which of the class member visibility settings indicates that a member variable can be accessed within a class and all sub classes but not outside of the class?

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.


2 Answers

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.

like image 76
deceze Avatar answered Oct 16 '22 07:10

deceze


Great question! I would like to add few more points

The purpose of specifying visibility in OOP languages is:

  1. To show what the properties and methods are meant to do. This is to bring clarity among developers as to how to access/modify the property and methods, to decide whether to extend the class or not.
  2. The properties that are set inside its respective class is validated and set to correct values and it is safe to be used inside the Class without checking the property type.
  3. It is not a foolproof way to secure the data from modification.

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%

like image 44
Anupama V Iyengar Avatar answered Oct 16 '22 08:10

Anupama V Iyengar