7.4.1. ProblemYou want to assign a visibility to methods and properties so they can only be accessed within classes that have a specific relationship to the object. 7.4.2. SolutionUse the public, protected, and private keywords, as shown in Example 7-9. Class using access control
7.4.3. DiscussionPHP allows you to enforce where you can access methods and properties. There are three levels of visibility:
Making a method or property public means anyone can call or edit it. This is the same behavior as versions of PHP before PHP 5. You can also label a method or property as protected, which restricts access to only the current class and any child classes that extend that class. The final visibility is private, which is the most restrictive. Properties and methods that are private can only be accessed within that specific class. If you're unfamiliar with this concept, access control can seem like an odd thing. However, when you use access control, you can actually create more robust code because it promotes data encapsulation, a key tenet of OO programming. Inevitably, whenever you write code, there's some part'the way you store the data, what parameters the functions take, how the database is organized'that doesn't work as well as it should. It's too slow, too awkward, or doesn't allow you to add new features, so you clean it up. Fixing code is a good thing, unless you accidently break other parts of your system in the process. When a program is designed with a high degree of encapsulation, the underlying data structures and database tables are not accessed directly. Instead, you define a set of functions and route all your requests through these functions. For example, you have a database table that stores names and email addresses. A program with poor encapsulation directly accesses the table whenever it needs to fetch a person's email address, as shown in Example 7-10. Selecting an email address
A better encapsulated program uses a function instead, as shown in Example 7-11. Selecting an email address using a function
Using getEmail( ) has many benefits, including reducing the amount of code you need to write to fetch an email address. However, it also lets you safely alter your database schema because you only need to change the single query in getEmail( ) instead of searching through every line of every file, looking for places where you SELECT data from the users table. It's hard to write a well-encapsulated program using functions , because the only way to signal to people "Don't touch this!" is through comments and programming conventions. Objects allow you to wall off implementation internals from outside access. This prevents people from relying on code that may change and forces them to use your functions to reach the data. Functions of this type are known as accessors, because they allow access to otherwise protected information. When redesigning code, if you update the accessors to work as before, none of the code will break. Marking something as protected or private signals that it may change in the future, so people shouldn't access it or they'll violate encapsulation. This is more than a social convention. PHP actually prevents people from calling a private method or reading a private property outside of the class. Therefore, from an external perspective, these methods and properties might as well not exist because there's no way to access them. In object-oriented programming, there is an implicit contract between the author and the users of the class. The users agree not to worry about the implementation details. The author agrees that as long as a person uses public methods they'll always work, even if the author redesigns the class. When deciding between protected and private, both provide protection against usage outside of the class. Therefore, the decision to choose one visibility versus the other really comes down to a judgement call'do you expect someone will need to invoke that method in a child class? Since it's hard to come up ahead of time with a complete list, it's best to lean toward using protected over private unless you're 110 percent sure that private is the right choice, and there's really no reason someone should ever need that method. |