Index
    Preface
      What This Book Is About
      What You Need to Know
      How This Book Is Organized
      How to Use This Book
      Conventions Used in This Book
      Using Code Examples
      How to Contact Us
      Web Site and Code Examples
      Acknowledgments
      Chapter 1.  Database Applications and the Web
      Section 1.1.  The Web
      Section 1.2.  Three-Tier Architectures
      Chapter 2.  The PHP Scripting Language
      Section 2.1.  Introducing PHP
      Section 2.2.  Conditions and Branches
      Section 2.3.  Loops
      Section 2.4.  Functions
      Section 2.5.  Working with Types
      Section 2.6.  User-Defined Functions
      Section 2.7.  A Working Example
      Chapter 3.  Arrays, Strings, and Advanced Data Manipulation in PHP
      Section 3.1.  Arrays
      Section 3.2.  Strings
      Section 3.3.  Regular Expressions
      Section 3.4.  Dates and Times
      Section 3.5.  Integers and Floats
      Chapter 4.  Introduction to Object-Oriented Programming with PHP 5
      Section 4.1.  Classes and Objects
      Section 4.2.  Inheritance
      Section 4.3.  Throwing and Catching Exceptions
      Chapter 5.  SQL and MySQL
      Section 5.1.  Database Basics
      Section 5.2.  MySQL Command Interpreter
      Section 5.3.  Managing Databases and Tables
      Section 5.4.  Inserting, Updating, and Deleting Data
      Section 5.5.  Querying with SQL SELECT
      Section 5.6.  Join Queries
      Section 5.7.  Case Study: Adding a New Wine
      Chapter 6.  Querying Web Databases
      Section 6.1.  Querying a MySQL Database Using PHP
      Section 6.2.  Processing User Input
      Section 6.3.  MySQL Function Reference
      Chapter 7.  PEAR
      Section 7.1.  Overview
      Section 7.2.  Core Components
      Section 7.3.  Packages
      Chapter 8.  Writing to Web Databases
      Section 8.1.  Database Inserts, Updates, and Deletes
      Section 8.2.  Issues in Writing Data to Databases
      Chapter 9.  Validation with PHP and JavaScript
      Section 9.1.  Validation and Error Reporting Principles
      Section 9.2.  Server-Side Validation with PHP
      Section 9.3.  JavaScript and Client-Side Validation
      Chapter 10.  Sessions
      Section 10.1.  Introducing Session Management
      Section 10.2.  PHP Session Management
      Section 10.3.  Case Study: Using Sessions in Validation
      Section 10.4.  When to Use Sessions
      Section 10.5.  PHP Session API and Configuration
      Chapter 11.  Authentication and Security
      Section 11.1.  HTTP Authentication
      Section 11.2.  HTTP Authentication with PHP
      Section 11.3.  Form-Based Authentication
      Section 11.4.  Protecting Data on the Web
      Chapter 12.  Errors, Debugging, and Deployment
      Section 12.1.  Errors
      Section 12.2.  Common Programming Errors
      Section 12.3.  Custom Error Handlers
      Chapter 13.  Reporting
      Section 13.1.  Creating a Report
      Section 13.2.  Producing PDF
      Section 13.3.  PDF-PHP Reference
      Chapter 14.  Advanced Features of Object-Oriented Programming in PHP 5
      Section 14.1.  Working with Class Hierarchies
      Section 14.2.  Class Type Hints
      Section 14.3.  Abstract Classes and Interfaces
      Section 14.4.  Freight Calculator Example
      Chapter 15.  Advanced SQL
      Section 15.1.  Exploring with SHOW
      Section 15.2.  Advanced Querying
      Section 15.3.  Manipulating Data and Databases
      Section 15.4.  Functions
      Section 15.5.  Automating Querying
      Section 15.6.  Table Types
      Section 15.7.  Backup and Recovery
      Section 15.8.  Managing Users and Privileges
      Section 15.9.  Tuning MySQL
      Chapter 16.  Hugh and Dave's Online Wines:A Case Study
      Section 16.1.  Functional and System Requirements
      Section 16.2.  Application Overview
      Section 16.3.  Common Components
      Chapter 17.  Managing Customers
      Section 17.1.  Code Overview
      Section 17.2.  Customer Validation
      Section 17.3.  The Customer Form
      Chapter 18.  The Shopping Cart
      Section 18.1.  Code Overview
      Section 18.2.  The Winestore Home Page
      Section 18.3.  The Shopping Cart Implementation
      Chapter 19.  Ordering and Shipping at the Online Winestore
      Section 19.1.  Code Overview
      Section 19.2.  Credit Card and Shipping Instructions
      Section 19.3.  Finalizing Orders
      Section 19.4.  HTML and Email Receipts
      Chapter 20.  Searching and Authentication in the Online Winestore
      Section 20.1.  Code Overview
      Section 20.2.  Searching and Browsing
      Section 20.3.  Authentication
      Appendix A.  Linux Installation Guide
      Section A.1.  Finding Out What's Installed
      Section A.2.  Installation Overview
      Section A.3.  Installing MySQL
      Section A.4.  Installing Apache
      Section A.5.  Installing PHP
      Section A.6.  What's Needed for This Book
      Appendix B.  Microsoft Windows Installation Guide
      Section B.1.  Installation Overview
      Section B.2.  Installing with EasyPHP
      Section B.3.  What's Needed for This Book
      Appendix C.  Mac OS X Installation Guide
      Section C.1.  Getting Started
      Section C.2.  Installing MySQL
      Section C.3.  Setting Up Apache and PHP
      Section C.4.  What's Needed for This Book
      Appendix D.  Web Protocols
      Section D.1.  Network Basics
      Section D.2.  Hypertext Transfer Protocol
      Appendix E.  Modeling and Designing Relational Databases
      Section E.1.  The Relational Model
      Section E.2.  Entity-Relationship Modeling
      Appendix F.  Managing Sessions in theDatabase Tier
      Section F.1.  Using a Database to Keep State
      Section F.2.  PHP Session Management
      Section F.3.  MySQL Session Store
      Appendix G.  Resources
      Section G.1.  Client Tier Resources
      Section G.2.  Middle-Tier Resources
      Section G.3.  Database Tier Resources
      Section G.4.  Security and Cryptography Resources
      Appendix H.  The Improved MySQL Library
      Section H.1.  New Features
      Section H.2.  Getting Started
      Section H.3.  Using the New Features
    Colophon
    Copyright



 

