®O B J E C T- O R I E N T E D      PHP         CONCEPTS, TECHNIQUES, A ND CODE                                               PETER LAVIN
OBJECT-ORIENTED           PHP    Concepts, Techniques,                and Code                      by Peter Lavin                                                                                                                                ®                                        San Francisco
OBJECT-ORIENTED PHP. Copyright © 2006 by Peter Lavin.All rights reserved. No part of this work may be reproduced or transmitted in any form or by any means, electronic ormechanical, including photocopying, recording, or by any information storage or retrieval system, without the priorwritten permission of the copyright owner and the publisher.Printed on recycled paper in the United States of America1 2 3 4 5 6 7 8 9 10 – 09 08 07 06No Starch Press and the No Starch Press logo are registered trademarks of No Starch Press, Inc. Other product andcompany names mentioned herein may be the trademarks of their respective owners. Rather than use a trademarksymbol with every occurrence of a trademarked name, we are using the names only in an editorial fashion and to thebenefit of the trademark owner, with no intention of infringement of the trademark.Publisher: William PollockManaging Editor: Elizabeth CampbellAssociate Production Editor: Christina SamuellCover and Interior Design: Octopod StudiosDevelopmental Editor: William PollockTechnical Reviewer: Peter MacIntyreCopyeditors: Publication Services, Inc. and Sarah LemaireCompositor: Riley HoffmanProofreader: Stephanie ProvinesFor information on book distributors or translations, please contact No Starch Press, Inc. directly:No Starch Press, Inc.555 De Haro Street, Suite 250, San Francisco, CA 94107phone: 415.863.9900; fax: 415.863.9950; [email protected]; www.nostarch.comThe information in this book is distributed on an “As Is” basis, without warranty. While every precaution has beentaken in the preparation of this work, neither the author nor No Starch Press, Inc. shall have any liability to anyperson or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by theinformation contained in it.Library of Congress Cataloging-in-Publication DataLavin, Peter.                                                                                         I. Title. Object-oriented PHP : concepts, techniques, and code / Peter Lavin.         p. cm. Includes index. ISBN 1-59327-077-11. PHP (Computer program language) 2. Object-oriented programming (Computer science)QA76.73.P224L38 2006 005.1'17--dc22                                                                                          2006015309
BRIEF CONTENTSAcknowledgments ........................................................................................................ xiiiIntroduction ...................................................................................................................xvChapter 1: What a Tangled Web We Weave....................................................................1Chapter 2: Basics of Object-Oriented Programming ............................................................5Chapter 3: Object-Oriented Features New to PHP 5 ..........................................................11Chapter 4: Show a Little Class ........................................................................................17Chapter 5: Mod UR Class ..............................................................................................25Chapter 6: The ThumbnailImage Class.............................................................................35Chapter 7: Building the PageNavigator Class...................................................................47Chapter 8: Using the PageNavigator Class ......................................................................57Chapter 9: Database Classes .........................................................................................65Chapter 10: Improvement Through Inheritance..................................................................75Chapter 11: Advanced Object-Oriented Programming Concepts ........................................91Chapter 12: Keeping It Fresh..........................................................................................99Chapter 13: More Magic Methods................................................................................111Chapter 14: Creating Documentation Using the Reflection Classes ....................................125Chapter 15: Extending SQLite ......................................................................................139Chapter 16: Using PDO...............................................................................................157Appendix A: Setting Up PHP 5 .....................................................................................165Appendix B: Conversion Table: PHP 4 and PHP 5 ...........................................................169Glossary ....................................................................................................................173Index .........................................................................................................................179
CONTENTS IN DETAILACKNOWLEDGMENTS                        xiiiINTRODUCTION                           xvWhat Does This Book Have to Offer? ....................................................................... xviWho Should Read This Book? .................................................................................. xviRequirements ......................................................................................................... xvi            Software .................................................................................................. xvi            Skills ........................................................................................................xviiOverview of Contents .............................................................................................xviiCompanion Website .............................................................................................. xixResources ............................................................................................................... xx            Websites ................................................................................................... xx            Books ....................................................................................................... xx1                                      1WHAT A TANGLED WEB WE WEAVEDo We Really Need Objects? .................................................................................... 2            Just a Scripting Language ............................................................................. 2            Object Orientation Is for Large Software Shops ............................................... 3            Leave Well Enough Alone ............................................................................ 3            Increased Complexity .................................................................................. 3The PHP Culture ....................................................................................................... 42                                      5BASICS OF OBJECT-ORIENTED PROGRAMMINGClass ...................................................................................................................... 6            Classes Versus Records ................................................................................ 6            A Cohesive Whole ...................................................................................... 6            Objects Are Instances .................................................................................. 6Objects Need Access Modifiers ................................................................................. 7Object Reuse and Inheritance .................................................................................... 7            Multiple Inheritance ..................................................................................... 8            Having Your Cake and Eating It Too .............................................................. 8Where to Go from Here ............................................................................................ 93                                      11OBJECT-ORIENTED FEATURES NEW TO PHP 5Access Modifiers .................................................................................................... 12Built-in Classes ....................................................................................................... 12            Exceptions ................................................................................................ 12            Database Classes ...................................................................................... 13
Web Services ........................................................................................... 13            Reflection Classes ..................................................................................... 14            Iterator ..................................................................................................... 14Backward Compatibility .......................................................................................... 14            Pass By Reference ..................................................................................... 14            Prognosis ................................................................................................. 15Where to Go from Here .......................................................................................... 15            Adoption of PHP 5 .................................................................................... 16            Compromise ............................................................................................. 164                               17SHOW A LITTLE CLASSDesign .................................................................................................................. 18            Defining the Problem ................................................................................. 18Not the Da Vinci Code ........................................................................................... 19            The Constructor ......................................................................................... 19            Referencing Instance Variables ................................................................... 20            Wrapper Methods ..................................................................................... 20Creating an Instance .............................................................................................. 21What Have You Accomplished? ............................................................................... 23But Will It Fly? ....................................................................................................... 235                               25MOD UR CLASSUpgrading to PHP 5 ............................................................................................... 26            Access Modifiers ....................................................................................... 26            The Constructor ......................................................................................... 28Modifying Your Class ............................................................................................. 29            Reconstructing the Constructor .................................................................... 29            Filtering Content ........................................................................................ 31            Resetting the Array .................................................................................... 32Summary of Changes ............................................................................................. 336                               35THE THUMBNAILIMAGE CLASSWhat Does a Designer Do? ..................................................................................... 36            Mimicking the Designer ............................................................................. 36            Help from PHP Functions ............................................................................ 36The ThumbnailImage Class ...................................................................................... 37            Data Members .......................................................................................... 37            Deconstructing the Constructor .................................................................... 37            Two Ways to Construct an Object ............................................................... 38            Internal Behavior—Private Methods ............................................................. 39            Must It Be Private? ..................................................................................... 40            A Helper Method ...................................................................................... 40            Public Methods ......................................................................................... 41            Garbage Collection ................................................................................... 41viii Con t en t s in D et ai l
Displaying the Image ................................................................................. 41            Get and Set Methods ................................................................................. 42            Image Quality ........................................................................................... 42            When to Change the Quality ...................................................................... 43Displaying a Thumbnail .......................................................................................... 44Putting It All Together .............................................................................................. 44Where to Go from Here .......................................................................................... 457                                 47BUILDING THE PAGENAVIGATOR CLASSHow Will the Navigator Behave? ............................................................................. 47            Different Kinds of Searches ......................................................................... 48What Will It Look Like? ........................................................................................... 48The Code .............................................................................................................. 49            The Constructor ......................................................................................... 51            Ain’t Misbehavin’ ...................................................................................... 52            Other Constructor Method Calls .................................................................. 52The getNavigator Method ....................................................................................... 54            Move First and Move Previous .................................................................... 54            Main Body of the Navigator ....................................................................... 55            Move Next and Move Last ......................................................................... 56            Current and Total Number of Pages ............................................................ 56Where to Go from Here .......................................................................................... 568                                 57USING THE PAGENAVIGATOR CLASSDirectoryItems Change ............................................................................................ 58CSS and Reusability ............................................................................................... 58Paging with Class .................................................................................................. 60            Displaying an Array Slice ........................................................................... 61            Creating the PageNavigator Object ............................................................ 62Where to Go from Here .......................................................................................... 639                                 65DATABASE CLASSESUsing What You Know ........................................................................................... 65One Lump or Two? ................................................................................................. 66The MySQLConnect Class ....................................................................................... 66            A Class-Conscious Variable ........................................................................ 67            Making Other Connections ......................................................................... 68            You Can Only Get There from Here ............................................................. 68The MySQLResultSet Class ....................................................................................... 69Using the Page Navigator ....................................................................................... 70            Ordering, Filtering, and Extracting .............................................................. 71            Traversing the Result Set ............................................................................. 72            Your Navigator Needs Directions ................................................................ 73Where to Go After the Navigator ............................................................................. 74                                  Contents in Detail ix
10                                    75IMPROVEMENT THROUGH INHERITANCEThe Standard PHP Library ........................................................................................ 76Extending a Class Through Inheritance ...................................................................... 76            The Exception Class ................................................................................... 77            protected ................................................................................................. 77            final ......................................................................................................... 78            More Magic Methods ................................................................................ 78Replacing Errors with Exceptions .............................................................................. 79The MySQLException Class ..................................................................................... 80Changes to the MySQLConnect Class ....................................................................... 81            Prodding Your Class into Action .................................................................. 82Catching Exceptions ............................................................................................... 83Implementing an Interface ....................................................................................... 84            Learning About the Iterator Interface ............................................................ 85            Implementation ......................................................................................... 86            Leaving a Method Undefined ...................................................................... 88            Implementation and Access ........................................................................ 88            Iterating Through a MySQLResultSet ............................................................ 89Where to Go from Here .......................................................................................... 8911                                    91ADVANCED OBJECT-ORIENTED PROGRAMMINGCONCEPTSAbstract Classes ..................................................................................................... 91            Private Methods Can’t Be Abstract .............................................................. 92            Interface or Pure Abstract Class? ................................................................. 92Polymorphism ........................................................................................................ 93            Controlling How Functions Are Used ........................................................... 93Static Classes ........................................................................................................ 94            Static Math Classes ................................................................................... 94            Instances of Static Classes .......................................................................... 95            Preventing Instantiation of a Static Class ....................................................... 96Design Patterns ...................................................................................................... 96            The Singleton Pattern ................................................................................. 96            Which Implementation? ............................................................................. 98Where to Go from Here .......................................................................................... 9812                                    99KEEPING IT FRESHSimpleXML .......................................................................................................... 100            XML ....................................................................................................... 100            RSS ....................................................................................................... 101            Structure of an RSS File ............................................................................ 101            Reading the Feed .................................................................................... 102Site-Specific Search .............................................................................................. 103            Google API ............................................................................................ 104            AJAX ..................................................................................................... 104            Installing SOAP ....................................................................................... 104x Contents in Detail
The SOAP Extension ................................................................................ 105            A SOAP Client ........................................................................................ 105            Testing the Functionality ........................................................................... 108            Viewing the Results Using AJAX ................................................................ 109Complex Tasks Made Easy .................................................................................... 110Would You Want to Do It Procedurally? .................................................................. 11013                            111MORE MAGIC METHODS__get and __set .................................................................................................... 112            Is It Worth It? .......................................................................................... 113__isset and __unset ............................................................................................... 113__call ................................................................................................................. 114__autoload .......................................................................................................... 115__sleep and __wakeup ......................................................................................... 116__clone ............................................................................................................... 116            Where’s Waldo? .................................................................................... 117            clone ..................................................................................................... 118            Aggregate Classes .................................................................................. 119            A Get Method for Object Data Members of an Aggregate Class .................. 121            No Clones Allowed ................................................................................. 122A Note About Overloading ................................................................................... 12214                            125CREATING DOCUMENTATION USINGTHE REFLECTION CLASSESWhat Are the Reflection Classes? ........................................................................... 126The Reflection Group of Classes ............................................................................. 126            The Reflection Class ................................................................................. 127            The ReflectionClass Class ......................................................................... 128            ReflectionMethod and ReflectionParameter ................................................. 129            Built-in Functions ...................................................................................... 129What Format Do You Want? ................................................................................. 130The Documenter Class .......................................................................................... 130            Describing the Documenter Class .............................................................. 130            Describing Methods and Data Members .................................................... 131            The Constructor ....................................................................................... 132            Method and Data Member Modifiers ......................................................... 132Using the Documenter Class .................................................................................. 134            Creating a Sidebar of Classes and Interfaces ............................................. 134            Formatting Detailed Documentation ........................................................... 134            Formatting Comments for the Documenter ................................................... 136Reflecting ............................................................................................................ 13715                            139EXTENDING SQLITEBrief Overview ..................................................................................................... 140Directory Structure ................................................................................................ 140                              Contents in Detail xi
How It’s Done ...................................................................................................... 141Getting Started .................................................................................................... 141Creating a Table .................................................................................................. 142Views ................................................................................................................. 143Triggers .............................................................................................................. 144PHP Implementation of SQLite ................................................................................ 145Extending SQLiteDatabase .................................................................................... 145Override the Query Methods ................................................................................. 146            Error Messages ....................................................................................... 147            Query Methods ....................................................................................... 148Utility Methods ..................................................................................................... 151            Getting Metadata .................................................................................... 152            Using Metadata ...................................................................................... 153User-Defined Functions .......................................................................................... 154Uses and Limitations of SQLite ............................................................................... 15616                                 157USING PDOPros and Cons ..................................................................................................... 158Converting the SQLite Application .......................................................................... 158            Code Changes ....................................................................................... 158Additional Capabilities of PDO .............................................................................. 161            The PDO Class ........................................................................................ 161            PDOStatement ........................................................................................ 161Assessment .......................................................................................................... 164            Is It the Holy Grail? .................................................................................. 164A                                  165SETTING UP PHP 5php.ini Settings .................................................................................................... 166            E_STRICT ................................................................................................ 167            Don’t Escape Twice ................................................................................. 168B                                  169CONVERSION TABLE: PHP 4 AND PHP 5GLOSSARY                           173INDEX                              179xii Con te nt s i n De ta il
ACKNOWLEDGMENTSSpecial thanks to my family for their support, encouragement, andforbearance; to the folks at No Starch for so deftly smoothing over therough edges; and lastly, thanks to Rasmus Lerdorf, creator of PHP.
INTRODUCTIONA number of years ago, before I started using PHP, Icreated dynamic web pages using C. This really wasn’ttoo different from some of the other options availableat the time, though it seems almost unthinkable now.Creating a dynamic page meant outputting HTMLfrom your script and recompiling that script if anychanges needed to be made. What PHP had to offer was the ability toembed server-side scripts into the body of a page wherever they were needed.This was a considerable improvement because it meant you could code theHTML as HTML and insert scripting when required. Introducing changeswas much easier, and since PHP is an interpreted language, there was noneed for recompilation.     The paths to using PHP are many and varied, but the single mostimportant reason for staying with it is ease of use. This is the major reasonthat PHP has become such a popular web programming language. With thearrival of version 5, PHP once again makes life simpler for web developers.You can now add the power of a robust but uncomplicated object-oriented(OO) language to your arsenal of web development tools.
What Does This Book Have to Offer?                      This book teaches OO PHP by doing it. If you are a PHP programmer who                      wants to make the switch to an OO approach, Object-Oriented PHP can ease                      the transition from procedural to object-oriented programming (OOP). Basic                      concepts are introduced using simple but useful classes. In short, this book:                           Brings together information from a variety of sources for a comprehen-                           sive overview of OO PHP                           Explains OO concepts through concrete examples, not in the abstract                           Takes a practical and easy-to-understand approach                           Demonstrates the advantages of OOP rather than just asserting them                           The classes developed in this book are fully functional and are all                      available for download at the companion website. This code can be put to                      work immediately in a variety of situations.                           The code takes full advantage of the capabilities of PHP 5 but, where                      possible, a PHP 4 version of the code is also provided, because you don’t                      always have a choice about where your code is deployed. Additionally, this                      will ease the transition for anyone already familiar with OOP under PHP 4.    Who Should Read This Book?                      This book will appeal to the developer who is familiar with PHP and wants to                      learn how to use its OO capabilities. However, programmers already familiar                      with an OO language, such as Java, who want to learn a scripting language will                      also find it useful. Additionally, if you are a system administrator who is consid-                      ering installing PHP 5, this book will help you make an informed decision.                           PHP is first and foremost a language for creating dynamic web pages, but                      the relative simplicity of OOP in PHP makes it an ideal language for a general                      introduction to OOP. The concepts learned here are applicable to any OO                      language, so if you want to get a feel for OOP, OO PHP is a good place to begin.                           Whatever your motivation, by the time you’ve finished this book you’ll                      have an excellent understanding of OOP and numerous classes that can                      easily be reused in a variety of circumstances. But, more importantly, you’ll                      be able to create your own classes and extend existing ones.    Requirements                      In order to get the maximum benefit from this book, there are software and                      skill prerequisites.                  Software                      With one or two minor exceptions (they are noted in the text), all the code                      in this book will run on PHP 5.0.4 and higher. The PHP 4 code will run just                      fine under PHP 5 but will issue warnings if error reporting is set to E_STRICT.                      (See Appendix A for more information about this new error reporting level.)xvi I n tr odu ct ion
PHP is available for virtually any operating system, so there are no                restrictions in this regard. As far as databases are concerned, any recent                version of MySQL, specifically versions 3 or higher, will do. Apache is the                preferred web server but Internet Information Server (IIS) can also be used.                (However, the acronym for Windows using IIS and MySQL with PHP may                serve to dissuade you from using this particular platform.)             Skills                Some knowledge of PHP is desirable, but barring that, a good understanding                of C-type syntax should get you through most code examples. Some knowl-                edge of (X)HTML and CSS is also assumed—after all, PHP is primarily a                web development language. You need only the most basic understanding                of XML even when working with the SimpleXMLElement or SOAPClient classes.                Some understanding of JavaScript would be beneficial.                      Familiarity with relational databases, especially MySQL, is recommended.Overview of Contents                OOP is often described as an iterative process, and this is the approach we                take in this book. We will develop working examples of classes in order to                explore specific OO concepts and then return to improve these classes.                      This book has sixteen chapters and two appendices. It is made up of                three different sections. The first three chapters offer an introduction to                OOP as implemented in PHP. Chapters 4 through 9 develop some useful                classes that demonstrate the basic syntax and concepts of OOP. Code com-                patible with PHP 4 and PHP 5 is provided. The remainder of the book                makes use of built-in classes available in PHP 5 only; consequently, there is                no PHP 4–compatible code. A brief outline of each chapter is provided here.                Chapter 1                Strangely enough, there are still web developers who question whether a                scripting language really needs to be object-oriented. This chapter deals with                issues related to this question.                Chapter 2                This chapter introduces the basics of OOP. The intent is not to exhaustively                cover the theoretical underpinnings of OOP—far from it. Think of this chap-                ter as a quick check for shallow water and rocks before diving in. The concepts                discussed are class, access modifiers, and inheritance—all you need to start                coding as quickly as possible.                Chapter 3                This chapter gives a broad overview of the changes introduced with PHP 5.                If you are new to PHP, it’s a good opportunity to assess the capabilities of the                language, but it should also appeal to the PHP 4 programmer who’s consid-                ering upgrading. This chapter also deals with some compatibility issues when                moving from version 4 to version 5.                                                                                                               Intr od uction xvii
Chapter 4                      Hands-on programming begins here. A relatively straightforward class is coded                      in the style of PHP 4. The most basic concept of OOP, a class, is introduced.                      Chapter 5                      The directory items class, created in Chapter 4, is upgraded to use the syntax                      of PHP 5. Further functionality is added to this class.                      Chapter 6                      This chapter creates a thumbnail image class for reducing images on the                      fly. This class is used in conjunction with the directory items class created in                      Chapter 5 to display images of a uniform size.                      Chapter 7                      After dealing with the size of images, the problem of displaying a large num-                      ber of images is addressed. A page navigator class is created in order to step                      through numerous images in an orderly fashion.                      Chapter 8                      Creating one class has lead to the creation of two other classes. This chapter                      demonstrates that these classes can work well in unison.                      Chapter 9                      Databases are an important element in most dynamic web pages. Creating                      our own MySQL database classes highlights the advantages of OOP in this                      area. Using the page navigator class in a different context demonstrates the                      reusability of OO code.                      Chapter 10                      Inheritance can improve the performance and ease of use of the MySQL                      database classes. Catching exceptions is cleaner and much less tedious than                      error trapping.                      Chapter 11                      In the interest of getting on with the coding, some advanced concepts of OOP                      were glossed over in Chapter 10. This chapter returns to some of the topics                      previously raised. It includes an in-depth discussion of abstract classes, inter-                      faces, and static classes. Design patterns and polymorphism are also examined.                      Chapter 12                      PHP is all about creating dynamic websites. So far we’ve seen how this can be                      done using databases. This chapter explores the creation of dynamic pages                      using the SimpleXMLElement and SOAPClient classes. This chapter also shows how                      asynchronous JavaScript and XML (AJAX) can work in unison with PHP. See                      just how easy it is to implement web services using classes built in to PHP 5.xviii Intro duc ti on
Chapter 13                This is one of the few non–project-oriented chapters. It explores in detail all                the magic methods available in PHP 5. Understanding these methods is                essential for getting the maximum benefit out of OO PHP and for avoiding                some common “gotchas.”                Chapter 14                PHP 5 includes a group of classes called the Reflection classes, typically used                to reverse engineer code. Pay a little attention to the format of internal docu-                mentation, and these classes can be used to make your code self-documenting.                Chapter 15                SQLite is packaged with PHP 5 and comes with an OO interface. This chapter                extends SQLite and develops a web-based resource management program.                No knowledge of SQLite is presupposed.                Chapter 16                PHP Data Object (PDO) is a data-access abstraction layer that works with most                databases. The application developed in Chapter 15 is converted to a PDO                application.                Appendix A                This appendix deals with OO issues related to the installation and config-                uration of PHP 5.                Appendix B                The major syntactic differences between PHP 4 and PHP 5 are presented                here in tabular form.Companion Website                This book has a companion website (http://objectorientedphp.com) where                you can download all the code related to it. Downloads are available as                zipped files or tarballs, chapter by chapter or as one complete download.                Code compatible with PHP 4 is clearly marked as such and, depending upon                your circumstances, may not need to be downloaded at all.                      The principle purpose of the companion site is to provide these down-                loads, but working examples of some of the classes created in this book are                also incorporated into the site. The DirectoryItems class is used to present the                downloads, and a page navigator is used in conjunction with MySQL classes                to page through a database of articles. Resources are added and displayed                using PDO and an SQLite database. Finally, documentation of internal PHP                classes is generated using the Documenter class. The companion website not                only provides support for this book, it is also a graphic demonstration of its                contents; to rephrase an expression, “the message becomes the medium.”                                                                                                                In t rod uc ti on xix
You can also post or review errata on the website, and links to many of                      the resources used in this book are provided.    Resources                      For your convenience, some of the most useful resources are reproduced here.                  Websites                      International PHP Magazine: www.phpmag.net                           Cutting-edge articles and news about PHP. Available by subscription only.                      PHP.net: http://php.net                           The official PHP site, where you will find documentation and many code                           examples. It is the primary source of information about PHP.                      php|architect: http://phparchitect.com                           A monthly magazine for PHP professionals. Available by subscription only.                      Planet PHP: www.planet-php.net                           Links to articles and all the latest news about PHP.                      Zend: www.zend.com                           Information about Zend products, but also many good tutorials by the                           creators of the scripting engine that underlies PHP.                  Books                      Essential PHP Security, by Chris Shiflett (O’Reilly)                      Learning XML, by Erik T. Ray (O’Reilly)                      PHP 5 Power Programming, by Andi Gutmans, Stig Bakken, and Derick                      Rethans (Prentice Hall)                      PHP Cookbook, by David Sklar and Adam Trachtenberg (O’Reilly)                      PHP Hacks, by Jack D. Herrington (O’Reilly)                      php|architect’s Guide to PHP Design Patterns, by Jason Sweat (php|architect)                      php|architect’s Guide to PHP Security, by Ilia Alshanetsky (php|architect)                      Programming PHP, by Kevin Tatroe, Peter MacIntyre, and Rasmus Lerdorf                      (O’Reilly)                      Thinking in Java, by Bruce Eckel (Prentice Hall)                      Upgrading to PHP 5, by Adam Trachtenberg (O’Reilly)xx In t rod uc ti on
1         WHAT A TANGLED WEB                     WE WEAVE               Creating a web page ain’t what it used to be.              Setting up a website today usually means            incorporating numerous technologies, among        them (X)HTML, CSS, JavaScript, SQL, and aserver-side scripting language. But that’s not all—a webpage also runs within a browser. There are several different browsers, of course,and each behaves differently. Not only that, but different versions of the samebrowser can act differently, and even the same version of the same browsercan’t be relied upon to behave the same when running on different operatingsystems, with different hardware, different screen resolutions, and so on.     Add to this the various configuration files—for the scripting languageand the web server, for example—which also affect the display of a particularweb page, and you can see that the web developer’s lot is not a happy one.     It may not be readily apparent that an object-oriented (OO) approach isa means of simplifying this situation. OO development might be seen assymptomatic of the larger problem. To the embattled web developer an OOapproach can appear to be just another complication of what’s already amessy business.
Do We Really Need Objects?                The ability of any server-side scripting language to “include” files within a web                page reduces initial work and ongoing maintenance. For instance, suppose a                website contains a menu at the top of each web page, and this menu is iden-                tical throughout the site. You could cut and paste the appropriate code into                every page, but this is both cumbersome and counterproductive. It’s much                better to write the code once and use a server-side scripting language to insert                the menu wherever it’s needed. That way, should an update be required, you                can make one change to one file rather than changing many files. This makes                site-wide updates much easier.                      You could summarize this approach as “include and reuse; don’t rewrite.”                In a sense, object-oriented programming (OOP) is just an extension of this                concept. Objects simplify web development by eliminating the need to cut,                paste, and adapt existing code. If the usefulness of OOP were this evident, it                would meet with little resistance. This has not been the case, however. Let’s                look at some of the more interesting objections to OO web development to                remove any nagging doubts you may have.             Just a Scripting Language                PHP is a scripting language. Some of the objections to OOP focus on this fact.                      Some scripting languages simply string together a series of commands                and for this reason are sometimes referred to as “glue.”1 A shell script, for                example, may combine a number of operating system commands in order                to eliminate the tedium of repetitively typing the same thing. The variety of                requirements of a web page might seem to support the view that PHP is just                this sort of scripting language—it provides a glue to hold together the dispa-                rate elements of a web page. If this is all that PHP does, then there is probably                no need for it to be object-oriented. In fact, object orientation might even be                a disadvantage. In this view, which is sometimes expressed with a degree of                condescension, OO capabilities are best left to full-blown programming lan-                guages and are an unnecessary encumbrance for a scripting language. An                OO scripting language is a contradiction in terms; it’s a language that’s                “getting above itself.”2                      To some extent, the limited OO capabilities of PHP 4 reinforced the                view that a scripting language shouldn’t attempt to be object-oriented. PHP 4                looked like a half-hearted attempt to jump on the OO bandwagon. Because                it was missing some of the major elements associated with OOP, it was easy                to dismiss OO PHP as a wannabe OO language. It simply lacked the tools of a                serious OO language. In light of the much-improved OO capabilities of PHP 5,                this view needs to be reassessed.             1 You’ll even find this description on the PHP site (http://php.net). In the FAQ on installation,             PHP is described as “the glue used to build cool web applications.”             2 For a recent variation on this argument see “James Gosling: Java Is Under No Serious Threat             from PHP, Ruby C#,” available at www.sys-con.tv/read/193146.htm. There, James Gosling argues             that “they are scripting languages and get their power through specialization: they just generate             web pages.” (Accessed March 19, 2006.)2 Chapter 1
Chapter 3 deals with the improvements to PHP’s object model in version 5.With these improvements, PHP is now a full-blown OO language. It should bejudged by how well it does the job, not on the basis of a preconceived notion ofwhat a scripting language should or shouldn’t do. After all, a programminglanguage, scripting or otherwise, is just a tool, a means to an end. Tools aremeant to be judged not by what they are, but by what they can do.Object Orientation Is for Large Software ShopsAnother argument against OOP goes like this: OOP is something best leftto the large shops. If a number of programmers are involved in the sameproject, an OO approach is a necessary evil, but it’s not much use for thelone developer. Because big software shops have many different program-mers doing somewhat specialized jobs, the modular, OO approach is required.It is not something that the lone developer needs to worry about. The lonedeveloper doesn’t have to coordinate his efforts with others, so a proceduralapproach is the better way.     This point of view correctly identifies the fact that an OO approach ismore modular and thus more suitable to an environment that requires col-laboration. It is also true that in some circumstances a single developer cando a superior job—too many cooks can spoil the broth. And it is probablyalso true that taking an OO approach will slow development. But an OOsolution takes more time than a procedural one only the first time that thesolution is created. The lone developer can benefit from the reusability andadaptability of an OO solution just like any large software shop can.Leave Well Enough AloneWe’ve dealt with some of the reasoned arguments against an OO approachto web development, but in many cases what’s at work is simply a reluctance tochange. PHP has been exceptionally successful as a procedural language. If itain’t broke, why fix it?     Computer languages, like their natural counterparts, must keep pace withchanges in the environment or risk becoming irrelevant. OOP doesn’t replaceprocedural programming or make it obsolete. Nor is an OO approach alwaysthe right approach, as some OO enthusiasts might have you believe. However,some web problems require an OO solution. Additionally, without a minimalunderstanding of the basics of OOP, you can’t make full use of the capabilitiesof PHP 5. For instance, if you want to create a SOAP client, there is really noother way to do it than by using the SOAPClient class.     There’s no requirement that once you start programming using an OOapproach you need always code this way. PHP is a hybrid language with OOcapabilities grafted onto it. You can use an OO approach when you want andotherwise revert to procedural programming.Increased ComplexityFear of PHP becoming overly complex is often a more subtly stated objec-tion to an OO PHP. There’s no doubt that OOP can sometimes introduce                                                                        What a Tangled Web We Weave 3
unwanted complexity—just look at multiple inheritance in C++ or Enterprise             Java, for example. This hasn’t happened with PHP, and there’s good reason             to suspect that it won’t. PHP is first and foremost a web development lan-             guage (which is probably why it has taken so long for PHP to adopt an OO             approach). Web programming is a specialized form of programming, and             OO capabilities have been introduced to serve this end. The fact that PHP’s             implementation of OOP doesn’t always make OO purists happy is indicative             of this. Even as a procedural language, PHP was never about being pretty or             being a model language; it has always been about solving web problems.                  A quick look at the culture of PHP should convince you that PHP is             unlikely to develop into an overly complex language.The PHP Culture             Culture is not something that is usually associated with a programming             language, but looking at the culture of PHP will help you understand PHP’s             implementation of OOP. PHP is an open-source language created more than             10 years ago by Rasmus Lerdorf. It has all the hallmarks of a successful open-             source project: It has been around for a number of years, it is continually being             upgraded, it has a robust developer community, and it has continuity of             leadership—Rasmus Lerdorf still takes a very active role in its development.                  PHP is by far the most popular web development language, and the             major reason for its success is ease of use. This is no accident. It is easy to use             because it was conceived as a language to simplify web development.3 This             has not been forgotten with PHP’s upgrade to a full-blown OO language.             For example, one of the new classes introduced in PHP 5 is the aptly named             SimpleXMLElement. With this class you can incorporate an RSS feed into a web             page using only four lines of code (see Chapter 12).                  The point of object orientation in PHP is not to turn PHP into Java or             something similar, but to provide the proper tools for web developers. Object             orientation is another strategy for adapting to the current circumstances of             web development.NOTE         The impetus to “Keep It Simple, Stupid” is alive and well (and, as it happens, living in             Paris). At a recent meeting of PHP core developers, the introduction of a new keyword             was rejected as “against the KISS approach of PHP” (minutes, PHP Developers Meet-             ing, Paris, November 11 and 12, 2005).                  Unquestionably, there will be a learning curve for a procedural program-             mer adopting an OO approach to web development, but you’ll quickly pick             up on PHP’s implementation of OOP. In fact, you’ll probably find that some             of the tasks you’re used to doing procedurally are more easily done in an OO             manner. I suspect that once you’ve started on the OO path, you’ll find more             and more uses for it.             3 See Rasmus Lerdorf, “Do You PHP?” available at www.oracle.com/technology/pub/articles/             php_experts/rasmus_php.html. (Accessed March 14, 2006.)4 Chapter 1
2  BASICS OF OBJECT-ORIENTED                PROGRAMMING               This chapter is aimed at an audience              unfamiliar with the basic concepts of            object-oriented programming (OOP).        The intent is to provide a general overview ofOOP with a view toward using PHP effectively. We’llrestrict the discussion to a few basic concepts of OOPas it relates to PHP, though it is sometimes useful tolook at other object-oriented (OO) languages such asJava or C++.     We’ll discuss three aspects of object orientation in this chapter: class, accessmodifiers, and inheritance. Although OOP may be a different programmingparadigm, in many respects it’s an extension of procedural programming, sowhere appropriate, I’ll use examples from procedural programming to helpexplain these concepts. Later chapters will return to the topics introducedhere and refine them through the use of concrete examples.
Class             You can’t have OOP without objects, and that’s what classes provide. At the             simplest level, a class is a data type. However, unlike primitive data types such             as an integer, a float, or a character, a class is a complex, user-defined data             type. A class is similar to a database record in that it encapsulates the char-             acteristics of an object. For example, the record of a Person might contain a             birth date, an address, a name, and a phone number. A class is a data type             made up of other data types that together describe an object.             Classes Versus Records             Although a class is like a record, an important difference is that classes con-             tain functions as well as different data types. And, when a function becomes             part of a data type, procedural programming is turned on its head, quite             literally, as you can see in the following example syntax. A function call that             looked like this:             function_call($somevariable);             looks something like this with OOP:             $somevariable->function_call();                  The significant difference here is that OO variables don’t have things             done to them; they do things. They are the actors rather than the acted upon,             and for this reason they are said to behave. The behavior of a class is the sum             of its functions.             A Cohesive Whole             Procedural programmers often work with code libraries. These libraries usually             group related functions together. For instance, all database functions might             be grouped together in a file called dbfunctions.inc. The functions that make             up an object’s behavior should also be related to one another, but in a much             stronger fashion than functions in the same library. Just as the different ele-             ments of a Person record describe an individual, so too should the behavior of             a class describe the class. In order for something to be an object, it should be a             cohesive whole incorporating appropriate characteristics and appropriate             behavior.             Objects Are Instances             Classes aren’t themselves objects, but a way of creating objects—they are             templates or blueprints that form the model for an object. When speaking             loosely, these two terms are sometimes used interchangeably, but strictly             speaking an object is an instance of a class. This is somewhat like the difference6 Chapter 2
between the concept of an integer and a specific variable $x with a specific                value. The concept of a class as a template for an object becomes clearer in                the context of inheritance, especially when we discuss multiple inheritance                (a topic we’ll deal with shortly).Objects Need Access Modifiers                OOP is made possible by using this simple concept of a class as a cohesive                aggregate of characteristics and behaviors—as you’ll see in Chapter 3, this is                exactly what objects are in PHP 4—but one of the most important features of                any OO language is the use of access modifiers. Access modifiers refine the object                model by controlling how an object is used or reused. Simply put, access modi-                fiers provide guidance about what you can and cannot do with an object.                To get a sense of what this means, let’s use an example from procedural                programming.                      Let’s define a subroutine as a function that is never invoked directly but                that is only called by other functions. Now suppose you’re a procedural pro-                grammer with a library of functions and subroutines that is used by several                other programmers. The ability to flag subroutines as secondary would be                helpful in instructing others how to use your library, but the only way to do                this is through documentation. However, in OOP, access modifiers not only                indicate the primacy of certain functions over others, they enforce it program-                matically. They implement language constraints to ensure that “subroutines”                are never called directly. Properly constructed classes are self-documenting                and self-regulating.                      In the situation just described, the need to document a code library arises                because it’s used in a collaborative environment; the exact same circum-                stance accounts for the existence of access modifiers. One of the assumptions                of OOP is that it is conducted within an interactive context with access modi-                fiers defining the ways of interacting. This is one of the important differences                between OOP and procedural programming. Access modifiers provide the                rules for using a class and this syntactically defined “etiquette” is commonly                referred to as an interface. By providing an interface, there is less need to rely                on documentation and on user programmers “doing the right thing.”                      Documenting code libraries is important because libraries get reused;                access modifiers matter for exactly the same reason—they facilitate reuse.Object Reuse and Inheritance                In a biological sense, a child inherits genes from its parents, and this genetic                material conditions the appearance and behavior of the child. In OOP the                meaning of inheritance is analogous—it is the ability to pass along charac-                teristics and behavior. At first this feature of OOP may seem somehow                magical, but really inheritance is just a technique for reusing code—much                the way you might include a library of functions in procedural programming.                                                                                     Basics of Object-Oriented Programming 7
If you identify an existing class that exactly suits your needs, you can             simply use it and benefit from the predefined behavior. Inheritance comes             into play when a class doesn’t do quite what you want. This situation is not             much different from adding functions to an existing code library. Through             inheritance you can take advantage of existing behavior but also graft on any             additional capabilities you need. For example, if you know that you want to             create a Blue jay class and none exists, you can use an existing Bird class by             inheriting from it, then modify it to suit your specific situation.                  When one class forms the basis for a new class, as a Bird class might for a             Blue jay class, the original class is often referred to as the base (or parent) class.             For obvious reasons, a class derived from another class is called a derived class             or a child class.             Multiple Inheritance             In nature, multiple inheritance is the norm, but in the world of OO PHP, an             object can have only one parent class. The creators of PHP 5 rejected the idea             of multiple inheritance for classes. To see why, let’s use the Bird class again to             show what multiple inheritance is and how it can lead to problems. If you             wanted to create a Whooping crane class, it would make sense to derive this             class from the Bird class. Suppose you also have an Endangered species class.             Multiple inheritance would allow you to create a Whooping crane class from a             combination of these two classes. This would seem to be an excellent idea             until you realize that both classes define an eating behavior. Which one should             you prefer? Awkward situations like this highlight the disadvantages of multiple             inheritance. With single inheritance this kind of situation never arises.             Having Your Cake and Eating It Too             Single inheritance offers a simpler and more straightforward approach, but             there are times when you may wish to combine behaviors from different classes.             A whooping crane is both a bird and endangered. It doesn’t make sense to             build one of these classes from scratch every time you want this combination.             Is there a way of combining different classes and avoiding the problem of             overlapping behavior?                  PHP solves this problem by introducing the concept of an interface. In             this context, interface means a class with no data members that is made up             only of functions that lack an implementation (function prototypes with no             bodies). Any class that inherits from an interface must implement the missing             function body. If Endangered species were an interface rather than a class,             having more than one eating function wouldn’t matter. The method defini-             tion in the Bird class would act as the implementation of the interface function.             In this way interfaces avoid the problem of defining the same function twice.NOTE         Because PHP does not require function prototyping, you may be unfamiliar with this             concept. A function prototype is the declaration of a function name and parameters             prior to its use—the function signature, if you like.8 Chapter 2
A class may inherit from only one class, but because interfaces lack an                implementation any number of them may be inherited. In true PHP fashion,                interfaces contribute to a powerful but flexible programming language.                (You’ll see how useful interfaces are in Chapter 10, where we add the                built-in interface Iterator to a database class.)                      Interfaces can be described as abstract because they always require an                implementation. Because they are abstract, interfaces bear more resemblance                to templates than classes do. Unlike classes, they can never be used “as is”;                they are only meaningful in the context of inheritance. Because interfaces lack                an implementation they can act only as a model for creating a derived class.Where to Go from Here                We’ve touched on three topics central to OOP: classes, access modifiers, and                inheritance. Classes define objects, access modifiers determine how objects                can be used, and inheritance makes it easy to adapt objects for different cir-                cumstances. I’ve emphasized the ways in which procedural programming is                like OOP with a view to easing the transition to an OO approach, but I’ve                also shown important differences. A data type like a class, which incorporates                functions, is unlike anything encountered in procedural programming. Addi-                tionally, OOP provides access modifiers to control how an object may be used.                Instead of relying on documentation and a disciplined approach, OOP                incorporates constraints into the language.                      The next chapter discusses the differences between PHP 4 and PHP 5.                This will be particularly useful for people already familiar with the OO capa-                bilities of PHP 4 who want an overview of the improvements.                                                                                     Basics of Object-Oriented Programming 9
3  OBJECT-ORIENTED FEATURES                 NEW TO PHP 5               PHP 3 was released in mid-1998. Some basic              object-oriented (OO) capabilities were            included, more or less as an afterthought,        to “provide new ways of accessing arrays.”1 Nosignificant changes were made to the object model whenversion 4 was released in mid-2000. The basics of object-oriented programming (OOP) were there—you couldcreate a class and single inheritance was supported.     With the release of PHP 5 in 2004 there was plenty of room for improv-ing PHP’s OO capabilities. At this point, Java, the most popular OO languageto date, had already been around for almost 10 years. Why did it take PHP solong to become a full-fledged OO language? The short answer is becausePHP is principally a web development language and the pressures of webdevelopment have only recently pushed it in this direction.1 See Zeev Suraski, “Object-Oriented Evolution of PHP,” available at www.devx.com/webdev/Article/10007/0/page/1. (Accessed March 27, 2006.)
Support for objects has been grafted onto the language—you can choose                to use objects or simply revert to procedural programming. That PHP is a                hybrid language should be viewed as something positive, not as a disadvantage.                There are some situations where you will simply want to insert a snippet                of PHP and other situations where you will want to make use of its OO                capabilities.                     As I have already argued in Chapter 1, in some cases, an OO solution is                the only solution. PHP 5 recognizes this fact and incorporates a full-blown                object model, consolidating PHP’s position as the top server-side scripting                language.                     Like Chapter 2, this will be a chapter of broad strokes. I’ll give a general                overview of how the object model has been improved, and then I’ll get into                the details using concrete examples in later chapters. I’ll also address the                issue of backward compatibility.Access Modifiers                Chapter 2 identified access modifiers as an essential element of an OO lan-                guage. PHP 5 gives us everything we would expect in this area. In previous                versions of PHP there was no support for data protection, meaning that all                elements of a class were publicly accessible. This lack of access modifiers was                probably the biggest disincentive to using objects in PHP 4.NOTE            A notion closely related to data protection is information hiding. Access modifiers                make information hiding possible by exposing an interface (as defined in Chapter 2).                This is also referred to as encapsulation of an object.Built-in Classes                Every OOP language comes with some built-in classes, and PHP is no excep-                tion. PHP 5 introduces the Standard PHP Library (SPL), which provides a                number of ready-made classes and interfaces. As of version 5.1, depending                upon how PHP is configured, all in all, there are well over 100 built-in classes                and interfaces—a healthy increase from the number available in version 5.0.                      Having ready-made objects speeds up development, and native classes                written in C offer significant performance advantages. Even if these built-in                classes don’t do exactly what you want, they can easily be extended to suit                your needs.     NOTE There are far too many classes for us to deal with all of them in this book, and some are                still not very well documented. We’ll focus on the classes that are especially noteworthy.                Exceptions                All OOP languages support exceptions, which are the OO way of handling                errors. In order to use exceptions, we need the keywords try, catch, and throw.                A try block encloses code that may cause an error. If an error occurs, it is12 Cha pt er 3
thrown and caught by a catch block. The advantage of exceptions over errorsis that exceptions can be handled centrally, making for much cleaner code.Exceptions also significantly reduce the amount of error-trapping code youneed to write, which offers welcome relief from an uninspiring task. Also, hav-ing a built-in exception class makes it very easy to create your own customizedexceptions through inheritance. (You’ll learn how to make the transitionfrom error trapping to exception handling in the section “Replacing Errorswith Exceptions” on page 79.)Database ClassesBecause PHP is all about building dynamic web pages, database support is all-important. PHP 5 introduces the mysqli (MySQL Improved) extension withsupport for the features of MySQL databases versions 4.1 and higher. Youcan now use features such as prepared statements with MySQL, and you cando so using the built-in OO interface. In fact, anything you can do procedur-ally can also be done with this interface.     SQLite is a database engine that is incorporated directly into PHP. It isnot a general-purpose database like MySQL, but it is an ideal solution insome situations, in many cases producing faster, leaner, and more versatileapplications. Again an entirely OO interface is provided.     PHP versions 5.1 and higher also bundle PHP Data Objects (PDO) withthe main PHP distribution. If you need to communicate with several differ-ent database back ends, then this package is the ideal solution. PDO’scommon interface for different database systems is only made possible bythe new object model.     Given the importance of databases, we’ll deal with them extensively inthis book. We’ll develop a MySQL database class starting with Chapter 9.In Chapter 15 we’ll look at SQLite, and in Chapter 16 we’ll discuss PDO.Web ServicesIn PHP 5 all Extensible Markup Language (XML) support is provided bythe libxml2 XML toolkit (www.xmlsoft.org). The underlying code for theSimple API for XML (SAX) and for the Document Object Model (DOM)has been rewritten, and DOM support has been brought in line with thestandard defined by the World Wide Web Consortium.     Unified treatment of XML under libxml2 makes for a more efficient andeasily maintained implementation. This is particularly important because sup-port for XML under PHP 4 is weak, and web services present many problemsthat require an OO approach.     Under PHP 4, creating a SOAP client and reading an RSS feed arechallenging programming tasks that require creating your own classes ormaking use of external classes such as NuSOAP (http://sourceforge.net/projects/nusoap). There’s no such need in PHP 5. In Chapter 12, you’llsee just how easy these tasks are using the built-in SOAPClient class andSimpleXMLElement. Again it’s the improved object model that makes thispossible.                                                                O bj ect -O r ien t ed Fea t ure s Ne w t o P HP 5 13
Reflection Classes                The reflection classes included in PHP 5 provide ways to introspect objects                and reverse engineer code. The average web developer might be tempted                to ignore these classes, but Chapter 14 shows how useful they are for auto-                mating a task that most developers approach with little enthusiasm: the                creation of documentation.                Iterator                In addition to built-in classes, PHP 5 also offers built-in interfaces. Iterator is                the most important, as a number of classes and interfaces are derived from                this interface. I’ll show you how to use Iterator in Chapter 10.Backward Compatibility                Backward compatibility may be an issue if your code already uses objects.                PHP 5 introduces a number of new “magic” methods. Magic methods begin                with a double underscore, and this requires changing any user-defined meth-                ods or functions that use this naming convention. All of these methods will                be discussed, particularly in Chapter 13. The most important ones relate to                how objects are created and destroyed. The PHP 4 style of object creation                is still supported, but you are encouraged to use the new magic method                approach.                      PHP 5 deprecates some existing object-related functions. For example,                is_a has been replaced by a new operator, instanceof (see Chapter 14). This                particular change won’t affect how your code runs under PHP 5. If you use a                deprecated function, you’ll see a warning if the error-reporting level is set to                E_STRICT (a useful technique for discovering where your code may need upgrad-                ing and discussed in more detail in Appendix A). In another example, the                get_parent_class, get_class, and get_class_methods functions now return a case-                sensitive result (though they don’t require a case-sensitive parameter), so if                you are using the returned result in a case-sensitive comparison you will have                to make changes.                Pass By Reference                The preceding examples of changes are relatively minor and fairly easy to                detect and upgrade. However, there is one change in particular that is of an                entirely different magnitude.                     The major change to PHP in version 5 relating to OOP is usually summed                up by saying that objects are now passed by reference. This is true enough,                but don’t let this mask what’s really at issue: a change in the way that the                assignment operator works when used with objects.                     Granted, the assignment operator is often invoked indirectly when                an object is passed to a function or method, but objects are now passed by                reference because of the implicit assignment. Prior to PHP 5, the default                behavior was to assign objects by value and pass them to functions by value.14 Cha pt er 3
This is perfectly acceptable behavior for primitives, but it incurs far too much      overhead with objects. Making a copy of a large object by passing it by value      can put strains on memory and in most cases, all that’s wanted is a reference      to the original object rather than a copy. Changing the function of the assign-      ment operator is a fairly significant change. In fact, the scripting engine      that underlies PHP, the Zend engine, was entirely rewritten for PHP 5.NOTE  In PHP 4 it’s possible to pass objects by reference using the reference operator (&), and in      fact it is good programming practice to do so. Needless to say, this use of the reference      operator becomes entirely superfluous after upgrading to PHP 5. We’ll discuss the      implications of this change in Chapter 13, in the section “__clone” on page 116.      Prognosis      The mere enumeration of the details of backward compatibility masks what      can be a highly charged issue. Whenever you change an established language,      there are competing interests. In many cases you’re damned if you do and      damned if you don’t. For example, retaining inconsistent function naming      conventions may be necessary to maintain backward compatibility, but you      may also be criticized for this very lack of consistency.           Of course, breaking backward compatibility means that some existing      code won’t function properly. In many circumstances it’s not easy to decide      where and when to break backward compatibility, but changing PHP to pass      objects by reference is a fairly defensible change despite any inconveniences.      The only thing you can be sure of is that any change will give rise to complaints      in some quarter. Certainly, having deprecated functions issue warnings is      one good way to give advance notice and let developers prepare for coming      changes.Where to Go from Here                If you’ve bought this book and read this far you’re obviously interested in                OOP. If you know PHP already, then learning OO PHP will not be too                difficult. Given the relative simplicity of PHP’s object model, certainly less                effort is required than for a C programmer to learn C++. Nevertheless, mov-                ing to a new language or a new version of a language entails some cost in                terms of time and effort, especially if it has an impact on your existing code                libraries.                      We’ve covered some of the backward compatibility issues as they relate to                OOP. Almost all procedural code will run with no changes under PHP 5. No                rewrites are required, and code does not need to be converted to an OO style.                      Upgrading existing applications to take advantage of PHP 5 is a different                matter. In the case of some large applications, upgrading may require sig-                nificant effort. Many applications will benefit by being upgraded. If you’ve                ever tried to customize software such as phpBB (the popular open-source                forum), you know that the task would be much simpler if the application was                object-oriented. However, upgrading an application such as phpBB means                beginning again from scratch.                                                                                   O bj ect -O r ien t ed Fea t ure s Ne w t o P HP 5 15
And there are other considerations besides code compatibility. After                learning the ins and outs of OOP with PHP 5, will you actually be able to                make use of it? Are there actually servers out there running PHP 5?                Adoption of PHP 5                As of this writing PHP 5 is hardly a bleeding-edge technology. It has been                available for more than a year, and there have been a number of bug fixes.                It’s a stable product. Where developers have control over web server config-                uration there’s no question that upgrading to PHP 5 will be beneficial. But                developers don’t always have a choice in this matter. In some situations                (where the developer has no control of the web host, for instance), the                decision to upgrade is in someone else’s hands.                     PHP is a victim of its own success. The popularity and stability of PHP 4                have slowed the adoption of PHP 5. PHP 4 is a mature language that supports                many applications, open-source and otherwise. There’s naturally a reluctance                to rock the boat. For this reason the adoption of PHP 5 has been somewhat                slow, especially in shared hosting environments.NOTE            Other web hosting options have been much quicker to adopt PHP 5. The various virtual                private server (VPS) hosting options usually include PHP 5, as do dedicated hosts.                As a more secure and increasingly inexpensive hosting option, VPS is becoming much                more popular.                Compromise                Widespread adoption of PHP 5 will happen sooner or later, but this book                recognizes that developers may need, at least for a time, to continue writing                new applications that will run under PHP 4. For this reason, wherever possible,                a PHP 4 version of code has been provided in addition to the PHP 5 version.                     In a sense, PHP 5 just formalizes what was already possible in PHP 4.                For instance, even though PHP 4 allows direct access to instance variables,                when creating a class in PHP 4 it makes sense to write accessor methods                for variables rather than setting or retrieving them directly. This requires a                disciplined approach, but it will yield code that not only runs under PHP 4                but also will be much easier to upgrade to PHP 5. Adding restrictive access                modifiers to variables will be a relatively simple task if accessor methods are                already in place. Writing code with the expectation of upgrading it will also                invariably mean writing better code.                     That’s all the talk about OOP. In the remaining chapters you’re going                to do OOP.16 Cha pt er 3
4         SHOW A LITTLE CLASS               Introductory books on object-oriented              programming (OOP) often use examples            of objects taken from the real world. For      example, you may be asked to imagine a “dog”class. We are all familiar with dogs, of course, so it’srelatively easy to describe a dog’s attributes. Most dogs have hair, four legs,and a tail. A dog’s behavior is equally easy to describe. Dogs bark, jump, run,roll over, dig, and, when passing fire hydrants . . .     I don’t mean to belittle this approach, but the objects that a web developerdeals with are not often objects “out there” that one can point to. They aremore likely to be conceptual rather than physical objects, and these are alittle harder to identify. Once identified, it is not easy to describe the objects’attributes and behavior.     With that in mind, the class I propose you create is a list of files. (I know,it’s not terribly exciting, but by keeping things simple, we can easily deal withsome of the basic concepts of OOP.) This class certainly won’t bark or jump,but by the time we’re finished, it may roll over and do a few tricks.
NOTE  We’ll use the syntax of PHP 4 to help ease into OOP. Starting with PHP 4 will also be      helpful for those who have already used OOP with PHP and want to upgrade their      code. I’ll show you how to do this in Chapter 5, and for convenience, I have also      included an appendix on this topic. (PHP 4 style code will run just fine under PHP 5      but will raise warnings if error reporting is set to E_STRICT in the php.ini file. See      Appendix A for the OO configuration options of the php.ini file.)    Design                      OOP doesn’t eliminate the need for systems analysis. It’s easy to forget about                      this step and to just start coding, especially when dealing with a fairly simple                      task. However, a little forethought during the design stage will reap benefits                      later on, so make sure you have a clear idea of what you want to do.                  Defining the Problem                      You often need to look at and manipulate the files in a specific directory, and                      you often want to do this with directories that hold resources such as photos                      or images, .pdf files, or files that are compressed for downloading. Probably                      the simplest approach, if your web server is Apache, is not to use any code at                      all and simply put a .htaccess file containing the directive Options +Indexes                      into the appropriate directory.                           By using a .htaccess file, you can simply point your browser to the                      directory that contains this file to see a list of its contents. Of course, if this                      were your only goal, then building a class to mimic this functionality would                      be entirely superfluous. However, you want to do a bit more than just list                      files. You want to have control over the order in which they appear and the                      file types that are listed, and you may also want to know the number of files.                           Consider this fairly specific task: Suppose you have some cleanup work                      that needs doing on directories that contain graphics. You need to remove                      deadwood, but before you can do so, you need to view the images. Rather than                      open each picture individually using an application such as Photoshop or                      GIMP, you want to open all the files at once in your browser. Not only do you                      want to see the image, you also want to note the filename of the image                      in case you decide to remove it.                           This is not a situation that requires an object-oriented (OO) solution. If                      you are familiar with PHP, you’ve probably already formulated a rough algo-                      rithm of how to solve this problem and determined which functions you                      need to use.                           If you are a programmer but not familiar with OOP, a procedural                      approach will doubtless seem more natural and be easier to execute, especially                      when approaching a straightforward problem. However, remember that we                      are deliberately trying to keep things simple to begin with. Stick with me at                      least until the end of the next chapter—you won’t be disappointed.                           At this early stage, our simple class may not convince you of the utility of                      OOP, but it will highlight the fact that OOP doesn’t do away with the need                      for procedural programming. The logic required for OOP is every bit as pro-                      cedural as the functions you’re used to creating and using.18 Cha pt er 4
Not the Da Vinci Code                We’ll reproduce the code here and intersperse it with comments. (If you                would like an overview of the entire class, now would be a good time to                download the code for this chapter from the companion website at http://                objectorientedphp.com.)                      In order to create a class, use the keyword class and an appropriate name:                   class DirectoryItems{ ... }                      Braces enclose all the elements of a class, indicated by the ellipsis in the                preceding line of code.                      We discussed the concept of a class in Chapters 2 and 3, but a bit of repeti-                tion here won’t be amiss. In its simplest form, a class can simply encapsulate a                variety of data types, the way a struct does in C or a type in Visual Basic. This                class will encapsulate data types, but it will also contain functions or methods.                      Like PHP’s built-in classes, we’ll use Java-style naming conventions for                the class name—not underscores, but uppercase letters for the start of each                word, otherwise known as studly caps. We’ll use the same naming convention                for files that contain class definitions. For example, the file that holds the                DirectoryItems class will be called DirectoryItems.php. This naming convention                is not a requirement but helps readily identify classes and their files.                      The first statement inside the class is the declaration of the variable                $filearray. Upon declaration, this variable is initialized as an array.                   var $filearray = array();NOTE  Notice the use of the var keyword. This syntax will be replaced in PHP 5, but here it      simply denotes an instance variable.           Any variable declared at this level, namely inside the braces that enclose      the class but outside any class function, is an instance variable or, as we might      also refer to it, a data member. (In most cases, classes contain more than one      data member, but one is sufficient for the moment.) Instance variables are      sometimes also referred to as properties. The placement of instance variables      outside of any function indicates that they have scope throughout the class.      Their visibility is not restricted to any specific function—they can be accessed      from anywhere within the class. You could say they are global to the class.      The Constructor      Next is a function that bears the same name as the class: the constructor.      Constructors are commonly used to initialize data members, and as in      Listing 4-1, filenames are added to the instance variable $filearray.      function DirectoryItems( $directory){            $d = \"\";            if(is_dir($directory)){                  $d = opendir($directory) or die(\"Couldn't open directory.\");                                                                                            Sh ow a L it t le Cla ss 19
while(false !== ($f=readdir($d))){                                if(is_file(\"$directory/$f\")){                                       $this-> filearray[] = $f;                                }                            }                            closedir($d);                      }else{                         //error                            die(\"Must pass in a directory.\");                      }                }                Listing 4-1: The DirectoryItems constructor                     Constructors are called whenever an object is created. In Listing 4-1, the                constructor accepts, as a parameter, a string variable of a directory name.                Any files contained within this directory are added to $filearray.                Referencing Instance Variables                The only remarkable thing about this code is the unusual syntax required to                refer to the instance variable. Variables such as $d and $f, which are local to                the constructor, are referenced in the same way as any other PHP variable,                but when using $filearray, we must precede it with $this->.                     If you’re familiar with other OO languages such as C++ or Java, you’ll be                familiar with $this, a “pseudo-variable” that identifies what follows as an                instance variable. However, unlike those other OO languages, use of $this                when referring to an instance variable is not optional in PHP.                     So much for the explanation of the syntax of the constructor. The                constructor actually performs a fairly simple and straightforward program-                ming task.                Wrapper Methods                The rest of the class is made up of a series of functions. Some of these func-                tions simply enclose or wrap existing array-related functions and are called                wrapper functions. These wrapper functions count or sort the list of filenames,                but instead of calling them functions, let’s use OO terminology and refer to                them as methods.NOTE            When declaring the methods of a class you are required to use the keyword function.                This can perhaps lead to some confusion. However, throughout we will use the term                method to distinguish between a regular function call and the calling a class function.                     Again, following the studly caps naming convention, if a method name                is a compound word, use lowercase for the first word and uppercase for any                subsequent words. Listing 4-2 includes three methods that use built-in PHP                array functions.20 Cha pt er 4
function indexOrder(){                         sort($this->filearray);                   }                   ////////////////////////////////////////////////////////////////////                   function naturalCaseInsensitiveOrder(){                         natcasesort($this->filearray);                   }                   ////////////////////////////////////////////////////////////////////                   function getCount(){                         return count($this->filearray);                   }                   Listing 4-2: Wrapper methods                      Finally, add one final method to check that files are all images:                   function checkAllImages(){                         $bln = true;                         $extension = \"\";                         $types = array( \"jpg\", \"jpeg\", \"gif\", \"png\");                         foreach ($this->filearray as $key => $value){                               $extension = substr($value,(strpos($value, \".\") + 1));                               $extension = strtolower($extension);                               if(!in_array($extension, $types)){                                     $bln = false;                                     break;                               }                         }                         return $bln;                   }                   Listing 4-3: A method to select only images                      The checkAllImages method loops through each element in the file array,                extracts the extension, and checks that it is one of the acceptable file types.                      In sum, the DirectoryItems class is made up of one data member, a special                function called a constructor, and four other functions or methods. As already                noted, you should save this file as DirectoryItems.php.Creating an Instance                A class by itself is of absolutely no use whatsoever, and if you preview in a                browser the code created so far, nothing will be displayed. That’s because at                this point we don’t really have anything—just the idea for something. We                need to create an instance of the class.                      The many Platonists amongst you will immediately know what we’re                talking about. Remember Plato and “ideal forms?” Of course you do—it                hasn’t been that long since you took Philosophy 101. The explanation of a                form usually involved a chair, because there was always one in the classroom.                The form of a chair doesn’t exist anywhere, but any specific chair embodies                                                                                                         Sh ow a L it t le Cla ss 21
that form. In other words, each particular chair is an instantiation of the chair                class. (If you skipped that lecture, we could say that a class acts as a template                for a specific occurrence of a class in much the way that a building relates to                its blueprint.)                     Listing 4-4 is a PHP page that creates an instance of the DirectoryItems                class. Briefly, this web page opens a directory immediately below the current                working directory, checks that all the files in that directory are graphics files,                sorts them in a case-insensitive way, and then displays them.                <html>                <head>                <title>Images</title>                </head>                <body>                <?php                require 'DirectoryItems.php';                $di =& new DirectoryItems('graphics');                $di->checkAllImages() or die(\"Not all files are images.\");                $di-> naturalCaseInsensitiveOrder();                //get array                echo \"<div style = \\"text-align:center;\\">\";                foreach ($di-> filearray as $key => $value){                    echo \"<img src=\\"graphics/$value\\" /><br />\n\";                }                echo \"</div><br />\";                ?>                </body>                </html>                Listing 4-4: Creating an instance of the DirectoryItems class                     Since we are going to create an instance of the DirectoryItems class, we                need to include this class by requiring the file that holds the class defini-                tion, namely the file saved as DirectoryItems.php. We create the class instance                with the code, $di =& new DirectoryItems('graphics');, where $di is the variable                or instance of the object, and new both allocates memory and, in association                with the class name, invokes the constructor. (When creating an object under                PHP 4, it is advisable to return a reference using the assignment by reference                operator, =&. The reason for this is discussed in detail in Chapter 13, in the                section “__clone” on page 116.)                     The constructor for the DirectoryItems class expects a directory name to                be passed in. In this case, use graphics, which is assumed to be a directory                immediately below the current directory. If the constructor cannot locate this                directory, construction fails and the program terminates. But if it’s successful,                an array of filenames is created.                     In this particular case we want to ensure that all the files in the graphics                directory are images. After all, we’re going to use this class to set the src                attribute of an img tag. The checkAllImages method does this work by looking                at filename extensions. The arrow operator we saw when using the pseudo-                variable $this, reappears here when we want to call an object method:                $di->checkAllImages().22 Cha pt er 4
Calling an object method is similar to calling a function in procedural                programming. However, instead of passing a variable to a function as is                commonly done, a class method is called on a variable, or more properly                speaking, an object or instance of a class. This is how objects may be said                to behave: they do things rather than having things done to them.                      Next, perform a case-insensitive sort of the filenames. Directly access                the data member, $filearray, and iterate through this array to display each                image.                      As you can see, we’ve created a class and used it to accomplish exactly                what we set out to do.What Have You Accomplished?                Using the syntax of PHP 4, you have created a class to assist in the display                of images in a web page. It is a fairly simple class, and it should be readily                apparent how the same job could be done procedurally.                      However, despite the simplicity of the class and of the task it performs,                there are some obvious advantages. On the plus side, you could say the                HTML page is fairly clean—the somewhat messy task of determining if all                files are image files has been hidden away inside the class file. Additionally,                if you want to reuse this code, you won’t have to cut and paste the way you                so often do with procedural programming; you need only use the require                directive with the class filename, and away you go.                      But would you want to reuse this class? Skeptics might say that we’ve                come the long way around and built a class to solve a specific problem, but                that we could have achieved the same effect more quickly using procedural                programming. Additionally, they might argue that this class is just an ad hoc                solution not easily reused elsewhere.                      There may be some truth to these criticisms; certainly the more a class is                tied to the specifics of a situation, the less reusable it is. However, remember                that we set out to create a fairly simple class with the intention of elucidating                some of the basics of OO programming. At this point we only have a fledg-                ling class that requires more nurturing.But Will It Fly?                OO enthusiasts are usually eager to point out the big ways in which OOP is                superior to procedural programming, through capabilities such as inheri-                tance, for instance. True enough, but probably of more importance is the fact                that once you have a class, providing that the basic design is sound, you can                easily add to its functionality. If it doesn’t do something you want it to do, the                simplest and often the best solution is to add a method to create additional                behavior.                      For example, you could easily add a method modeled on the method                checkAllImages that would check for other types of files. Or, suppose some of                the files in the directory passed to the constructor are not image files, and                you don’t want your program to attempt to display them. This could be                                                                                                         Sh ow a L it t le Cla ss 23
remedied with a filter method. I’m sure you can think of other ways in which                      this class can be improved. The next chapter will improve on this class so that                      it can be used in a variety of ways, but the focus will be on its use with a direc-                      tory of image files.                           Furthermore, some of the shortcomings of this class suggest the creation                      of additional classes rather than additions to the DirectoryItems class. First,                      images are of varying sizes. This not only affects the aesthetics of a web page,                      but, if the images are large, this can significantly slow the rate at which a                      page downloads. Second, if there are a considerable number of files in one                      directory, a single web page that displays all of them will be unacceptably long.                      In later chapters we’ll follow up on both of these ideas.                           At the beginning of this chapter I promised that we wouldn’t create a                      dog class, and perhaps instead, we’ve created an ugly duckling. In any case,                      you’ll want to stick around for another chapter not only to see if our fledgling                      can fly but also to see whether our ugly duckling turns into a swan.24 Cha pt er 4
5                MOD UR CLASS               Chapter 4 left us with some clear objec-              tives. We need to add functionality to the            DirectoryItems class, and we need to upgrade it      to take advantage of the changes introduced inPHP 5. And that’s exactly what we’ll do in this chapter.We’ll upgrade the syntax of the DirectoryItems classfirst; then we’ll improve its functionality by addingmethods.     Keeping in mind that we plan to use the DirectoryItems class to displayimages, we’ll add a method that ignores all non-image files, so we don’t needto worry if other file types occur within a directory containing mostly images.We’ll also broaden the scope of the class so that we can filter the contents ofa directory and focus on a specific file type.
Upgrading to PHP 5                      As you’re aware, the major change to PHP with version 5 is improved support                      for OOP. In this regard, two of the most important changes are the introduc-                      tion of access modifiers and changed syntax for class construction. Both of                      these changes will have an impact on the DirectoryItems class.                  Access Modifiers                      Next to the concept of a class, access modifiers are arguably the most important                      feature of an OO language. The principal use of access modifiers is to describe                      and constrain data members and methods. The access modifiers we are con-                      cerned with in this chapter are public and private. The modifier private is                      used to modify or describe matters relating to the internal behavior of a class.                      The modifier public is used to describe the external behavior of a class or, if                      you prefer, a class’s interface.                           As far as syntactic changes to the DirectoryItems class are concerned, this                      means replacing the keyword var with private, so that                         var $filearray = array();                      becomes                         private $filearray = array();                           As you’ll recall, $filearray is the sole data member of the DirectoryItems                      class. In most cases (except static classes, which we will discuss in Chapter 11),                      you should make all data members private, because by doing so, you are                      protecting the integrity of your data by restricting access to it.                           To better understand access modifiers, it’s useful to think of data                      members or instance variables as though they are data in a database. In order                      to maintain the integrity of the data in a database, it’s wise to limit access and                      restrict the ways in which data can be added or changed. A programmer might                      well write an application to achieve this result, requiring users to log in and                      implementing controls on the way in which data are formatted. For instance,                      you may want dates stored in a particular format and enforce this through                      the use of a masked textbox.                           Since access modifiers are nonexistent in PHP 4, changing the value                      of a variable only requires a simple assignment. You could modify the                      $filearray variable in the following way:                         $di->filearray[0] = \"anyfile.jpg\";                           It’s a disadvantage to do things this way because changes to $filearray                      are not controlled and allowing direct access to data members greatly increases                      the risk of contaminating your data. If you use the keyword private, direct                      access is no longer possible.26 Cha pt er 5
NOTE  In terms of the preceding database analogy, making an instance variable private      means that access to the data is only permitted through use of the programmer’s      application or front end.           But wait, it’s your code, right? You won’t change it improperly, so why      should you care? Because OO programming assumes that other programmers      may use your objects and vice versa.           Bruce Eckel refers to this as client programmers using objects created by      class creators.1 Even if you are a lone developer and don’t expect other pro-      grammers to use your code, access modifiers are still an important safeguard.      Why? How many times have you returned to your own code, even after only a      short period of time away from it, and had trouble trying to figure out what      exactly you were trying to achieve? Clearly, in this situation, even though      you are the class originator, you are also, at the same time, a client pro-      grammer. The use of access modifiers forces the programmer to make his      or her intentions explicit. If a particular data member or method relates to      the internal behavior of a class, then applying the appropriate access modifier      documents this intention. If nothing else, we all need access modifiers to      protect our code from that most presumptuous of client programmers—      ourselves.           When first encountering the private keyword, there is sometimes a mis-      taken tendency to view it solely as a security measure and then point out its      ineffectiveness by showing how easily a malicious user programmer could      subvert it. Even more so with a non-compiled language like PHP, because      it’s an easy matter to change a modifier from private to public. It’s better to      view the use of access modifiers as indicative of the originating program-      mer’s intentions—as a form of internal documentation. (However, the use      of access modifiers does add to security insofar as any well thought out and      well documented class is a more secure class.)           The private keyword can be applied to methods as well as to data      members. You’ll see an example of a private method later in this chapter,      but for the moment, let’s look at the use of the modifier public when applied      to a method.           Once the need for the keyword private is apparent, so also is the need for      a public method or interface so that private data members may be accessed      in a controlled fashion. Now that the $filearray variable is private, you no      longer have any kind of access to it. For this reason, you need a public method,      sometimes called an accessor method, in order to retrieve that private variable:      public function getFileArray(){            return $this->filearray      }           In the previous chapter, you directly accessed this data member thus:      $di->filearray. You might well wonder what the difference is and conclude      that direct access is preferable because it is more succinct. However, the impor-      tant difference is that when you directly access a data member, you are working      1 Bruce Eckel, Thinking in Java (Prentice Hall, 1998), 30.                                                                  Mod UR Cla ss 27
with the original, but when you use a method to retrieve a data member, you                retrieve a copy of that original. When working directly with the original, you                risk changing its value, inadvertently or otherwise. When working with a copy,                there is no such danger because, should the copy be changed, the original                will remain intact. In other words, what’s returned from the getFileArray                method is returned by value, not by reference. Changing the copy won’t                have any effect on the original.                     It is perhaps clearer now how a public method is an interface. A public                method mediates between a data member and a user programmer in the                same way that the front end of a database mediates between a user and the                data. Controlled access to the data simplifies how a class is used and, in so                doing, helps preserve its integrity.                The Constructor                In Chapter 4, you saw how the class name functioned as a special method                called the constructor. However, PHP 5 changes the way that objects are                constructed. Specifically,                function DirectoryItems($directory){ ... }                becomes                public function __construct($directory){ ... }                     Methods beginning with a double underscore are magic methods. They                are given this name because they are not (usually) called directly. This new                method for constructing objects is invoked in exactly the same way as a con-                structor is invoked under PHP 4. Creating an instance of the DirectoryItems                class still uses the keyword new along with the class name:                $di = new DirectoryItems(\"graphics\");NOTE                 The syntax for creating an object is the same, but in PHP 5, the __constructNOTE            method is executed rather than a method bearing the class name.                In PHP 5, you need not return the object created by the constructor (or any method for                that matter) by reference. The reason for this is explained in Chapter 13 in the section                “__clone” on page 116.                     Altering the constructor may seem like an unnecessary change to those                of you familiar with constructors in other OO languages, but there are advan-                tages that you’ll see when we discuss inheritance. Without getting into the                details of inheritance at this early stage, let’s just say that having a fixed name                for the constructor in every class allows you to avoid hard-coding class names                unnecessarily. This in turn will of course make your code easier to maintain.                The access modifier public is optional when applied to a constructor (or any other                method, for that matter), but it certainly doesn’t hurt to use it. You may still create a                constructor using the class name, but adopting the style of PHP 5 now will avoid any                future backward-compatibility issues.28 Cha pt er 5
Modifying Your Class                You’ve upgraded the syntax of your code to PHP 5 standards, but you still                need to improve the functionality of your DirectoryItems class. This involves                rewriting the constructor to make it do a bit more work and adding more                methods to the class. The additional methods will improve the flexibility of                the class by filtering for specific file types.             Reconstructing the Constructor                Currently, the constructor for the DirectoryItems class uses an array to keep                track of filenames. The underutilization of the capabilities of an array suggest                changes to the constructor.                      Arrays in PHP are very flexible—they can be either numerical or associa-                tive. The current constructor simply stores the filenames in a numeric array,                but if you change this to an associative array, you can make better use of the                data member $filearray. Since all operating systems require that each filename                within a directory be unique, the filename is ideal for acting as a key in an                associative array. Let’s see how you might take advantage of this.                      When properly ordered and created, a directory and its subdirectories                can function like a database and its tables; in fact, for some databases, a table                is a directory and its contents.                      If you consider the DirectoryItems class as a table and the files in the array                as “records,” then, if you set things up in just the right way, filenames can                function as the “title” field for each file in that database.                      You can implement this by using a strict naming convention for all your                files. For example, if all your files are formatted using underscores to separate                words (Lady_of_Shallott.jpg, for instance), then by replacing underscores                with spaces and stripping out filename extensions, the filename alone can                serve as the title for each image when it is displayed.                      I won’t reproduce the original code for the constructor here, but look                back at Chapter 4 if you need to refresh your memory. The code for the new                constructor and a private method called from within the constructor is                shown in Listing 5-1.                   public function __construct($directory, $replacechar = \"_\"){                         $this->directory = $directory;                         $this-> replacechar=$replacechar;                         $d = \"\";                         if(is_dir($directory)){                                     $d = opendir($directory) or die(\"Failed to open directory.\");                                     while(false !== ($f=readdir($d))){                                                  if(is_file(\"$directory/$f\")){                                                  $title = $this-> createTitle($f);                                                  $this->filearray[$f] = $title;                                                  }                                     }                                     closedir($d);                         }else{                                     //error                                                                                                              Mod UR Cla ss 29
die(\"Must pass in a directory.\");                                      }                         }                            private function createTitle($title){                                //strip extension                                $title = substr($title,0,strrpos($title, \".\"));                                //replace word separator                                $title = str_replace($this->replacechar,\" \",$title);                                return $title;                         }                         Listing 5-1: The constructor and the createTitle method                           The original constructor for this class accepted only one parameter—a                      directory name. You are now passing an additional parameter, $replacechar,                      and it has a default value of “_”. This parameter will function as the character                      in a filename and will be replaced by a space in order to make a readable,                      English “title” from the filename.                           By assigning a default value to $replacechar, users of the DirectoryItems                      class have three options. They can:                      1. Use another replacement character by passing a second value to the                           constructor (a hyphen, perhaps)                      2. Let the second value default to an underscore                      3. Simply ignore the existence of this parameter (if they don’t want to use                           a title)                           Next, you copy the character used as a word separator into an instance                      variable, because you need to reference it not only in the constructor but                      also in the createTitle method.                           In the original version of this class, you did not need to keep track of                      the directory name passed to the constructor because once it was used in the                      constructor, it was no longer needed. Because you intend to filter filenames,                      you now need to preserve the directory name, so you copy it into an instance                      variable. How you use the variable $directory will become apparent when we                      discuss the removeFilter method later in this chapter.           NOTE Local variables can have the same name as instance variables because the pseudo-                      variable $this allows you to distinguish one from the other.                           The method createTitle ( ) creates the title for each image by remov-                      ing the filename extension and replacing the underscores with spaces. This                      method is reproduced in full starting at .                           Notice the use of the access modifier private. This method, the only                      private method in the entire class, is private because there is no reason to                      access it except from the constructor. The createTitle method affects the                      internal behavior of the DirectoryItems class and identifying it as private                      allows you to indicate that this behavior is internal and hidden rather than                      external and exposed.30 Cha pt er 5
                                
                                
                                Search
                            
                            Read the Text Version
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
 
                    