this print for content only—size & color not accurate
CYAN
MAGENTA
YELLOW
BLACK
PANTONE 123 C
BOOKS FOR PROFESSIONALS BY PROFESSIONALS
®
Matt Zandstra, Author of
Sams Teach Yourself PHP in
24 Hours
US $44.99
Shelve in:
PHP
User level:
Intermediate
www.apress.com
SOURCE CODE ONLINE
Companion eBook
See last page for details
on $10 eBook version
ISBN 978-1-4302-2925-4
9 781430 229254
5 44 9 9
PHP Objects, Patterns, and Practice THIRD EDITION
Dear Reader,
Over the past decade, PHP has embraced the object-oriented revolution. The
language itself, the developers who work with it, and the applications they build,
all increasingly share a focus on objects and object-oriented design. Another
movement, separate but related, has taken root as well. That is the use of tools
and techniques that help to ensure the success of projects, the efficacy of teams,
and the quality of code.
You’ll begin with an overview of PHP's object-oriented features, introducing
key topics like class declaration, object instantiation, inheritance, and method
and property encapsulation. You'll also learn about advanced topics including
static methods and properties, abstract classes, interfaces, exception handling,
object cloning, namespaces, closures and more.
The next part of this book is devoted to design patterns, a vocabulary for
applying elegant solutions to common problems in software development. You’ll
learn about pattern concepts and discover how to implement several key pat-
terns in your PHP applications. You’ll also find chapters on enterprise and data-
base patterns.
In the last section of this book, you will find practices and tools for managing
your codebase and for collaborating with others in development. These include
Phing, PHPUnit, phpDocumentor, PEAR, and Subversion. You’ll also learn how
to use Continuous Integration, a system that brings all these tools together and
automates them.
I wrote PHP Objects, Patterns, and Practice to provide the kind of overview of
code design and project practice I wish had been available when I first started to
develop serious PHP applications. I hope this book inspires pleasure in coding and
teaches you to build systems that are elegant in both design and management.
Matt Zandstra
THE APRESS ROADMAP
Pro PHP:
Patterns, Frameworks,
Testing, and More
PHP Objects, Patterns, and Practice,
Third Edition
Pro
PHP Refactoring
with Test Driven Design
PHP Object-Oriented Solutions
Pro
PHP and jQuery
Practical Web 2.0 Applications
with PHP
PHP for
Absolute Beginners
Beginning
PHP and MySQL,
Third Edition
Zandstra
Companion
eBook Available
PHP Objects,
Patterns, and
Practice
7.5 x 9.25 spine = 1.000" 536 page count
THE EXPERT’S VOICE
®
IN OPEN SOURCE
THIRD EDITION
Matt Zandstra
Build powerful code by mastering PHP’s
object-oriented enhancements, design patterns,
and essential development tools
THIRD
EDITION
PHP
Objects, Patterns,
and Practice
i
PHP Objects, Patterns,
and Practice
Third Edition
■ ■ ■
Matt Zandstra
ii
PHP Objects, Patterns, and Practice, Third Edition
Copyright © 2010 by Matt Zandstra
All rights reserved. No part of this work may be reproduced or transmitted in any form or by any
means, electronic or mechanical, including photocopying, recording, or by any information
storage or retrieval system, without the prior written permission of the copyright owner and the
publisher.
ISBN-13 (pbk): 978-1-4302-2925-4
ISBN-13 (electronic): 978-1-4302-2926-1
Printed and bound in the United States of America 9 8 7 6 5 4 3 2 1
Trademarked names may appear in this book. Rather than use a trademark symbol with every
occurrence of a trademarked name, we use the names only in an editorial fashion and to the
benefit of the trademark owner, with no intention of infringement of the trademark.
President and Publisher: Paul Manning
Lead Editor: Michelle Lowman, Matt Wade
Technical Reviewer: Wes Hunt
Editorial Board: Clay Andres, Steve Anglin, Mark Beckner, Ewan Buckingham, Gary Cornell,
Jonathan Gennick, Jonathan Hassell, Michelle Lowman, Matthew Moodie, Duncan Parkes,
Jeffrey Pepper, Frank Pohlmann, Douglas Pundick, Ben Renow-Clarke, Dominic
Shakeshaft, Matt Wade, Tom Welsh
Coordinating Editor: Jim Markham
Copy Editor: Tracy Brown Collins
Compositor: MacPS, LLC
Indexer: Toma Mulligan
Artist: April Milne
Cover Designer: Anna Ischenko
Distributed to the book trade worldwide by Springer-Verlag New York, Inc., 233 Spring Street, 6th Floor,
New York, NY 10013. Phone 1-800-SPRINGER, fax 201-348-4505, e-mail ,
or visit www.springeronline.com.
For information on translations, please e-mail , or visit www.apress.com.
Apress and friends of ED books may be purchased in bulk for academic, corporate, or promotional
use. eBook versions and licenses are also available for most titles. For more information, reference
our Special Bulk Sales–eBook Licensing web page at www.apress.com/info/bulksales.
The information in this book is distributed on an “as is” basis, without warranty. Although every
precaution has been taken in the preparation of this work, neither the author(s) nor Apress shall
have any liability to any person or entity with respect to any loss or damage caused or alleged to be
caused directly or indirectly by the information contained in this work.
The source code for this book is available to readers at www.apress.com. You will need to answer
questions pertaining to this book in order to successfully download the code.
iii
Contents at a Glance
■Contents at a Glance iii
■Contents v
■About the Author xvii
■About the Technical Reviewer xviii
■Acknowledgments xix
■Introduction to the Third Edition xx
Part 1: Introduction 1
■Chapter 1: PHP: Design and Management 3
Part 2: Objects 9
■Chapter 2: PHP and Objects 11
■Chapter 3: Object Basics 15
■Chapter 4: Advanced Features 41
■Chapter 5: Object Tools 71
■Chapter 6: Objects and Design 99
Part 3: Patterns 121
■Chapter 7: What Are Design Patterns? Why Use Them? 123
■Chapter 8: Some Pattern Principles 131
■Chapter 9: Generating Objects 145
■Chapter 10: Patterns for Flexible Object Programming 169
■Chapter 11: Performing and Representing Tasks 189
■Chapter 12: Enterprise Patterns 221
■Chapter 13: Database Patterns 275
Part 4: Practice 315
■Chapter 14: Good (and Bad) Practice 317
■Chapter 15: An Introduction to PEAR and Pyrus 323
■Chapter 16: Generating Documentation with phpDocumentor 347
■Chapter 17: Version Control with Subversion 361
■Chapter 18: Testing with PHPUnit 379
■Chapter 19: Automated Build with Phing 407
■Chapter 20: Continuous Integration 427
Part 5: Conclusion 451
■Chapter 21: Objects, Patterns, Practice 453
■Appendix A: Bibliography 463
■Appendix B: A Simple Parser 467
■Index 219
iv
v
Contents
■Contents at a Glance iii
■Contents v
■About the Author xvii
■About the Technical Reviewer xviii
■Acknowledgments xix
■Introduction to the Third Edition xx
Part 1: Introduction 1
■Chapter 1: PHP: Design and Management 3
The Problem 3
PHP and Other Languages 4
About This Book 5
Objects 6
Patterns 6
Practice 6
What’s New in the Third Edition 7
Summary 7
Part 2: Objects 9
■Chapter 2: PHP and Objects 11
The Accidental Success of PHP Objects 11
In the Beginning: PHP/FI 11
Syntactic Sugar: PHP 3 11
PHP 4 and the Quiet Revolution 12
■ CONTENTS
vi
Change Embraced: PHP 5 13
Into the Future 14
Advocacy and Agnosticism: The Object Debate 14
Summary 14
■Chapter 3: Object Basics 15
Classes and Objects 15
A First Class 15
A First Object (or Two) 16
Setting Properties in a Class 17
Working with Methods 19
Creating a Constructor Method 21
Arguments and Types 22
Primitive Types 22
Taking the Hint: Object Types 25
Inheritance 27
The Inheritance Problem 27
Working with Inheritance 31
Public, Private, and Protected: Managing Access to Your Classes 35
Summary 39
■Chapter 4: Advanced Features 41
Static Methods and Properties 41
Constant Properties 44
Abstract Classes 45
Interfaces 47
Late Static Bindings: The static Keyword 48
Handling Errors 51
Exceptions 52
Final Classes and Methods 57
Working with Interceptors 58
Defining Destructor Methods 62
■ CONTENTS
vii
Copying Objects with __clone() 63
Defining String Values for Your Objects 65
Callbacks, Anonymous Functions and Closures 66
Summary 70
■Chapter 5: Object Tools 71
PHP and Packages 71
PHP Packages and Namespaces 71
Autoload 80
The Class and Object Functions 81
Looking for Classes 82
Learning About an Object or Class 83
Learning About Methods 84
Learning About Properties 85
Learning About Inheritance 85
Method Invocation 86
The Reflection API 87
Getting Started 87
Time to Roll Up Your Sleeves 88
Examining a Class 90
Examining Methods 91
Examining Method Arguments 93
Using the Reflection API 94
Summary 97
■Chapter 6: Objects and Design 99
Defining Code Design 99
Object-Oriented and Procedural Programming 100
Responsibility 103
Cohesion 104
Coupling 104
Orthogonality 104
Choosing Your Classes 105
■ CONTENTS
viii
Polymorphism 106
Encapsulation 107
Forget How to Do It 108
Four Signposts 109
Code Duplication 109
The Class Who Knew Too Much 109
The Jack of All Trades 109
Conditional Statements 110
The UML 110
Class Diagrams 110
Sequence Diagrams 117
Summary 119
Part 3: Patterns 121
■Chapter 7: What Are Design Patterns? Why Use Them? 123
What Are Design Patterns? 123
A Design Pattern Overview 125
Name 125
The Problem 125
The Solution 126
Consequences 126
The Gang of Four Format 126
Why Use Design Patterns? 127
A Design Pattern Defines a Problem 127
A Design Pattern Defines a Solution 127
Design Patterns Are Language Independent 127
Patterns Define a Vocabulary 127
Patterns Are Tried and Tested 128
Patterns Are Designed for Collaboration 128
Design Patterns Promote Good Design 128
PHP and Design Patterns 129
Summary 129
■ CONTENTS
ix
■Chapter 8: Some Pattern Principles 131
The Pattern Revelation 131
Composition and Inheritance 132
The Problem 132
Using Composition 135
Decoupling 137
The Problem 137
Loosening Your Coupling 139
Code to an Interface, Not to an Implementation 141
The Concept That Varies 142
Patternitis 143
The Patterns 143
Patterns for Generating Objects 143
Patterns for Organizing Objects and Classes 143
Task-Oriented Patterns 143
Enterprise Patterns 144
Database Patterns 144
Summary 144
■Chapter 9: Generating Objects 145
Problems and Solutions in Generating Objects 145
The Singleton Pattern 149
The Problem 149
Implementation 150
Consequences 152
Factory Method Pattern 152
The Problem 153
Implementation 155
Consequences 157
Abstract Factory Pattern 157
The Problem 158
Implementation 159
■ CONTENTS
x
Consequences 161
Prototype 162
The Problem 163
Implementation 163
But That’s Cheating! 166
Summary 167
■Chapter 10: Patterns for Flexible Object Programming 169
Structuring Classes to Allow Flexible Objects 169
The Composite Pattern 169
The Problem 170
Implementation 172
Consequences 175
Composite in Summary 178
The Decorator Pattern 179
The Problem 179
Implementation 181
Consequences 185
The Facade Pattern 185
The Problem 185
Implementation 186
Consequences 187
Summary 187
■Chapter 11: Performing and Representing Tasks 189
The Interpreter Pattern 189
The Problem 189
Implementation 190
Interpreter Issues 197
The Strategy Pattern 198
The Problem 198
Implementation 199
The Observer Pattern 202
■ CONTENTS
xi
Implementation 204
The Visitor Pattern 210
The Problem 210
Implementation 211
Visitor Issues 215
The Command Pattern 216
The Problem 216
Implementation 216
Summary 220
■Chapter 12: Enterprise Patterns 221
Architecture Overview 221
The Patterns 222
Applications and Layers 222
Cheating Before We Start 225
Registry 225
Implementation 226
The Presentation Layer 235
Front Controller 235
Application Controller 245
Page Controller 257
Template View and View Helper 262
The Business Logic Layer 264
Transaction Script 265
Domain Model 269
Summary 273
■Chapter 13: Database Patterns 275
The Data Layer 275
Data Mapper 275
The Problem 276
Implementation 276
Consequences 287
■ CONTENTS
xii
Identity Map 288
The Problem 288
Implementation 289
Consequences 291
Unit of Work 291
The Problem 292
Implementation 292
Consequences 296
Lazy Load 296
The Problem 296
Implementation 297
Consequences 298
Domain Object Factory 298
The Problem 298
Implementation 299
Consequences 300
The Identity Object 301
The Problem 301
Implementation 302
Consequences 307
The Selection Factory and Update Factory Patterns 307
The Problem 307
Implementation 307
Consequences 311
What’s Left of Data Mapper Now? 311
Summary 313
Part 4: Practice 315
■Chapter 14: Good (and Bad) Practice 317
Beyond Code 317
Borrowing a Wheel 317
Playing Nice 319
■ CONTENTS
xiii
Giving Your Code Wings 319
Documentation 320
Testing 321
Continuous Integration 322
Summary 322
■Chapter 15: An Introduction to PEAR and Pyrus 323
What Is PEAR? 323
Phar Out with Pyrus 324
Installing a Package 326
PEAR Channels 327
Using a PEAR Package 329
Handling PEAR Errors 331
Creating Your Own PEAR Package 334
package.xml 334
Package Elements 334
The contents Element 336
Dependencies 339
Tweaking Installation with phprelease 340
Preparing a Package for Shipment 341
Setting Up Your Own Channel 341
Summary 346
■Chapter 16: Generating Documentation with phpDocumentor 347
Why Document? 347
Installation 348
Generating Documentation 349
DocBlock Comments 350
Documenting Classes 352
File-Level Documentation 353
Documenting Properties 353
Documenting Methods 355
■ CONTENTS
xiv
Creating Links in Documentation 356
Summary 359
■Chapter 17: Version Control with Subversion 361
Why Use Version Control? 361
Getting Subversion 362
Configuring a Subversion Repository 363
Creating a Repository 363
Beginning a Project 364
Updating and Committing 368
Adding and Removing Files and Directories 371
Adding a File 371
Removing a File 372
Adding a Directory 372
Removing Directories 373
Tagging and Exporting a Release 373
Tagging a Project 373
Exporting a Project 374
Branching a Project 374
Summary 378
■Chapter 18: Testing with PHPUnit 379
Functional Tests and Unit Tests 379
Testing by Hand 380
Introducing PHPUnit 382
Creating a Test Case 382
Assertion Methods 383
Testing Exceptions 384
Running Test Suites 385
Constraints 386
Mocks and Stubs 388
Tests Succeed When They Fail 391
■ CONTENTS
xv
Writing Web Tests 394
Refactoring a Web Application for Testing 394
Simple Web Testing 397
Introducing Selenium 398
A Note of Caution 403
Summary 405
■Chapter 19: Automated Build with Phing 407
What Is Phing? 407
Getting and Installing Phing 408
Composing the Build Document 408
Targets 410
Properties 412
Types 416
Tasks 421
Summary 425
■Chapter 20: Continuous Integration 427
What Is Continuous Integration? 427
Preparing a Project for CI 428
CruiseControl and phpUnderControl 436
Installing CruiseControl 436
Installing phpUnderControl 438
Installing Your Project 440
Summary 450
Part 5: Conclusion 451
■Chapter 21: Objects, Patterns, Practice 453
Objects 453
Choice 454
Encapsulation and Delegation 454
Decoupling 454
Reusability 455
Aesthetics 455
■ CONTENTS
xvi
Patterns 455
What Patterns Buy Us 456
Patterns and Principles of Design 456
Practice 458
Testing 459
Documentation 459
Version Control 459
Automated Build 459
Continuous Integration 460
What I Missed 460
Summary 460
■Appendix A: Bibliography 463
Books 463
Articles 464
Sites 464
■Appendix B: A Simple Parser 467
The Scanner 467
The Parser 474
■Index 487
■ CONTENTS
xvii
About the Author
■ Matt Zandstra has worked as a web programmer, consultant, and writer for over a decade. He is a
senior developer at Yahoo, and a freelance coder and writer. Matt is the author of Teach Yourself PHP in
24 Hours (SAMS) and a contributor to DHTML Unleashed (SAMS). He has written articles for Linux
Magazine, Zend.com, IBM DeveloperWorks, and php|architect Magazine, among others. He works
primarily with PHP and Java, designing and building web and command-line applications.
Matt lives in Liverpool with his wife, Louise, and two children, Holly and Jake.
■ CONTENTS
xviii
About the Technical Reviewer
■ Wes Hunt is a web-application developer and consultant at 4th Dimension
Development, which builds web solutions for organizations from small to the
enterprise level. For over a decade, he has used Java and PHP to deliver everything
plus the kitchen sink for clients. His latest passion is leveraging Flex with a PHP
back-end to produce RIAs for clients. Wes uses development patterns and best
practices in order to spend more time enjoying the outdoors near his home in
Montana.
■ CONTENTS
xix
Acknowledgments
When you first have an idea for a book (in my case, while drinking good coffee in a Brighton cafe), it is
the subject matter alone that grips you. In the enthusiasm of the moment, it is easy to forget the scale of
the undertaking. I soon rediscovered the sheer hard work a book demands, and I learned once again that
it’s not something you can do alone. At every stage of this book’s development, I have benefited from
enormous support.
In fact, my thanks must predate the book’s conception. The themes of this book first saw the light of
day in a talk I gave for a Brighton initiative called Skillswap (www.skillswap.org) run by Andy Budd. It
was Andy’s invitation to speak that first planted the seeds of the idea in my mind. For that, I still owe
Andy a pint and much thanks.
By chance, attending that meeting was Jessey White-Cinis, another Apress author, who put me in
touch with Martin Streicher, who commissioned the book for Apress straightaway.
My thanks go out to both Jessey and Martin for seeing potential in the slightest of beginnings.
Once again the Apress team has provided enormous support in the face of a very tight deadline, and
my tendency to go quiet as I moved with my family to a new continent in the middle of the project.
Thanks to Steven Metsker for his kind permission to re-implement in PHP a brutally simplified
version of the parser API he presented in his book Building Parsers in Java.
Writing to a deadline is not conducive to family life, and so I must send my thanks and love to my
wife, Louise, and to our children, Holly and Jake. I have missed you all.
Since the publication of the first edition, I have been lucky to receive much enthusiastic and
constructive feedback from readers. I’m sorry that I haven’t been able to reply to everyone individually,
but I’d like to take this opportunity to thank all correspondents for your messages.
The soundtrack to the writing of the first edition was provided by John Peel. John was a broadcaster
who waged a 40-year war on the bland and mass-produced in music simply by championing everything
original and eclectic he could lay his hands on. John died suddenly in October 2004, leaving listeners
around the world bereft. He had an extraordinary impact on many lives, and I would like to add my
thanks here.
■ CONTENTS
xx
Introduction to the Third Edition
When I first had the idea for PHP Objects, Patterns, and Practice, I felt I was swimming against the tide.
Many pattern implementations in PHP felt like glorified workarounds due to limitations in the
language. These days, though, it can be hard to keep up with pace of innovation in PHP objects,
design, and project practice.
If that's a problem, well, it's the kind you want to have. Especially if you have the tools at hand to
navigate the risks and opportunities that present themselves.
PHP continues to tick items off the object-oriented developer's wish list. Since the last edition of
this book, we have seen namespaces make it into the language, late static binding, anonymous
functions, and closures (if those don't yet mean anything to you, don't worry, they're all covered by
this book). PHP is an active language, constantly evolving to meet the needs of its users.
For a developer, this presents some interesting challenges. Not least, the tension between a stable
codebase and the desire to take advantage of the goodies that every new release brings. With a good
suite of tests, preferably run automatically, tools for collaboration, and an easily installed system, you
can improve the design of your code, play with new features, and be fairly sure that you're not
breaking stuff.
And that's where this book comes in, I hope. I want to explore what's exciting, both in the
language and in the wider world of object-oriented design. At the same time, I want to take in the
tools and practices you can use to safeguard your project from the hordes of bugs that lurk beyond
sight whenever you make a change.
As well as new language features, this edition benefits from coverage of web testing with Selenium,
and the ultimate tool of tools: a Continuous Integration server that runs tests, builds your system, and
applies diagnostic tools to your project.
How real is a web application? It exists as lines of code, of course, bits stored on a computer. It
exists in its execution on a server. But really, for the developer, an application first lives in the
imagination. It is a structure made up of parts that interlock more or less elegantly. Then, if we're
lucky, it is realized and deployed, and it really comes alive at the moment someone uses it. There,
right there, is where the magic of coding lives.
That's what this book is really about. It's about taking an idea and shaping it, and the pleasure to
be found in the process. It's about the shapes of a system in your imagination, and the satisfaction
when these shapes are expressed in code. And then again when the system actually works. It's about
the freedom that tests give you to take risks, and the risks that your imagination inspires you to take.
It's the moment that something you wrote becomes real in the eyes of another.
P A R T 1
■ ■ ■
1
Introduction
CHAPTER 1 ■ PHP: DESIGN AND MANAGEMENT
2
C H A P T E R 1
■ ■ ■
3
PHP: Design and Management
When PHP 5 was released early in 2004, among the most important features it introduced was enhanced
support for object-oriented programming. This stimulated much interest in objects and design within
the PHP community. In fact, this was an intensification of a process that began when version 4 first
made object-oriented programming with PHP a serious reality.
In this chapter, I look at some of the needs that coding with objects can address. I very briefly
summarize the evolution of patterns and related practices in the Java world. I look at signs that indicate
a similar process is occurring among PHP coders.
I also outline the topics covered by this book.
I will look at
• The evolution of disaster: A project goes bad.
• Design and PHP: How object-oriented design techniques are taking root in the
PHP community.
• This book: Objects. Patterns. Practice.
The Problem
The problem is that PHP is just too easy. It tempts you to try out your ideas, and flatters you with good
results. You write much of your code straight into your web pages, because PHP is designed to support
that. You add utility functions (such as database access code) to files that can be included from page to
page, and before you know it you have a working web application.
You are well on the road to ruin. You don’t realize this, of course, because your site looks fantastic. It
performs well, your clients are happy, and your users are spending money.
Trouble strikes when you go back to the code to begin a new phase. Now you have a larger team,
some more users, a bigger budget. Yet without warning, things begin to go wrong. It’s as if your project
has been poisoned.
Your new programmer is struggling to understand code that is second nature to you, though
perhaps a little byzantine in its twists and turns. She is taking longer than you expected to reach full
strength as a team member.
A simple change, estimated at a day, takes three days when you discover that you must update 20 or
more web pages as a result.
One of your coders saves his version of a file over major changes you made to the same code some
time earlier. The loss is not discovered for three days, by which time you have amended your own local
copy. It takes a day to sort out the mess, holding up a third developer who was also working on the file.
Because of the application’s popularity, you need to shift the code to a new server. The project has
to be installed by hand, and you discover that file paths, database names, and passwords are hard-coded
into many source files. You halt work during the move because you don’t want to overwrite the