To keep programming productive and enjoyable, state-of-the-art practices and principles are essential. Object-oriented programming and design help manage complexity by keeping components cleanly separated. Unit testing helps prevent endless, exhausting debugging sessions. Refactoring keeps code supple and readable. PHP offers all this, and more. PHP in Action shows you how to apply PHP techniques and principles to all the most common challenges of web programming, including: Web presentation and templates User interaction including the Model-View-Contoller architecture Input validation and form handling Database connection and querying and abstraction Object persistence This book takes on the most important challenges of web programming in PHP 5 using state-of-the art programming and software design techniques including unit testing, refactoring and design patterns. It provides the essential skills you need for developing or maintaining complex to moderately complex PHP web applications. PHP in Action......Page 1 brief contents......Page 6 contents......Page 8 preface......Page 18 acknowledgments......Page 20 about this book......Page 22 about the title......Page 26 about the cover illustration......Page 27 PHP and modern software development......Page 30 1.1.1 Why PHP is so popular......Page 31 1.1.2 Overcoming PHP’s limitations......Page 35 1.2.1 Agile methodologies: from hacking to happiness......Page 37 1.2.3 The evolving discipline of object-oriented programming......Page 39 1.2.4 Design patterns......Page 40 1.2.5 Refactoring......Page 41 1.2.6 Unit testing and test-driven development......Page 42 1.3 Summary......Page 44 Objects in PHP......Page 45 2.1.1 Why we’re comparing PHP to Java......Page 46 2.1.3 Hello world......Page 47 2.1.4 Constructors: creating and initializing objects......Page 48 2.1.5 Inheritance and the extends keyword......Page 50 2.1.6 Inheriting constructors......Page 51 2.2.1 How exceptions work......Page 52 2.2.2 Exceptions versus return codes-when to use which......Page 54 2.2.3 Creating your own exception classes......Page 56 2.2.5 Don’t overdo exceptions......Page 57 2.3 Object references in PHP 4 and PHP 5......Page 58 2.3.1 How object references work......Page 59 2.3.3 When references are not so useful......Page 60 2.4.1 What is “method overloading”?......Page 61 2.4.2 Java-style method overloading in PHP......Page 62 2.4.3 A near aspect-oriented experience: logging method calls......Page 63 2.4.4 Autoloading classes......Page 65 2.5 Summary......Page 66 Using PHP classes effectively......Page 67 3.1 Visibility: private and protected methods and variables......Page 68 3.1.1 How visible do we want our methods to be?......Page 69 3.1.2 When to use private methods......Page 70 3.1.4 Keeping your instance variables private or protected......Page 71 3.1.5 Accessors for private and protected variables......Page 72 3.1.6 The best of both worlds? Using interception to control variables......Page 73 3.1.7 Final classes and methods......Page 75 3.2 The class without objects: class methods, variables, and constants......Page 76 3.2.1 Class (static) methods......Page 77 3.2.2 When to use class methods......Page 78 3.2.3 Class variables......Page 79 3.2.4 Class constants......Page 80 3.2.5 The limitations of constants in PHP......Page 81 3.3.2 Using abstract classes......Page 83 3.4 Class type hints......Page 84 3.4.2 When to use type hints......Page 85 3.5.1 What is an interface?......Page 87 3.5.3 Using interfaces to make design clearer......Page 88 3.5.4 Using interfaces to improve class type hints......Page 89 3.6 Summary......Page 91 Understanding objects and classes......Page 92 4.1 Why objects and classes are a good idea......Page 93 4.1.3 Polymorphism......Page 94 4.1.4 Objects make code easier to read......Page 95 4.1.5 Classes help eliminate duplication......Page 100 4.1.6 You can reuse objects and classes......Page 101 4.1.8 Objects provide type safety......Page 102 4.2 Criteria for good design......Page 103 4.2.2 Transparency......Page 105 4.2.3 Simple design......Page 106 4.2.4 Once and only once......Page 107 4.3.1 Objects come from the unreal world......Page 109 4.3.2 Domain object basics......Page 111 4.4 Summary......Page 112 Understanding class relationships......Page 114 5.1.1 Inheritance as a thinking tool......Page 115 5.1.2 Refactoring to inheritance......Page 116 5.2 Object composition......Page 121 5.3 Interfaces......Page 123 5.3.1 The interface as a thinking tool......Page 124 5.3.2 Single and multiple inheritance......Page 125 5.4.1 Avoiding vaguely named parent classes......Page 126 5.4.2 Avoiding deep inheritance hierarchies......Page 127 5.5 Summary......Page 128 Object-oriented principles......Page 129 6.1 Principles and patterns......Page 130 6.1.2 Learning OO principles......Page 131 6.2.1 OCP for beginners......Page 132 6.2.2 Replacing cases with classes......Page 133 6.2.3 How relevant is the OCP in PHP?......Page 135 6.3 The single-responsibility principle (SRP)......Page 136 6.3.1 Mixed responsibilities: the template engine......Page 137 6.3.2 An experiment: separating the responsibilities......Page 139 6.3.3 Was the experiment successful?......Page 141 6.4 The dependency-inversion principle (DIP)......Page 142 6.4.1 What is a dependency?......Page 143 6.4.2 Inserting an interface......Page 145 6.5.1 The “three-tier” model and its siblings......Page 146 6.5.2 Can a web application have a Domain layer?......Page 147 6.6 Summary......Page 149 Design patterns......Page 150 7.1.1 “Hello world” using Strategy......Page 152 7.1.2 How Strategy is useful......Page 154 7.2.1 Adapter for beginners......Page 155 7.2.2 Making one template engine look like another......Page 156 7.2.3 Adapters with multiple classes......Page 158 7.2.4 Adapting to a generic interface......Page 161 7.3.1 Resource Decorator......Page 162 7.3.2 Decorating and redecorating......Page 163 7.4 Null Object......Page 166 7.4.2 Null Strategy objects......Page 167 7.5.1 How iterators work......Page 169 7.5.3 Iterators versus plain arrays......Page 170 7.5.4 SPL iterators......Page 171 7.6 Composite......Page 172 7.6.1 Implementing a menu as a Composite......Page 173 7.6.2 The basics......Page 175 7.6.4 Recursive processing......Page 176 7.6.5 Is this inefficient?......Page 177 7.7 Summary......Page 178 Design how-to: date and time handling......Page 179 8.1.1 Easier, but not simpler......Page 180 8.1.2 OO advantages......Page 181 8.2.1 Single time representation: Time Point, Instant, DateAndTime......Page 182 8.2.2 Different kinds of time spans: Period, Duration, Date Range, Interval......Page 183 8.3.1 Using creation methods......Page 185 8.3.2 Multiple constructors......Page 186 8.3.3 Using factory classes......Page 189 8.4 Large-scale structure......Page 190 8.4.1 The package concept......Page 191 8.4.2 Namespaces and packages......Page 192 8.4.3 PHP’s lack of namespace support......Page 193 8.4.4 Dealing with name conflicts......Page 194 8.5.1 How object references can make trouble......Page 200 8.5.2 Implementing value objects......Page 201 8.5.3 Changing an immutable object......Page 202 8.6.1 DateAndTime......Page 203 8.6.2 Properties and fields......Page 204 8.6.3 Periods......Page 210 8.6.4 Intervals......Page 212 8.7 Summary......Page 213 Test-driven development......Page 216 9.1 Building quality into the process......Page 217 9.1.1 Requirements for the example......Page 218 9.2 Database select......Page 219 9.2.1 A rudimentary test......Page 220 9.2.2 The first real test......Page 221 9.2.3 Make it pass......Page 223 9.2.4 Make it work......Page 225 9.2.5 Test until you are confident......Page 227 9.3.1 Making the tests more readable......Page 228 9.3.2 Red, green, refactor......Page 230 9.4.1 Testing transactions......Page 232 9.4.2 Implementing transactions......Page 234 9.4.3 The end of debugging?......Page 235 9.5 Summary......Page 236 Advanced testing techniques......Page 237 10.1 A contact manager with persistence......Page 238 10.1.1 Running multiple test cases......Page 239 10.1.2 Testing the contact’s persistence......Page 240 10.1.3 The Contact and ContactFinder classes......Page 242 10.1.4 setUp() and tearDown()......Page 244 10.1.5 The final version......Page 245 10.2.1 Designing the Mailer class and its test environment......Page 246 10.2.2 Manually coding a mock object......Page 247 10.2.3 A more sophisticated mock object......Page 248 10.2.4 Top-down testing......Page 249 10.2.5 Mock limitations......Page 251 10.3.1 Installing fakemail......Page 252 10.3.2 A mail test......Page 254 10.4 Summary......Page 257 Refactoring web applications......Page 259 11.1 Refactoring in the real world......Page 260 11.1.1 Early and late refactoring......Page 261 11.1.2 Refactoring versus reimplementation......Page 262 11.2.1 Improving readability......Page 263 11.2.2 Eliminating duplication......Page 265 11.3 Separating markup from program code......Page 268 11.3.2 Using CSS appropriately......Page 269 11.3.3 Cleaning up a function that generates a link......Page 270 11.3.4 Introducing templates in SimpleTest......Page 275 11.4 Simplifying conditional expressions......Page 280 11.4.1 A simple example......Page 281 11.4.2 A longer example: authentication code......Page 282 11.4.3 Handling conditional HTML......Page 288 11.5 Refactoring from procedural to object-oriented......Page 289 11.5.1 Getting procedural code under test......Page 290 11.5.2 Doing the refactorings......Page 291 11.6 Summary......Page 294 Taking control with web tests......Page 296 12.1 Revisiting the contact manager......Page 297 12.1.1 The mock-up......Page 298 12.1.2 Setting up web testing......Page 299 12.1.3 Satisfying the test with fake web page interaction......Page 301 12.1.4 Write once, test everywhere......Page 302 12.2 Getting a working form......Page 304 12.2.1 Trying to save the contact to the database......Page 305 12.2.2 Setting up the database......Page 306 12.2.3 Stubbing out the finder......Page 308 12.3.1 Making the contact manager unit-testable......Page 310 12.3.2 From use case to acceptance test......Page 312 12.4 The horror of legacy code......Page 315 12.5 Summary......Page 319 Using templates to manage web presentation......Page 322 13.1.1 To separate or not to separate.........Page 323 13.1.2 Why templates?......Page 324 13.2 Which template engine?......Page 326 13.2.1 Plain PHP......Page 328 13.2.2 Custom syntax: Smarty......Page 329 13.2.3 Attribute language: PHPTAL......Page 331 13.3 Transformation: XSLT......Page 335 13.3.2 Setting up XSLT......Page 336 13.3.3 The XSLT stylesheet......Page 337 13.3.4 Running XSLT from PHP......Page 339 13.4 Keeping logic out of templates......Page 340 13.4.1 View Helper......Page 341 13.4.3 Handling date and time formats......Page 342 13.4.4 Generating hierarchical displays......Page 345 13.4.5 Preventing updates from the template......Page 348 13.5.1 PHPTAL......Page 349 13.6 Summary......Page 350 14.1 Combining templates (Composite View)......Page 352 14.2 Implementing a straightforward composite view......Page 353 14.2.1 What we need to achieve......Page 354 14.2.2 Using Smarty......Page 355 14.2.3 Using PHPTAL......Page 357 14.2.4 Using page macros with PHPTAL......Page 358 14.3 Composite View examples......Page 359 14.3.1 Making print-friendly versions of pages......Page 360 14.3.2 Integrating existing applications into a Composite View......Page 362 14.3.3 Multi-appearance sites and Fowler’s Two Step View......Page 363 14.4 Summary......Page 364 User interaction......Page 365 15.1 The Model-View-Controller architecture......Page 367 15.1.1 Clearing the MVC fog......Page 368 15.1.2 Defining the basic concepts......Page 369 15.1.3 Command or action?......Page 371 15.1.4 Web MVC is not rich-client MVC......Page 372 15.2 The Web Command pattern......Page 373 15.2.2 Command identifier......Page 374 15.2.3 Web handler......Page 375 15.3.1 Example: a “naive” web application......Page 376 15.3.2 Introducing command functions......Page 378 15.4 Summary......Page 382 Controllers......Page 383 16.1.1 A basic request object......Page 384 16.1.2 Security issues......Page 385 16.2.1 A simple example......Page 388 16.2.2 Choosing Views from a Page Controller......Page 390 16.2.3 Making commands unit-testable......Page 391 16.2.5 Using templates......Page 392 16.2.6 The redirect problem......Page 393 16.3 Building a Front Controller......Page 396 16.3.1 Web Handler with single-command classes......Page 397 16.3.3 Using command groups......Page 398 16.3.4 Forms with multiple submit buttons......Page 400 16.3.6 Controllers for Composite Views......Page 401 16.4 Summary......Page 403 Input validation......Page 404 17.1.1 Validation and application architecture......Page 405 17.1.2 Strategies for validation......Page 406 17.1.3 Naming the components of a form......Page 407 17.2.1 The duplication problem......Page 408 17.2.2 The styling problem......Page 409 17.2.4 How many problems can we solve?......Page 410 17.3.1 Ordinary, boring client-side validation......Page 411 17.3.2 Validating field-by-field......Page 413 17.3.3 You can’t do that!......Page 415 17.3.4 The form......Page 418 17.4.1 Rules and validators......Page 420 17.4.2 A secure request object architecture......Page 421 17.4.3 Now validation is simple......Page 426 17.4.4 A class to make it simple......Page 427 17.4.5 Using Specification objects......Page 430 17.4.7 Adding validations to the facade......Page 434 17.5 Synchronizing server-side and client-side validation......Page 436 17.5.3 Generating server-side validation from client-side validation......Page 437 17.6 Summary......Page 439 Form handling......Page 440 18.1.1 Minimalistic requirements and design......Page 441 18.1.2 Putting generated elements into the HTML form......Page 442 18.1.3 Finding abstractions......Page 443 18.1.4 More specific requirements......Page 444 18.1.5 The select problem......Page 445 18.2 Implementing the solution......Page 446 18.2.1 Wrapping the HTML_QuickForm elements......Page 447 18.2.2 Input controls......Page 448 18.2.3 Which class creates the form controls?......Page 452 18.2.4 Validation......Page 453 18.2.5 Using the form object in a template......Page 454 18.2.6 What next?......Page 457 18.3 Summary......Page 458 Database connection, abstraction, and configuration......Page 459 19.1 Database abstraction......Page 460 19.1.1 Prepared statements......Page 461 19.1.2 Object-oriented database querying......Page 464 19.2.1 A simple configured database connection......Page 465 19.2.2 Making an SPL-compatible iterator from a result set......Page 467 19.3 Making the database connection available......Page 469 19.3.1 Singleton and similar patterns......Page 470 19.3.2 Service Locator and Registry......Page 472 19.4 Summary......Page 475 Objects and SQL......Page 478 20.1 The object-relational impedance mismatch......Page 479 20.2 Encapsulating and hiding SQL......Page 480 20.2.1 A basic example......Page 481 20.2.2 Substituting strings in SQL statements......Page 482 20.3 Generalizing SQL......Page 486 20.3.1 Column lists and table names......Page 487 20.3.3 Generating INSERT, UPDATE and DELETE statements......Page 490 20.3.5 Applicable design patterns......Page 495 20.4 Summary......Page 496 Data class design......Page 497 21.1.1 Retrieving data with Finder classes......Page 498 21.1.2 Mostly procedural: Table Data Gateway......Page 501 21.2 Letting objects persist themselves......Page 506 21.2.1 Finders for self-persistent objects......Page 507 21.2.2 Letting objects store themselves......Page 512 21.3 The Data Mapper pattern......Page 513 21.3.1 Data Mappers and DAOs......Page 514 21.3.2 These patterns are all the same......Page 515 21.4.1 How the patterns work in a typical web application......Page 517 21.5 Summary......Page 519 Brain-dead SimpleTest example......Page 520 Brain-dead PHPUnit example......Page 521 A.2 Organizing tests in a directory structure......Page 522 A.3 PHPUnit and SimpleTest assertions......Page 523 Sending and checking HTTP requests......Page 525 Assertions about page content......Page 526 Forms and buttons......Page 527 HTTP authentication......Page 528 Frames......Page 529 B.1 Filter input......Page 530 B.2 Escape output......Page 532 B.3 Cross-site scripting......Page 533 B.4 SQL Injection......Page 534 B.5 Session fixation......Page 536 B.7 Summary......Page 537 resources......Page 538 index......Page 540 PHP in Action 1 brief contents 6 contents 8 preface 18 acknowledgments 20 about this book 22 about the title 26 about the cover illustration 27 PHP and modern software development 30 1.1 How PHP can help you 31 1.1.1 Why PHP is so popular 31 1.1.2 Overcoming PHP’s limitations 35 1.2 Languages, principles, and patterns 37 1.2.1 Agile methodologies: from hacking to happiness 37 1.2.2 PHP 5 and software trends 39 1.2.3 The evolving discipline of object-oriented programming 39 1.2.4 Design patterns 40 1.2.5 Refactoring 41 1.2.6 Unit testing and test-driven development 42 1.3 Summary 44 Objects in PHP 45 2.1 Object fundamentals 46 2.1.1 Why we’re comparing PHP to Java 46 2.1.2 Objects and classes 47 2.1.3 Hello world 47 2.1.4 Constructors: creating and initializing objects 48 2.1.5 Inheritance and the extends keyword 50 2.1.6 Inheriting constructors 51 2.2 Exception handling 52 2.2.1 How exceptions work 52 2.2.2 Exceptions versus return codes-when to use which 54 2.2.3 Creating your own exception classes 56 2.2.4 Replacing built-in PHP fatal errors with exceptions 57 2.2.5 Don’t overdo exceptions 57 2.3 Object references in PHP 4 and PHP 5 58 2.3.1 How object references work 59 2.3.2 The advantages of object references 60 2.3.3 When references are not so useful 60 2.4 Intercepting method calls and class instantiation 61 2.4.1 What is “method overloading”? 61 2.4.2 Java-style method overloading in PHP 62 2.4.3 A near aspect-oriented experience: logging method calls 63 2.4.4 Autoloading classes 65 2.5 Summary 66 Using PHP classes effectively 67 3.1 Visibility: private and protected methods and variables 68 3.1.1 How visible do we want our methods to be? 69 3.1.2 When to use private methods 70 3.1.3 When to use protected methods 71 3.1.4 Keeping your instance variables private or protected 71 3.1.5 Accessors for private and protected variables 72 3.1.6 The best of both worlds? Using interception to control variables 73 3.1.7 Final classes and methods 75 3.2 The class without objects: class methods, variables, and constants 76 3.2.1 Class (static) methods 77 3.2.2 When to use class methods 78 3.2.3 Class variables 79 3.2.4 Class constants 80 3.2.5 The limitations of constants in PHP 81 3.3 Abstract classes and methods (functions) 83 3.3.1 What are abstract classes and methods? 83 3.3.2 Using abstract classes 83 3.4 Class type hints 84 3.4.1 How type hints work 85 3.4.2 When to use type hints 85 3.5 Interfaces 87 3.5.1 What is an interface? 87 3.5.2 Do we need interfaces in PHP? 88 3.5.3 Using interfaces to make design clearer 88 3.5.4 Using interfaces to improve class type hints 89 3.5.5 Interfaces in PHP 5 versus Java 91 3.6 Summary 91 Understanding objects and classes 92 4.1 Why objects and classes are a good idea 93 4.1.1 Classes help you organize 94 4.1.2 You can tell objects to do things 94 4.1.3 Polymorphism 94 4.1.4 Objects make code easier to read 95 4.1.5 Classes help eliminate duplication 100 4.1.6 You can reuse objects and classes 101 4.1.7 Change things without affecting everything 102 4.1.8 Objects provide type safety 102 4.2 Criteria for good design 103 4.2.1 Don’t confuse the end with the means 105 4.2.2 Transparency 105 4.2.3 Simple design 106 4.2.4 Once and only once 107 4.3 What are objects, anyway? 109 4.3.1 Objects come from the unreal world 109 4.3.2 Domain object basics 111 4.4 Summary 112 Understanding class relationships 114 5.1 Inheritance 115 5.1.1 Inheritance as a thinking tool 115 5.1.2 Refactoring to inheritance 116 5.2 Object composition 121 5.3 Interfaces 123 5.3.1 The interface as a thinking tool 124 5.3.2 Single and multiple inheritance 125 5.4 Favoring composition over inheritance 126 5.4.1 Avoiding vaguely named parent classes 126 5.4.2 Avoiding deep inheritance hierarchies 127 5.5 Summary 128 Object-oriented principles 129 6.1 Principles and patterns 130 6.1.1 Architectural principles or patterns 131 6.1.2 Learning OO principles 131 6.2 The open-closed principle (OCP) 132 6.2.1 OCP for beginners 132 6.2.2 Replacing cases with classes 133 6.2.3 How relevant is the OCP in PHP? 135 6.3 The single-responsibility principle (SRP) 136 6.3.1 Mixed responsibilities: the template engine 137 6.3.2 An experiment: separating the responsibilities 139 6.3.3 Was the experiment successful? 141 6.4 The dependency-inversion principle (DIP) 142 6.4.1 What is a dependency? 143 6.4.2 Inserting an interface 145 6.5 Layered designs 146 6.5.1 The “three-tier” model and its siblings 146 6.5.2 Can a web application have a Domain layer? 147 6.6 Summary 149 Design patterns 150 7.1 Strategy 152 7.1.1 “Hello world” using Strategy 152 7.1.2 How Strategy is useful 154 7.2 Adapter 155 7.2.1 Adapter for beginners 155 7.2.2 Making one template engine look like another 156 7.2.3 Adapters with multiple classes 158 7.2.4 Adapting to a generic interface 161 7.3 Decorator 162 7.3.1 Resource Decorator 162 7.3.2 Decorating and redecorating 163 7.4 Null Object 166 7.4.1 Mixing dark and bright lights 167 7.4.2 Null Strategy objects 167 7.5 Iterator 169 7.5.1 How iterators work 169 7.5.2 Good reasons to use iterators 170 7.5.3 Iterators versus plain arrays 170 7.5.4 SPL iterators 171 7.5.5 How SPL helps us solve the iterator/array conflict 172 7.6 Composite 172 7.6.1 Implementing a menu as a Composite 173 7.6.2 The basics 175 7.6.3 A fluent interface 176 7.6.4 Recursive processing 176 7.6.5 Is this inefficient? 177 7.7 Summary 178 Design how-to: date and time handling 179 8.1 Why object-oriented date and time handling? 180 8.1.1 Easier, but not simpler 180 8.1.2 OO advantages 181 8.2 Finding the right abstractions 182 8.2.1 Single time representation: Time Point, Instant, DateAndTime 182 8.2.2 Different kinds of time spans: Period, Duration, Date Range, Interval 183 8.3 Advanced object construction 185 8.3.1 Using creation methods 185 8.3.2 Multiple constructors 186 8.3.3 Using factory classes 189 8.4 Large-scale structure 190 8.4.1 The package concept 191 8.4.2 Namespaces and packages 192 8.4.3 PHP’s lack of namespace support 193 8.4.4 Dealing with name conflicts 194 8.5 Using value objects 200 8.5.1 How object references can make trouble 200 8.5.2 Implementing value objects 201 8.5.3 Changing an immutable object 202 8.6 Implementing the basic classes 203 8.6.1 DateAndTime 203 8.6.2 Properties and fields 204 8.6.3 Periods 210 8.6.4 Intervals 212 8.7 Summary 213 Test-driven development 216 9.1 Building quality into the process 217 9.1.1 Requirements for the example 218 9.1.2 Reporting test results 219 9.2 Database select 219 9.2.1 A rudimentary test 220 9.2.2 The first real test 221 9.2.3 Make it pass 223 9.2.4 Make it work 225 9.2.5 Test until you are confident 227 9.3 Database insert and update 228 9.3.1 Making the tests more readable 228 9.3.2 Red, green, refactor 230 9.4 Real database transactions 232 9.4.1 Testing transactions 232 9.4.2 Implementing transactions 234 9.4.3 The end of debugging? 235 9.4.4 Testing is a tool, not a substitute 236 9.5 Summary 236 Advanced testing techniques 237 10.1 A contact manager with persistence 238 10.1.1 Running multiple test cases 239 10.1.2 Testing the contact’s persistence 240 10.1.3 The Contact and ContactFinder classes 242 10.1.4 setUp() and tearDown() 244 10.1.5 The final version 245 10.2 Sending an email to a contact 246 10.2.1 Designing the Mailer class and its test environment 246 10.2.2 Manually coding a mock object 247 10.2.3 A more sophisticated mock object 248 10.2.4 Top-down testing 249 10.2.5 Mock limitations 251 10.3 A fake mail server 252 10.3.1 Installing fakemail 252 10.3.2 A mail test 254 10.3.3 Gateways as adapters 257 10.4 Summary 257 Refactoring web applications 259 11.1 Refactoring in the real world 260 11.1.1 Early and late refactoring 261 11.1.2 Refactoring versus reimplementation 262 11.2 Refactoring basics: readability and duplication 263 11.2.1 Improving readability 263 11.2.2 Eliminating duplication 265 11.3 Separating markup from program code 268 11.3.1 Why the separation is useful 269 11.3.2 Using CSS appropriately 269 11.3.3 Cleaning up a function that generates a link 270 11.3.4 Introducing templates in SimpleTest 275 11.4 Simplifying conditional expressions 280 11.4.1 A simple example 281 11.4.2 A longer example: authentication code 282 11.4.3 Handling conditional HTML 288 11.5 Refactoring from procedural to object-oriented 289 11.5.1 Getting procedural code under test 290 11.5.2 Doing the refactorings 291 11.6 Summary 294 Taking control with web tests 296 12.1 Revisiting the contact manager 297 12.1.1 The mock-up 298 12.1.2 Setting up web testing 299 12.1.3 Satisfying the test with fake web page interaction 301 12.1.4 Write once, test everywhere 302 12.2 Getting a working form 304 12.2.1 Trying to save the contact to the database 305 12.2.2 Setting up the database 306 12.2.3 Stubbing out the finder 308 12.3 Quality assurance 310 12.3.1 Making the contact manager unit-testable 310 12.3.2 From use case to acceptance test 312 12.4 The horror of legacy code 315 12.5 Summary 319 Using templates to manage web presentation 322 13.1 Separating presentation and domain logic 323 13.1.1 To separate or not to separate... 323 13.1.2 Why templates? 324 13.2 Which template engine? 326 13.2.1 Plain PHP 328 13.2.2 Custom syntax: Smarty 329 13.2.3 Attribute language: PHPTAL 331 13.3 Transformation: XSLT 335 13.3.1 “XMLizing” a web page 336 13.3.2 Setting up XSLT 336 13.3.3 The XSLT stylesheet 337 13.3.4 Running XSLT from PHP 339 13.4 Keeping logic out of templates 340 13.4.1 View Helper 341 13.4.2 Alternating row colors 342 13.4.3 Handling date and time formats 342 13.4.4 Generating hierarchical displays 345 13.4.5 Preventing updates from the template 348 13.5 Templates and security 349 13.5.1 PHPTAL 349 13.5.2 Smarty 350 13.5.3 XSLT 350 13.6 Summary 350 Constructing complex web pages 352 14.1 Combining templates (Composite View) 352 14.1.1 Composite View: one or several design patterns? 353 14.1.2 Composite data and composite templates 353 14.2 Implementing a straightforward composite view 353 14.2.1 What we need to achieve 354 14.2.2 Using Smarty 355 14.2.3 Using PHPTAL 357 14.2.4 Using page macros with PHPTAL 358 14.3 Composite View examples 359 14.3.1 Making print-friendly versions of pages 360 14.3.2 Integrating existing applications into a Composite View 362 14.3.3 Multi-appearance sites and Fowler’s Two Step View 363 14.4 Summary 364 User interaction 365 15.1 The Model-View-Controller architecture 367 15.1.1 Clearing the MVC fog 368 15.1.2 Defining the basic concepts 369 15.1.3 Command or action? 371 15.1.4 Web MVC is not rich-client MVC 372 15.2 The Web Command pattern 373 15.2.1 How it works 374 15.2.2 Command identifier 374 15.2.3 Web handler 375 15.2.4 Command executor 376 15.3 Keeping the implementation simple 376 15.3.1 Example: a “naive” web application 376 15.3.2 Introducing command functions 378 15.4 Summary 382 Controllers 383 16.1 Controllers and request objects 384 16.1.1 A basic request object 384 16.1.2 Security issues 385 16.2 Using Page Controllers 388 16.2.1 A simple example 388 16.2.2 Choosing Views from a Page Controller 390 16.2.3 Making commands unit-testable 391 16.2.4 Avoiding HTML output 392 16.2.5 Using templates 392 16.2.6 The redirect problem 393 16.3 Building a Front Controller 396 16.3.1 Web Handler with single-command classes 397 16.3.2 What more does the command need? 398 16.3.3 Using command groups 398 16.3.4 Forms with multiple submit buttons 400 16.3.5 Generating commands with JavaScript 401 16.3.6 Controllers for Composite Views 401 16.4 Summary 403 Input validation 404 17.1 Input validation in application design 405 17.1.1 Validation and application architecture 405 17.1.2 Strategies for validation 406 17.1.3 Naming the components of a form 407 17.2 Server-side validation and its problems 408 17.2.1 The duplication problem 408 17.2.2 The styling problem 409 17.2.3 Testing and page navigation problems 410 17.2.4 How many problems can we solve? 410 17.3 Client-side validation 411 17.3.1 Ordinary, boring client-side validation 411 17.3.2 Validating field-by-field 413 17.3.3 You can’t do that! 415 17.3.4 The form 418 17.4 Object-oriented server-side validation 420 17.4.1 Rules and validators 420 17.4.2 A secure request object architecture 421 17.4.3 Now validation is simple 426 17.4.4 A class to make it simple 427 17.4.5 Using Specification objects 430 17.4.6 Knowledge-rich design 434 17.4.7 Adding validations to the facade 434 17.5 Synchronizing server-side and client-side validation 436 17.5.1 Form generator 437 17.5.2 Configuration file 437 17.5.3 Generating server-side validation from client-side validation 437 17.6 Summary 439 Form handling 440 18.1 Designing a solution using HTML_QuickForm 441 18.1.1 Minimalistic requirements and design 441 18.1.2 Putting generated elements into the HTML form 442 18.1.3 Finding abstractions 443 18.1.4 More specific requirements 444 18.1.5 The select problem 445 18.2 Implementing the solution 446 18.2.1 Wrapping the HTML_QuickForm elements 447 18.2.2 Input controls 448 18.2.3 Which class creates the form controls? 452 18.2.4 Validation 453 18.2.5 Using the form object in a template 454 18.2.6 What next? 457 18.3 Summary 458 Database connection, abstraction, and configuration 459 19.1 Database abstraction 460 19.1.1 Prepared statements 461 19.1.2 Object-oriented database querying 464 19.2 Decorating and adapting database resource objects 465 19.2.1 A simple configured database connection 465 19.2.2 Making an SPL-compatible iterator from a result set 467 19.3 Making the database connection available 469 19.3.1 Singleton and similar patterns 470 19.3.2 Service Locator and Registry 472 19.4 Summary 475 Objects and SQL 478 20.1 The object-relational impedance mismatch 479 20.2 Encapsulating and hiding SQL 480 20.2.1 A basic example 481 20.2.2 Substituting strings in SQL statements 482 20.3 Generalizing SQL 486 20.3.1 Column lists and table names 487 20.3.2 Using SQL aliases 490 20.3.3 Generating INSERT, UPDATE and DELETE statements 490 20.3.4 Query objects 495 20.3.5 Applicable design patterns 495 20.4 Summary 496 Data class design 497 21.1 The simplest approaches 498 21.1.1 Retrieving data with Finder classes 498 21.1.2 Mostly procedural: Table Data Gateway 501 21.2 Letting objects persist themselves 506 21.2.1 Finders for self-persistent objects 507 21.2.2 Letting objects store themselves 512 21.3 The Data Mapper pattern 513 21.3.1 Data Mappers and DAOs 514 21.3.2 These patterns are all the same 515 21.3.3 Pattern summary 517 21.4 Facing the real world 517 21.4.1 How the patterns work in a typical web application 517 21.4.2 Optimizing queries 519 21.5 Summary 519 Tools and tips for testing 520 A.1 The basics 520 Brain-dead SimpleTest example 520 Brain-dead PHPUnit example 521 A.2 Organizing tests in a directory structure 522 A.3 PHPUnit and SimpleTest assertions 523 A.4 SimpleTest web test API 525 Sending and checking HTTP requests 525 Assertions about page content 526 Links 527 Forms and buttons 527 Displaying content and information 528 HTTP authentication 528 Browser navigation 529 Cookies 529 Frames 529 Security 530 B.1 Filter input 530 B.2 Escape output 532 B.3 Cross-site scripting 533 B.4 SQL Injection 534 B.5 Session fixation 536 B.6 More information 537 B.7 Summary 537 resources 538 index 540 To keep programming productive and enjoyable, state-of-the-art practices andprinciples are essential. Object-oriented programming and design help managecomplexity by keeping components cleanly separated. Unit testing helps preventendless, exhausting debugging sessions. Refactoring keeps code supple andreadable. PHP offers all this-and more.PHP in Action shows you how to apply PHP techniques and principles to all themost common challenges of web programming, including:Web presentation and templatesUser interaction including the Model-View-Contoller architectureInput validation and form handlingDatabase connection and querying and abstractionObject persistence Purchase of the print book comes with an offer of a free PDF, ePub, and Kindle eBook from Manning. Also available is all code from the book. From the Publisher: To keep programming productive and enjoyable, state-of-the-art practices and principles are essential. Object-oriented programming and design help manage complexity by keeping components cleanly separated. Unit testing helps prevent endless, exhausting debugging sessions. Refactoring keeps code supple and readable. PHP offers all this-and more. This book shows you how to apply PHP techniques and principles to all the most common challenges of web programming, including: Web presentation and templates; User interaction including the Model-View-Controller architecture; Input validation and form handling; Database connection and querying and abstraction; Object persistence To keep programming productive and enjoyable, state-of-the-art practices andprinciples are essential. Object-oriented programming and design help managecomplexity by keeping components cleanly separated. Unit testing helps preventendless, exhausting debugging sessions. Refactoring keeps code supple andreadable. PHP offers all this-and more. PHP in Action shows you how to apply PHP techniques and principles to all themost common challenges of web programming, Purchase of the print book comes with an offer of a free PDF, ePub, and Kindle eBook from Manning. Also available is all code from the book.