6

As you know, PHP class has private, public and protected keywords. I just started to write classes and I wonder what are the advantages of class visibility in PHP5.

And of course also disadvantages...

Gordon
  • 312,688
  • 75
  • 539
  • 559
kuzey beytar
  • 3,076
  • 6
  • 37
  • 46
  • 2
    I don't think there is any disadvantage to it, except that you have to write a little bit more code to use it. Other than that, it gives you complete control over your code and its execution, and that beats any disadvantages it could bring (if there's any). – netcoder Nov 24 '10 at 15:36
  • 1
    *(related)* http://stackoverflow.com/questions/3725539/reasons-to-avoid-access-modifiers-in-php/3725581#3725581, http://stackoverflow.com/questions/2146271/importance-of-protected-private-in-php-classes, http://stackoverflow.com/questions/196737/why-not-use-protected-or-private-in-php, http://stackoverflow.com/questions/419844/best-to-use-private-methods-or-protected-methods – Gordon Nov 24 '10 at 15:37
  • If you have no use case, then you are using them without use case. Beware that they add no security themselves, and the reliability gain is mostly hypothetical. – mario Nov 24 '10 at 17:18

5 Answers5

10

It is useful if you want to apply OOP practices such as Information Hiding(Encapsulation).

If you declare class members as private, they cannot be accessed from code outside of your class. You have to provide methods to access them. This separates the interface of your class from the actual implementation.
Other code that uses your class does not need to know the name of the class member or how you actually store information internally.

Example:

Consider a class Books the somehow gives me a list of books. I can define a public member that holds an array of books:

class Books {
    public $list;
}

On the other side, if I define a method getList(), I can change the implementation later, without effecting the code that uses the class:

class Books {
    private $list;
    public function getList() {
         // get list from database, from XML, etc.
         // might use $list internally but does not have to
    }
}

Obviously, you don't need modifiers like private, protected or public to implement this behavior, but it leads to better structured code and clearer interfaces. Imagine you have a class that has both a public $list and a method getList(). How do you know which one of them to use?
This applies not only for getting values, but especially for setting values.

There are no disadvantages if you use them, only advantages IMHO. The difference between them is the scope of the visibility. public members can be accessed from outside code, protected members can be accessed form inheriting classes and private members only from the class.

Methods can also have these modifiers and follow a similar purpose. E.g. if a method is declared as private, it is clear that it is probably some kind of helper method, that is used internally only and is not supposed to be called form the outside.


So in the end it boils down to two things:

  • Control: Which parts of your class can be accessed in which way
  • Self-documentation or understanding: Other people using your class can figure out more easily, which part of your class they are supposed to access and which not.
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • You seem to mix up C++ with PHP... :) Don't forget the to declare `getList` as an actual function (i.e.: `public function getList`). – netcoder Nov 24 '10 at 15:41
  • @netcoder: Ah thanks :) If you switch between several programming languages it is easy to loose track sometimes ;) – Felix Kling Nov 24 '10 at 15:43
4

Let me answer with an example:

Leaving it all up to the client (not good):

class myClass
{
    public $name; // cannot contain spaces

}

$mc = new myClass();
$mc->name = 'John Smith'; // Oh no!

Now with more control:

class myClass
{
    private $name; // cannot contain spaces

    public function setName($value)
    {
        if (strpos($value, ' ') !== false) {
            throw new Exception('Name contains space.');
        }

        $this->name = $value;
    }

    public function getName()
    {
        return $this->name;
    }

}

$mc = new myClass();
try {
    $mc->setName('John Smith');
} catch (Exception $e) {
    echo 'Cannot set name. Reason: ', $e->getMessage();
}

Using access specifiers allows you to better protect members/methods from bad use. There are no disadvantages other than something more to learn.

webbiedave
  • 48,414
  • 8
  • 88
  • 101
  • Except that nobody does that. It's mostly shallow setters and getters. – mario Nov 24 '10 at 17:16
  • @mario: Unfortunately, many inexperienced programmers use getters/setters in the way you described. In that case, they should simply have made the members public. – webbiedave Nov 24 '10 at 17:19
  • I guess it has to do with the origin of getters/setters. But in scripting languages it's sometimes advantageous to use `__get` and `__set` anyway, which simplifies having e.g. a type enforcement ruleset. – mario Nov 24 '10 at 17:23
3

Visibility is one of the main ideas behind encapsulation, which powers object-oriented programming (esp. proper polymorphism). You should definitely specify the visibility properly, since you cannot guarantee that your class will work as expected, otherwise. By using this correctly, you have exact control over how your class members can be accessed.

I do not know of any disadvantages (except that you need to write some extra lines of code).

jwueller
  • 30,582
  • 4
  • 66
  • 70
  • 1
    Just an addition: Everybody, who reads the class, definitly see, where he/she can, should, should not, or can not access the methods/properties. – KingCrunch Nov 24 '10 at 15:36
  • 1
    Also, one of the biggest advantage to encapsulation in PHP is type checks. Unlike Java or C++, PHP is dynamically typed. If you have a public property `$foo` that you expect is a string, you can still change it to an array and get unexpected results when executing a method that needs it. Having proper encapsulation and setters allow you to throw exceptions if the value you're passing is of the wrong type, as it is being set. – netcoder Nov 24 '10 at 15:44
  • @netcoder: This is why I want member type hinting in php. In many cases getter/setter code could be reduced to nothing. Such as a name property that must be a string, but any string. But AFAIK this is not soon to be reality. :( – DampeS8N Nov 24 '10 at 15:52
1

Just imagine what would happen if you have full access to the electrical installation in your home. How long it would take before you would burn down the building or kill yourself?

Internal processes might be dangerous that's why that installation provides some public interface. In this example it would be a socket and a light switch. It's quite hard to burn down the house using light switch, isn't it?

Crozin
  • 43,890
  • 13
  • 88
  • 135
  • 1. You do have full access to your household electrical installation. All you need is a scewdriver. 2. Unless you're pretty stupid, there is no danger in having access to a well installed electrical system. Even then, the danger is in the stupidity. 3. It's just as easy to be stupid with an electrical socket as it is with all the rest of the installation. If the switch is faulty, it's MORE likely that problems will happen there than elsewhere, because it gets used more. – naught101 Nov 28 '10 at 23:16
0

Yes they are important. Put simply, they keep your code from accessing things in the wrong places.

I'm not sure of any disadvantages, other than declaring something protected or private may mean a little more work writing a getter and a setter method.

simshaun
  • 21,263
  • 1
  • 57
  • 73