Previous Section  < Day Day Up >  Next Section

4.2 Inheritance

Inheritance is available in PHP4 and PHP5.

One of the powerful concepts in object-oriented programming is inheritance. Inheritance allows a new class to be defined by extending the capabilities of an existing base class or parent class. PHP allows a new class to be created by extending an existing class with the extends keyword.

Example 4-7 shows how the UnitCounter class from Example 4-4 is extended to create the new class CaseCounter. The aim of the extended class is to track the number of cases or boxes that are needed to hold the units accumulated by the counter. For example, if bottles of wines are the units, then a case might hold 12 bottles.

Example 4-7. Defining the CaseCounter class by extending UnitCounter
<?php



// Access to the UnitCounter class definition

require "example.4-1.php";



class CaseCounter extends UnitCounter

{

    var $unitsPerCase;



    function addCase( )

    {

        $this->add($this->unitsPerCase);

    }



    function caseCount( )

    {

        return ceil($this->units/$this->unitsPerCase);

    }



    function CaseCounter($caseCapacity)

    {

        $this->unitsPerCase = $caseCapacity;

    }

}



?>

Before we discuss the implementation of the CaseCounter, we should examine the relationship with the UnitCounter class. Figure 4-1 illustrates this relationship in a simple class diagram . There are several different notations for representing class diagrams; we show the inheritance relationship by joining two classes with an annotated line with a solid arrowhead.

Figure 4-1. Class diagram showing UnitCounter and CaseCounter
figs/wda2_0401.gif


The new CaseCounter class provides features related to counting cases worth of units—for example, bottles of wine—while the UnitCounter base class provides the counting and total weight capabilities. To create a CaseCounter object, the number of units that are stored in a case needs to be specified. This value is passed to the constructor when new CaseCounter object is created,

// Create a CaseCounter that holds 12 bottles in a case

$order = new CaseCounter(12);

the value is then recorded in the member variable $unitsPerCase.

The addCase( ) member function uses the $unitsPerCase member variable to add a case of units to the counter:

function addCase( )

