Recipe 7.4. Implementing Access Control


7.4.1. Problem

You 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. Solution

Use the public, protected, and private keywords, as shown in Example 7-9.

Class using access control

class Person {     public $name;     // accesible anywhere     protected $age;   // accesible within the class and child classes     private $salary;  // accesible only within this specific class     public function __construct() {     // ...     }     protected function set_age() {     // ...     }     private function set_salary() {     // ...     } }

7.4.3. Discussion

PHP allows you to enforce where you can access methods and properties. There are three levels of visibility:

  • public

  • protected

  • private

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

$name   = 'Rasmus Lerdorf'; $db     = mysqli_connect(); $result = mysqli_query($db, "SELECT email FROM users                             WHERE name  LIKE '$name'"); $row    = mysqli_fetch_assoc($db, $r); $email  = $row['email'];

A better encapsulated program uses a function instead, as shown in Example 7-11.

Selecting an email address using a function

function getEmail($name) {     $db = mysqli_connect();     $result = mysqli_query($db, "SELECT email FROM users                                 WHERE name  LIKE '$name'");     $row    = mysqli_fetch_assoc($db, $r);     $email  = $row['email'];     return $email } $email = getEmail('Rasmus Lerdorf');

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.




PHP Cookbook, 2nd Edition
PHP Cookbook: Solutions and Examples for PHP Programmers
ISBN: 0596101015
EAN: 2147483647
Year: 2006
Pages: 445

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net