Section 7.0. Introduction


7.0. Introduction

PHP 5 has significantly improved support for object-oriented programming (OOP). This is a major change and a key reason to upgrade your code from PHP 4. If you're a fan of OOP, you will be very happy with the tools PHP 5 provides you.

Early versions of PHP were strictly procedural: you could define functions, but not objects. PHP 3 introduced an extremely rudimentary form of objects, written as a late-night hack. Back in 1997, nobody expected the explosion in the number of PHP programmers, or that people would write large-scale programs in PHP. Therefore, these limitations weren't considered a problem.

Over the years, PHP gained additional object-oriented features; however, the development team never redesigned the core OO code to gracefully handle objects and classes. As a result, although PHP 4 improved overall performance, writing complex OO programs with it is still difficult, if not nearly impossible.

PHP 5 fixes these problems by using Zend Engine 2 (ZE2). ZE2 enables PHP to include more advanced object-oriented features, while still providing a high degree of backward compatibility to the millions of PHP scripts already written.

If you don't have experience with object-oriented programming outside of PHP, then you're in for a bit of a surprise. While some of the new features allow you to do things more easily, many features don't let you do anything new at all. In many ways, they restrict what you can do.

Even though it seems counterintuitive, these limitations actually help you quickly write safe code because they promote code reuse and data encapsulation. These key OO programming techniques are explained throughout the chapter. But first, here's an introduction to object-oriented programming, its vocabulary, and its concepts.

A class is a package containing two things: data and methods to access and modify that data. The data portion consists of variables; they're known as properties. The other part of a class is a set of functions that can use its properties'they're called methods.

When you define a class, you don't define an object that can be accessed and manipulated. Instead, you define a template for an object. From this blueprint, you create malleable objects through a process known as instantiation. A program can have multiple objects of the same class, just as a person can have more than one book or many pieces of fruit.

Classes also live in a defined hierarchy. Each class down the line is more specialized than the one above it. These specialized classes are called child classes, while the class they're modifying is called the parent class. For example, a parent class could be a building. Buildings can be further divided into residential and commercial. Residential buildings can be further subdivided into houses and apartment buildings, and so forth. The top-most parent class is also called the base class.

Both houses and apartment buildings have the same set of properties as all residential buildings, just as residential and commercial buildings share some things in common. When classes are used to express these parent-child relationships, the child class inherits the properties and methods defined in the parent class. This allows you to reuse the code from the parent class and requires you to write code only to adapt the new child to its specialized circumstances. This is called inheritance and is one of the major advantages of classes over functions. The process of defining a child class from a parent is known as subclassing or extending.

Objects play another role in PHP outside their traditional OO position. Since PHP can't use more than one namespace, the ability for a class to package multiple properties into a single object is extremely helpful. It allows clearly demarcated separate areas for variables.

Classes in PHP are easy to define and create:

class guest_book {  public $comments;  public $last_visitor;  function update($comment, $visitor) {  ...  } }

The class keyword defines a class, just as function defines a function. Properties are declared using the public keyword. Method declaration is identical to function definition.

The new keyword instantiates an object:

$gb = new guest_book;

Object instantiation is covered in more detail in Recipe 7.1.

Inside a class, you can optionally declare properties using public. There's no requirement to do so, but it is a useful way to reveal all the variables of the class. Since PHP doesn't force you to predeclare all your variables, it's possible to create one inside a class without PHP throwing an error or otherwise letting you know. This can cause the list of variables at the top of a class definition to be misleading, because it's not the same as the list of variables actually in the class.

In PHP 4, you declared a property using var instead of public. You can still use var, but public was added as a synonym because PHP 5 actually offers three different types of properties: public, protected, and private properties. Public properties are identical to properties in PHP 4, but the other two types behave differently. This is explained in more detail in Recipe 7.4.

Besides declaring a property, you can also assign it a value:

public $last_visitor = 'Donnan';

You can assign constant values only using this construct:

public $last_visitor = 'Donnan'; // okay public $last_visitor = 9; // okay public $last_visitor = array('Jesse'); // okay public $last_visitor = pick_visitor(); // bad public $last_visitor = 'Chris' . '9'; // bad

If you try to assign something else, PHP dies with a parse error.

To assign a non-constant value to a variable, do it from a method inside the class:

class guest_book {   public $last_visitor;   public function update($comment, $visitor) {     if (!empty($comment)) {       array_unshift($this->comments, $comment);       $this->last_visitor = $visitor;     }   } }

If the visitor left a comment, you add it to the beginning of the array of comments and set that person as the latest visitor to the guest book. The variable $this is a special variable that refers to the current object. So to access the $last_visitor property of an object from inside that object, refer to $this->last_visitor.

To assign nonconstant values to variables upon instantiation, assign them in the class constructor. The class constructor is a method automatically called when a new object is created, and it is named __construct( ), as shown in Example 7-1.

Assigning values to properties within a class constructor

class guest_book {   public $comments;   public $last_visitor;   public function __construct($user) {     $dbh = mysqli_connect('localhost', 'username', 'password', 'sites');     $user = mysqli_real_escape_string($dbh, $user);     $sql = "SELECT comments, last_visitor FROM guest_books WHERE user='$user'";     $r = mysqli_query($dbh, $sql);     if ($obj = mysqli_fetch_object($dbh, $r)) {       $this->comments = $obj->comments;       $this->last_visitor = $obj->last_visitor;     }   } } $gb = new guest_book('stewart');

Constructors are covered in Recipe 7.2. Note that in PHP 4, constructors had the same name as the class. In this example, that would be guest_book.

Be careful not to mistakenly type $this->$size. This is legal, but it's not the same as $this->size. Instead, it accesses the property of the object whose name is the value stored in the $size variable. More often than not, $size is undefined, so $this->$size appears empty. For more on variable property names, see Recipe 5.4.

Besides using -> to access a method or member variable, you can also use :: . This syntax accesses static methods in a class. These methods are identical for every instance of a class, because they can't rely on instance-specific data. There's no $this in a static method. For example:

class convert {  // convert from Celsius to Fahrenheit  public static function c2f($degrees) {    return (1.8 * $degrees) + 32;  } } $f = convert::c2f(100); // 212

To implement inheritance by extending an existing class, use the extends keyword:

class xhtml extends xml {   // ... }

Child classes inherit parent methods and can optionally choose to implement their own specific versions, as shown in Example 7-2.

Overriding parent methods

class DB {  public $result;  function getResult() {   return $this->result;  }  function query($sql) {   error_log("query() must be overridden by a database-specific child");   return false;  } } class MySQL extends DB {  function query($sql) {   $this->result = mysql_query($sql);  } }

The MySQLclass above inherits the getResult( )method unchanged from the parent DB class, but has its own MySQL-specific query( )method.

Preface the method name with parent:: to explicitly call a parent method, as shown in Example 7-3.

Calling parent methods explicitly

function escape($sql) {  $safe_sql = mysql_real_escape_string($sql); // escape special characters  $safe_sql = parent::escape($safe_sql); // parent method adds '' around $sql  return $safe_sql; }

Recipe 7-14 covers accessing overridden methods.




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