{

  // The add( ) function is defined in the 

  // base class UnitCounter

  $this->add($this->unitsPerCase);

}

The units are added by calling the base UnitCounter member function add( ). Unless they are declared as private, member variables and functions defined in the base class can be called in derived classes using the -> operator and the special placeholder variable $this.

The caseCount( ) member function calculates the number of cases needed to contain the total number of units. For example, if there are 50 bottles of wine, and a case can hold 12 bottles, then 5 cases are needed to hold the wine. The number of cases is therefore calculated by dividing the total number of units—stored in the member variable $unit defined in the UnitCounter class—by the member variable $unitsPerCase. The result of the division is rounded up to the next whole case with the ceil( ) function. The ceil( ) function is described in Chapter 3.

When a new CaseCounter object is created and used, all of the publicly accessible member variables and functions of the base class are also available. This means that you can use a CaseCounter object as if it were a UnitCounter but it also has the extra features of the CaseCounter class. Consider an example:

// Create a CaseCounter that holds 12 bottles in a case

$order = new CaseCounter(12);



// Add seven bottles using the UnitCounter defined function

$order->add(7);



// Add a case using the CaseCounter defined function

$order->addCase( );



// Print the total number of Units : 19

print $order->units;



// Print the number of cases: 2

print $order->caseCount( );

Unlike some other object-oriented languages, PHP only allows a single base class to be specified when defining new classes. Allowing inheritance from multiple base classes can lead to unnecessarily complex code and, in practice, isn't very useful. In Chapter 14, we explore advanced techniques that eliminate the need for multiple inheritance.

4.2.1 Calling Parent Constructors

The ability to call parent constructors is available in PHP5.

CaseCounter objects use three member variables: two are defined in the UnitCounter class, and the third is defined in CaseCounter. When a CaseCounter object is created, PHP calls the _ _construct( ) function defined in CaseCounter and sets the value of the member variable $unitsPerCase with the value passed as a parameter. In the following fragment, the value passed to the _ _construct( ) function is 12:

// Create a CaseCounter that holds 12 bottles in a case

$order = new CaseCounter(12);

PHP only calls the _ _construct( ) function defined in CaseCounter; the constructor of the parent class UnitCounter is not automatically called. Therefore, objects created from the CaseCounter class defined in Example 4-7 always have the weight defined as 1 kg, the value that's set in the member variable of the parent class. The CaseCounter class shown in Example 4-8 solves this problem by defining a _ _construct( ) function that calls the UnitCounter _ _construct( ) function using the parent:: reference.

Example 4-8. Calling parent constructor function
<?php



// Access to the UnitCounter class definition

include "example.4-4.php";



class CaseCounter extends UnitCounter

{

    private $unitsPerCase;



    function addCase( )

    {

        $this->add($this->unitsPerCase);

    }



    function caseCount( )

    {

        return ceil($this->numberOfUnits( )/$this->unitsPerCase);

    }



    function _  _construct($caseCapacity, $unitWeight)

    {

        parent::_  _construct($unitWeight);

        $this->unitsPerCase = $caseCapacity;

    }

}



?>

As Example 4-8 is written to use features provided by PHP5, we extend the more sophisticated UnitCounter class defined in Example 4-4. Also, the member variable $unitsPerCase is now defined to be private and we use the PHP5 _ _construct( ) function. The constructor function of the improved CaseCounter shown in Example 4-8 takes a second parameter, $unitWeight which is passed to the _ _construct( ) function defined in the UnitCounter class.

4.2.2 Redefined Functions

Both PHP4 and PHP5 allow functions to be redefined, and the parent:: and class reference operators are available in PHP5.

Functions defined in a base class can be redefined in a descendant class. When objects of the descendant class are created, the redefined functions take precedence over those defined in the base class. We have already seen the _ _construct( ) function of the base UnitCounter class redefined in the CaseCounter class in Example 4-8.

Consider the Shape and Polygon classes defined in the following code fragment:

class Shape

{

    function info( ) 

    { 

        return "Shape."; 

    }

}



class Polygon extends Shape

{

    function info( ) 

    { 

        return "Polygon."; 

    }

}

The class Shape is the base class to Polygon, making Polygon a descendant of Shape. Both classes define the function info( ). So, following the rule of redefined functions, when an object of class Polygon is created, the info( ) function defined in the Polygon class takes precedence. This is shown in the following example:

