Seven Steps to Better PHP Code

3,198 views
2,361 views

Published on

You have a basic OOP knowledge in PHP? You have seen the usual examples, but don't really see how to apply them to solve your coding problems? This session will show you how you can make better use of OOP by presenting seven best practices and teach you how to apply them in real life. Topics covered include dependency injection, separation of concerns, loose coupling, and much more.

Published in: Technology
1 Comment
6 Likes
Statistics
Notes
No Downloads
Views
Total views
3,198
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
158
Comments
1
Likes
6
Embeds 0
No embeds

No notes for slide

Seven Steps to Better PHP Code

  1. Stefan Priebsch thePHP.cc ZendCon09 Seven Steps to Better OOP Code
  2. Stefan Priebsch Co-Founder and Principal Consultant
  3. Premium PHP Consulting & Training. Worldwide. Sebastian Arne Stefan Bergmann Blankerts Priebsch
  4. Disclaimer
  5. „Hang the rules. They're more like guidelines anyway.“ --Elizabeth Swann, Pirates of the Caribbean
  6. Is OOP slow?
  7. foo() 3.09 µsec Test::foo() 3.26 µsec $test->foo() 3.12 µsec $test = new Test(); $test->foo() 4.03 µsec The usual disclaimer for benchmarks applies!
  8. 25% slower!
  9. 1 µsec
  10. print ~ 10 µsec file_get_contents() ~ 30 µsec mysql_connect() ~ 100 µsec HTTP GET Request ~ 35,000 µsec The usual disclaimer for benchmarks applies!
  11. I/O is where the action is.
  12. OOP is fast enough.
  13. Do not care about #1 performance * *Some restrictions may apply.
  14. What do you do for a living?
  15. class Something { public function doWork() { … load data … … perform calculations … … render HTML output … … store calculation result ... } }
  16. class Something { public function doManyThings() { $this->loadData(); $this->performCalculations(); $this->renderHtml(); $this->storeResult(); } protected function loadData() protected function performCalulations() protected function renderHtml() protected function storeResult() }
  17. class DataLoader { public function loadData() } class Calculator { public function calculateResult() } class HtmlRenderer { public function render() } class StorageManager { public function storeResult() }
  18. #2 Clearly separate different concerns
  19. One Responsibility
  20. class SomeObject { protected function loadData() { $this->data = $this->db->query(...); } public function render() { $this->loadData(); return HtmlRenderer::createTable($this->data); } }
  21. Let others do the work.
  22. class CrystalBall { public function predictLottoNumbers($a, $b, $c) { … return new LottoNumbers(...); } }
  23. #3 Focus on the API
  24. Interface vs. Implementation
  25. Keep secrets
  26. class Person { protected function talk() { Stranger::askForACigarette(); } }
  27. class Person { protected function talk() { Stranger::getInstance()->askForACigarette(); } }
  28. class Person { protected function talkTo(Friend $friend) { $friend->askForACigarette(); } } class Friend { public function askForACigarette() { return new Cigarette(); } }
  29. Do not talk to strangers.
  30. Create loosely #4 coupled classes
  31. Make dependencies explicit.
  32. class SomeObject { protected function loadData() { $this->data = $this->db->query(...); } public function render() { $this->loadData(); return HtmlRenderer::createTable($this->data); } }
  33. class SomeObject { protected function loadData() { $this->data = $this->db->query(...); } public function render(Renderer $renderer) { $this->loadData(); return $this->renderer->createTable($this->data); } }
  34. class SomeObject { protected function loadData(DbGateway $db) { $this->data = $db->query(...); } public function render(Renderer $renderer) { $this->loadData(); return $renderer->createTable($this->data); } }
  35. class SomeObject { public function __construct(DbGateway $db, Renderer $r) { $this->db = $db; $this->renderer = $r; } ... }
  36. Use dependency #5 injection
  37. class Engine { public function start(); public functoin stop(); public function goFaster($amount); public function goSlower($amount); }
  38. class Car extends Engine { ... }
  39. class SteeringWheel { public function turnRight($degrees); public function turnLeft($degree); }
  40. class Car extends Engine extends SteeringWheel { ... }
  41. Multiple inheritance?
  42. Engine
  43. Engine + Steering Wheel
  44. Engine + Steering Wheel + Seat
  45. Combine objects.
  46. Seat Car Steering Engine Wheel
  47. class Car { protected $engine; protected $steeringWheel; protected $frontSeat; public function __construct() { $this->engine = new Engine(); $this->steeringWheel = new SteeringWheel(); $this->frontSeat = new Seat(); } }
  48. class Car { public function __construct(Engine $engine, SteeringWheel $steeringWheel, Seat $seat) { $this->engine = $engine; $this->steeringWheel = $steeringWheel; $this->frontSeat = $seat; } }
  49. $engine = new Engine(); $steeringWheel = new SteeringWheel(); $seat = new Seat(); $car = new Car($engine, $steeringWheel, $seat);
  50. $engine = new SuperStrongEngine(); $steeringWheel = new FancySteeringWheel(); $seat = new MichaelSchuhmacherRacingSeat(); $car = new Car($engine, $steeringWheel, $seat);
  51. Favour composition #6 over inheritance
  52. Avoid inheritance.
  53. Constants Superglobals Session Class to Test Webservice Configuration Database
  54. If it's not tested, it does not exist
  55. Make it easy #7 to (unit) test
  56. Fewer dependencies.
  57. Testable = Maintainable
  58. Testable = Extensible
  59. Thank you.
  60. Contact ■ http://thePHP.cc ■ http://www.priebsch.de ■ http://www.slideshare.net/spriebsch ■ http://twitter.com/spriebsch ■ stefan@thePHP.cc, IRC: spriebsch Copyright © 2009 thePHP.cc, Germany

×