0
Organizing Your
 PHP Projects
     Paul M. Jones
   ConFoo, Montréal
     10 Mar 2010

   http://joind.in/1289
Read These
• “Mythical Man-Month”, Brooks
• “Art of Project Management”, Berkun
• “Peopleware”, DeMarco and Lister




   ...
Project Planning
        in One Lesson
•   Examine real-world projects

•   The One Lesson for
    organizing your project...
About Me
•   Web Architect

•   PHP since 1999 (PHP 3)

•   Solar Framework (lead)

•   Savant Template System (lead)

•  ...
About You
•   Project lead/manager?

•   Improve team consistency?

•   Want to share your code
    with others?

•   Want...
Goals for Organizing
•   Security

•   Integration and extension

•   Adaptable to change

•   Predictable and maintainabl...
Project Research;
              or,
“Step 1: Study Underpinnings”



              7
Project Evolution Tracks
               One-Off
                Heap

              Standalone
                 App

  Lib...
One-Off Heap
•   No discernible architecture

•   Browse directly to the scripts

•   Add to it piece by piece

•   Little...
Standalone Application
•   One-off heap ++

•   Series of separate page
    scripts and common includes

•   Installed in ...
Standalone Application:
   Typical Main Script
// Setup or bootstrapping
define('INCLUDE_PATH', dirname(__FILE__) . '/');
...
Standalone Application:
  Typical Include File