$a = new Shape;

$b = new Polygon;



// prints "Shape."

print $a->info( );



// prints "Polygon."

print $b->info( );

With PHP 5, we can use the parent:: reference to access the info( ) function from the parent class. For example, we can modify the Polygon class definition of info( ) as follows:

class Polygon extends Shape

{

    function info( ) 

    {

        return parent::info( ) . "Polygon."; 

    }

}



$b = new Polygon;



// prints "Shape.Polygon."

print $b->info( );

This approach can be used in descendant classes, proving a way of accumulating the result of ancestor functionality. Consider a Triangle class that extends the Polygon class:

class Triangle extends Polygon

{

    function info( )

    {

        return parent::info( ) . "Triangle.";

    }

}



$t = new Triangle;



// prints "Shape.Polygon.Triangle."

print $t->info( );

The parent:: reference operator only allows access to the immediate parent class. PHP allows access to any known ancestor class using a class reference operator—we introduced the class reference earlier in our discussion of static member variables and functions in Section 4.1. We can rewrite the Triangle class to call the ancestor version of the info( ) functions directly:

class Triangle extends Polygon

{

    function info( )

    {

        return Shape::info( ) . Polygon::info( ) . "Triangle.";

    }

}



$t = new Triangle;



// prints "Shape.Polygon.Triangle."

print $t->info( );

Using the class access operators makes code less portable. For example, you would need to modify the implementation of the Triangle class if you decided that Triangle would extend Shape directly. Using the parent:: reference operator allows you to re-arrange class hierarchies more easily.

4.2.3 Protected Member Variables and Functions

Protected members are available in PHP5.

Member variables and functions can be defined using the protected keyword. This offers a compromise between being public and private: it allows access to member variables and functions defined in a class from within descendant classes, but it prevents access to the member variables and functions from code outside of the class hierarchy. So, for example, a child class can access a parent class's protected functions, but the parent class protected functions can't be accessed from an unrelated class or from within a script that uses the class.

In Example 4-5, we introduced the FreightCalculator class to work out freight costs based on the number of cases and the total weight of a shipment. The FreightCalculator class defined in Example 4-5 calculates the per case and per kilogram costs using the two private functions perCaseTotal( ) and perKgTotal( ).

In Example 4-9, we rewrite the FreightCalculator class to define these functions as protected. This allows a new class AirFreightCalculator to extend FreightCalculator and redefine the functions to apply different rates per kilogram and case count.

Example 4-9. An air freight calculator
class FreightCalculator

{



    protected $numberOfCases;

    protected $totalWeight;



    function totalFreight( )

    {

        return $this->perCaseTotal( ) + $this->perKgTotal( );

    }



    protected function perCaseTotal( )

    {

        return $this->numberOfCases * 1.00;

    }



    protected function perKgTotal( )

    {

        return $this->totalWeight * 0.10;

    }



    function _  _construct($numberOfCases, $totalWeight)

    {

        $this->numberOfCases = $numberOfCases;

        $this->totalWeight = $totalWeight;

    }

}





class AirFreightCalculator extends FreightCalculator

{



    protected function perCaseTotal( )

    {

        // $15 + $1 per case

        return 15 + $this->numberOfCases * 1.00;

    }



    protected function perKgTotal( )

    {

        // $0.40 per kilogram

        return $this->totalWeight * 0.40;

    }

}

Because the AirFreightCalculator implementation of perCaseTotal( ) and perKgTotal( ) requires access to the FreightCalculator member variables $totalWeight and $numberOfCases, these have also been declared as protected.

4.2.4 Final Functions

Declaring final functions is available in PHP5.

The AirFreightCalculator class defined in Example 4-9 doesn't redefine the totalFreight( ) member function because the definition in FreightCalculator correctly calculates the total. Descendant classes can be prevented from redefining member functions in base classes by declaring them as final. Declaring the totalFreight( ) member function with the final keyword prevents accidental redefinition in a descendant class:

final function totalFreight( )

{

    return $this->perCaseTotal( ) + $this->perKgTotal( );



}

    Previous Section  < Day Day Up >  Next Section







    Copyright © 2010 | Domen maybe sale - bye this domen