// expects certain globals
if (! defined('APP_CONSTANT')) {
    die("Direc...
Standalone Application:
 Typical File Structure
 index.php               #   main pages
 page1.php               #
 page2....
Standalone Application:
   Support Structure
 bin/           #   command-line tools
 cache/         #   cache files
 css/ ...
Project Evolution Tracks
               One-Off
                Heap

              Standalone
                 App

  Lib...
Modular Application
•   Standalone application ++

•   Same file structure and script style

•   One additional directory:
...
CMS
•   Modular application ++

•   General-purpose application
    broker

•   All "main" scripts become
    sub-applicat...
Application/CMS
             Projects
• Achievo         • Eventum     • PhpMyAdmin
• Code Igniter*   • Gallery     • Seagu...
Project Evolution Tracks
               One-Off
                Heap

              Standalone
                 App

  Lib...
Library Collection
•   Specific, limited logic extracted
    from an app

•   Re-used directly in unrelated
    application...
Library Project:
    Typical File Structure
Foo.php                 #    Foo
Foo/                    #
     Component.php ...
Framework
•   Codebase

    •   Library collection

    •   Apps extend from it

•   Support structure

    •   Bootstrap ...
Library/Framework Projects
•   AdoDB            •   Lithium        •   Savant

•   Cake             •   Mojavi/Agavi   •  ...
Project Evolution Tracks
  class-       One-Off      include-
 oriented       Heap        oriented

              Standalo...
The One Lesson;
       or,
  “Step 2: ... ?”




        25
Organize your project
            as if
it is a library collection.
Elements of
        The One Lesson

• Stop using globals
• Namespace everything
• Class-to-file naming

                   ...
1. Stop Using Globals

• Stop using
  register_globals

• Stop using $GLOBALS
• Stop using global

                       ...
2. Namespace Everything

•   Automatic deconfliction of identifiers

    •   Classes (“vendor”)

    •   Functions, variable...
Choosing a Namespace

•   Project, client, brand, channel

•   A short word or acronym,
    not a letter (“Z”)

•   A uniq...
PHP 5.2 “Namespaces”
// class User {}
class Vendor_User {}
$user = new Vendor_User();

// function get_info() {}
function ...
PHP 5.3 Namespaces
namespace vendor;
class User {}

// relative namespace
namespace vendor;
$user = new User();

// absolu...
3. Class-To-File Naming

• Class name maps directly to file name
 • Vendor_User    => Vendor/User.php

• Horde, PEAR, Solar...
Class-to-File Naming
 (PHP 5.2, Horde/PEAR)

// studly-caps needs preg_replace(), but:
VendorAuthOpenId => ...
    Vendor/...
Class-to-File
          (PHP 5.3, PSR-0)

foo_barpkgMain     => /foo_bar/pkg/Main.php
foo_barpkgMain_Sub => /foo_bar/pkg/M...
The One Lesson In Practice;
           or,
     “Step 3: Profit!”




             36
Extended Effects of
             The One Lesson
•   Can be used anywhere
    (app, module, lib, CMS, framework)

•   Struc...
Mambo CMS
administrator/
components/
editor/
files/
help/
images/
includes/
    Vendor/
index.php
installation/
language/
...
Zend Framework
 project/
     application/
          bootstrap.php
          configs/
          controllers/
          mod...
Lithium
app/
    config/
    controllers/
    extensions/
    index.php
    libraries/
    models/
    resources/
    test...
Symfony 2
hello/
     config/
     console/
     HelloKernel.php
src/
     Application/
         HelloBundle/
            ...
Solar
system/
    config/
    config.php
    docroot/
         index.php
         public/
    include/
         Solar.php
...
Solar Apps Are Libraries Too
          include/
            Solar/
            Vendor/
              App/
                ...
Refactoring
• Move from existing include-based architecture
  to class-based architecture ...
  • ... by functionality
  •...
Summary
The One Lesson

• Organize your project as if it will be part of
  a library collection
  • Avoid globals
  • Use namespac...
Goals for Organizing
•   Security

•   Integration and extension

•   Adaptable to change

•   Predictable and maintainabl...
• Questions?
• Comments?
• Criticism?


               48
Thanks!

• <http://paul-m-jones.com>
• <http://solarphp.com>
• Solar Framework talk on Thursday
• <http://joind.in/1289>

...
Organizing Your PHP Projects (2010 ConFoo)
Upcoming SlideShare
Loading in...5
×

Organizing Your PHP Projects (2010 ConFoo)

9,285

Published on

By using a few simple organizational principles, developers can make their project structure predictable, extensible, and modular. These techniques make it easy to de-conflict and share code between multiple projects. They also make it easy to automate project-support tasks such as testing, documentation, and distribution. This talk will discuss these principles, how they can be discovered from researching publicly available PHP projects, and how they are used (or not used) in popular applications and frameworks.

Published in: Technology

Transcript of "Organizing Your PHP Projects (2010 ConFoo)"

  1. 1. Organizing Your PHP Projects Paul M. Jones ConFoo, Montréal 10 Mar 2010 http://joind.in/1289
  2. 2. Read These • “Mythical Man-Month”, Brooks • “Art of Project Management”, Berkun • “Peopleware”, DeMarco and Lister 2
  3. 3. Project Planning in One Lesson • Examine real-world projects • The One Lesson for organizing your project • Elements of The One Lesson • The One Lesson in practice 3
  4. 4. About Me • Web Architect • PHP since 1999 (PHP 3) • Solar Framework (lead) • Savant Template System (lead) • Zend Framework (found. contrib.) • PEAR Group (2007-2008) • Web framework benchmarks 4
  5. 5. About You • Project lead/manager? • Improve team consistency? • Want to share your code with others? • Want to use code from others? • Want to reduce recurring integration issues? 5
  6. 6. Goals for Organizing • Security • Integration and extension • Adaptable to change • Predictable and maintainable • Teamwork consistency • Re-use rules on multiple projects 6
  7. 7. Project Research; or, “Step 1: Study Underpinnings” 7
  8. 8. Project Evolution Tracks One-Off Heap Standalone App Library ? Modular App Collection Framework CMS 8
  9. 9. One-Off Heap • No discernible architecture • Browse directly to the scripts • Add to it piece by piece • Little to no separation of concerns • All variables are global • Unmanageable, difficult to extend 9
  10. 10. Standalone Application • One-off heap ++ • Series of separate page scripts and common includes • Installed in web root • Each responsible for global execution environment • Script variables still global 10
  11. 11. Standalone Application: Typical Main Script // Setup or bootstrapping define('INCLUDE_PATH', dirname(__FILE__) . '/'); include_once INCLUDE_PATH . "inc/prepend.inc.php" include_once INCLUDE_PATH . "lib/foo.class.php"; include_once INCLUDE_PATH . "lib/View.class.php"; // Actions (if we're lucky) $foo = new Foo(); $data = $foo->getData(); // Display (if we're lucky) $view = new View(INCLUDE_PATH . 'tpl/'); $view->assign($data); echo $view->fetch('template.tpl'); // Teardown include_once INCLUDE_PATH . "inc/append.inc.php"; 11
  12. 12. Standalone Application: Typical Include File // expects certain globals if (! defined('APP_CONSTANT')) {     die("Direct access not allowed."); } 12
  13. 13. Standalone Application: Typical File Structure index.php # main pages page1.php # page2.php # page3.php # sub/ # sub-section index.php # zim.php # gir.php # inc/ # includes config.inc.php # prepend.inc.php # lib/ # libraries foo.class.php # Bundle1/ # Bundle2/ # 13
  14. 14. Standalone Application: Support Structure bin/ # command-line tools cache/ # cache files css/ # stylesheets docs/ # documentation img/ # images install/ # installation scripts js/ # javascript log/ # log files sql/ # schema migrations theme/ # themes or skins tpl/ # templates -- no standard naming or structure -- index.html file in each directory 14
  15. 15. Project Evolution Tracks One-Off Heap Standalone App Library ? Modular App Collection Framework CMS 15
  16. 16. Modular Application • Standalone application ++ • Same file structure and script style • One additional directory: “modules”, “plugins”, etc • Hooks in the “main” scripts for additional behaviors • Use global variables to coordinate between modules 16
  17. 17. CMS • Modular application ++ • General-purpose application broker • All "main" scripts become sub-applications • Still in the web root, still using globals to coordinate 17
  18. 18. Application/CMS Projects • Achievo • Eventum • PhpMyAdmin • Code Igniter* • Gallery • Seagull* • Coppermine • Joomla/ • SugarCRM Mambo • DokuWiki • Vanilla • MediaWiki • Drupal • WordPress 18
  19. 19. Project Evolution Tracks One-Off Heap Standalone App Library ? Modular App Collection Framework CMS 19
  20. 20. Library Collection • Specific, limited logic extracted from an app • Re-used directly in unrelated applications and other libraries • No global variables • Class-oriented • Can exist anywhere in the file system 20
  21. 21. Library Project: Typical File Structure Foo.php # Foo Foo/ # Component.php # Foo_Component Component/ # Element1.php # Foo_Component_Element1 Element2.php # Foo_Component_Element2 Bar.php # Bar Bar/ # Task.php # Bar_Task Part/ # Part1.php # Bar_Task_Part1 Part2.php # Bar_Task_Part2 21
  22. 22. Framework • Codebase • Library collection • Apps extend from it • Support structure • Bootstrap file • Public assets • Protected assets 22
  23. 23. Library/Framework Projects • AdoDB • Lithium • Savant • Cake • Mojavi/Agavi • Seagull * • CgiApp • PAT • Smarty • Code Igniter * • PEAR • Solar • Doctrine • PHP Unit • SwiftMailer • EZ Components • Phing • Symfony • HtmlPurifier • Phly • WACT • Horde • Prado • Zend Framework 23
  24. 24. Project Evolution Tracks class- One-Off include- oriented Heap oriented Standalone App Library ? Modular App Collection Framework CMS 24
  25. 25. The One Lesson; or, “Step 2: ... ?” 25
  26. 26. Organize your project as if it is a library collection.
  27. 27. Elements of The One Lesson • Stop using globals • Namespace everything • Class-to-file naming 27
  28. 28. 1. Stop Using Globals • Stop using register_globals • Stop using $GLOBALS • Stop using global 28
  29. 29. 2. Namespace Everything • Automatic deconfliction of identifiers • Classes (“vendor”) • Functions, variables, constants • Use with $_SESSION, $_COOKIE, etc. keys 29
  30. 30. Choosing a Namespace • Project, client, brand, channel • A short word or acronym, not a letter (“Z”) • A unique name, not a generic name related to a task (Date, HTML, RSS, Table, User) 30
  31. 31. PHP 5.2 “Namespaces” // class User {} class Vendor_User {} $user = new Vendor_User(); // function get_info() {} function vendor_get_info() // $_SESSION["user_prefs"] $_SESSION["Vendor_User"]["prefs"]; 31
  32. 32. PHP 5.3 Namespaces namespace vendor; class User {} // relative namespace namespace vendor; $user = new User(); // absolute namespace namespace other; $user = new vendorUser(); 32
  33. 33. 3. Class-To-File Naming • Class name maps directly to file name • Vendor_User => Vendor/User.php • Horde, PEAR, Solar, Zend, others • Highly predictable file locations • Lends itself to autoloading 33
  34. 34. Class-to-File Naming (PHP 5.2, Horde/PEAR) // studly-caps needs preg_replace(), but: VendorAuthOpenId => ... Vendor/Auth/Open/Id.php? Vendor/Auth/OpenId.php? // underscores just need str_replace() Vendor_Auth_OpenId => Vendor/Auth/OpenId.php 34
  35. 35. Class-to-File (PHP 5.3, PSR-0) foo_barpkgMain => /foo_bar/pkg/Main.php foo_barpkgMain_Sub => /foo_bar/pkg/Main/Sub.php • PEAR, Solar, Zend, Doctrine, Lithium, Symfony 2 35
  36. 36. The One Lesson In Practice; or, “Step 3: Profit!” 36
  37. 37. Extended Effects of The One Lesson • Can be used anywhere (app, module, lib, CMS, framework) • Structure for refactoring and additions • Testing, profiling, and public files can parallel the same structure • Intuitive for new developers • No more include-path woes 37
  38. 38. Mambo CMS administrator/ components/ editor/ files/ help/ images/ includes/ Vendor/ index.php installation/ language/ mainbody.php mambots/ media/ modules/ templates/ 38
  39. 39. Zend Framework project/ application/ bootstrap.php configs/ controllers/ models/ views/ helpers/ scripts/ library/ Zend/ Vendor/ public index.php 39
  40. 40. Lithium app/ config/ controllers/ extensions/ index.php libraries/ models/ resources/ tests/ views/ webroot/ libraries/ lithium/ vendor/ 40
  41. 41. Symfony 2 hello/ config/ console/ HelloKernel.php src/ Application/ HelloBundle/ Bundle.php Controller/ Resources/ autoload.php vendor/ symfony/ zend/ vendor/ web/ 41
  42. 42. Solar system/ config/ config.php docroot/ index.php public/ include/ Solar.php Solar/ Vendor/ script/ source/ sqlite/ tmp/ 42
  43. 43. Solar Apps Are Libraries Too include/ Solar/ Vendor/ App/ Page.php Page/ Layout/ Locale/ Public/ View/ Model/ Gir.php Gir/ Zim.php Zim/ 43
  44. 44. Refactoring • Move from existing include-based architecture to class-based architecture ... • ... by functionality • ... by script • Then build scripts out of classes, not includes • Then build apps out of classes, not scripts • Leads to MVC / MVP / PAC architecture 44
  45. 45. Summary
  46. 46. The One Lesson • Organize your project as if it will be part of a library collection • Avoid globals • Use namespaces for deconfliction • Use class-to-file naming convention 46
  47. 47. Goals for Organizing • Security • Integration and extension • Adaptable to change • Predictable and maintainable • Teamwork consistency • Re-use rules on multiple projects 47
  48. 48. • Questions? • Comments? • Criticism? 48
  49. 49. Thanks! • <http://paul-m-jones.com> • <http://solarphp.com> • Solar Framework talk on Thursday • <http://joind.in/1289> 49
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×