Lean Php Presentation

14,702 views

Published on

Overview of issues with doing lean development in PHP -- Project Management, Testing, and Community.

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
14,702
On SlideShare
0
From Embeds
0
Number of Embeds
13
Actions
Shares
0
Downloads
58
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Lean Php Presentation

  1. 1. Lean PHP Practices Alan Pinstein & Jason Ardell Atlanta PHP Users Group April 1, 2009
  2. 2. What is Leverage? More work the first time, usually involves: Learning a new library or tool Setting up infrastructure Easier to do it 2..∞ Easier to maintain
  3. 3. Types of Leverage Project Leverage Testing Leverage Community Leverage
  4. 4. Project Leverage It hurts when I... Set up my project on a new machine Deploy new versions of my project Stop doing that!
  5. 5. Project Leverage - Tools mp - Migrations for PHP (presentation) rake/cap => pantr is php gitflow user_management Dependency management runit - daemons / process supervision config-magic
  6. 6. runit Process Supervisor Don’t write daemons - you’ll do it wrong Write scripts, and runit keeps them alive in the background Gracefully handles errors, failures, logging, upgrades
  7. 7. runit in action // graceful upgrade 2010-02-10_03:53:55 Stop requested for worker process on queue: inbox 2010-02-10_03:53:55 Stopping worker process on queue: inbox 2010-02-10_03:53:56 Starting worker process on queue: inbox // graceful error handling 2010-04-01_17:55:08 [Job: 383820 RUNNING] Process InboxImage 60629 (Carol 011_fi.jpg) 2010-04-01_17:55:08 [Job: 383820 COMPLETED] 2010-04-01_17:55:08 JQWorker doesn't have enough memory for next job (4194304). 2010-04-01_17:55:08 Starting worker process on queue: inbox 2010-04-01_17:55:09 [Job: 383821 RUNNING] Process InboxImage 60622 (Carol 015_fi.jpg) 2010-04-01_17:55:09 [Job: 383821 COMPLETED]
  8. 8. config-magic N config files * M environments = Too Many Config Files Config-Magic applies “profiles”: dev-alan, dev-jason, staging, production to “templates”: framework, orm, rake, cap, shell scripts, webserver
  9. 9. # config.ini [templates] httpd.configFileTemplate = ##TEMPLATES_DIR##/##CONFIG##.conf httpd.configFile = ##OUTPUT_DIR##/##CONFIG##.conf propel-conf.configFileTemplate = ##TEMPLATES_DIR##/virtualtour-conf.php propel-conf.configFile = ##OUTPUT_DIR##/virtualtour-conf.php propel-build-properties.configFileTemplate = ##TEMPLATES_DIR##/build.properties propel-build-properties.configFile = ##OUTPUT_DIR##/../propel-build/ build.properties propel-conf-xml.configFileTemplate = ##TEMPLATES_DIR##/runtime-conf.xml propel-conf-xml.configFile = ##OUTPUT_DIR##/../propel-build/runtime-conf.xml webapp.configFileTemplate = ##TEMPLATES_DIR##/##CONFIG##.conf webapp.configFile = ##OUTPUT_DIR##/##CONFIG##.conf sh.configFileTemplate = ##TEMPLATES_DIR##/##CONFIG##.conf sh.configFile = ##OUTPUT_DIR##/##CONFIG##.conf [data] ; your default data here. any settings here will be overridden by values in the profile's ini file on a setting-by-setting basis isProduction = false path.psql = /usr/bin/psql path.convert = /usr/bin/convert path.propel-gen = externals/pear/propel-gen path.phocoa = ##path.project.appDir##/externals/phocoa/phocoa path.php.include_path = ##path.phocoa##:##path.project.appDir##:##path.project.appDir##/ classes:##path.project.appDir##/externals:##path.project.appDir##/externals/pear/php path.php = "/usr/bin/php -d include_path=##path.php.include_path##" app.group = showcase_web app.user = tourbuzz httpd.user = _www
  10. 10. # profile - dev.ini path.php = "/opt/local/bin/php -d include_path=##path.php.include_path##" path.project.containerDir = /Users/ardell/Documents/workspace/ tourbuzz path.project.appDir = ##path.project.containerDir##/tourbuzz path.awstats = /opt/showcase/awstats/wwwroot/cgi-bin/awstats.pl path.convert = /opt/local/bin/convert path.psql = /opt/local/lib/postgresql83/bin/psql host.name = ardell.dev.tourbuzz.net host.aliases = host.ip = 127.0.0.1 host.port = 8080 db.host = localhost db.name = virtualtour_dev db.user = virtualtour db.pass = app.user = ardell app.group = tourbuzz_web runit.system_service_dir = /opt/local/var/service
  11. 11. # template #!/bin/sh PHP="##path.php##" export PSQL=##path.psql## export IS_PRODUCTION=<?php print ($profileData ['##isProduction##'] ? 1 : 0); ?> # db settings export DB_ROOT_USER=##db.root.user## export DB_USER=##db.user## export DB_NAME=##db.name## export DB_HOST=##db.host## export PROJECT_DIR=##path.project.containerDir## export LOG_DIR=$PROJECT_DIR/log export APP_DIR=##path.project.appDir## export APP_USER=##app.user## export APP_GROUP=##app.group##
  12. 12. $ cfg dev #!/bin/sh PHP="/opt/local/bin/php -d include_path=/Users/alanpinstein/dev/sandbox/ virtualtour/tourbuzz/externals/phocoa/phocoa:/Users/alanpinstein/dev/sandbox/ virtualtour/tourbuzz:/Users/alanpinstein/dev/sandbox/virtualtour/tourbuzz/ classes:/Users/alanpinstein/dev/sandbox/virtualtour/tourbuzz/externals:/Users/ alanpinstein/dev/sandbox/virtualtour/tourbuzz/externals/pear/php" export PSQL=/opt/local/lib/postgresql83/bin/psql export IS_PRODUCTION=0 # db settings export DB_ROOT_USER=postgres export DB_USER=virtualtour export DB_NAME=virtualtour_dev export DB_HOST=localhost export PROJECT_DIR=/Users/alanpinstein/dev/sandbox/virtualtour export LOG_DIR=$PROJECT_DIR/log export APP_DIR=/Users/alanpinstein/dev/sandbox/virtualtour/tourbuzz export APP_USER=alanpinstein export APP_GROUP=showcase_web
  13. 13. Testing Leverage It hurts when I... Refactor Introduce regression bugs Don’t have confidence that my code works Have to test my web pages in N browsers
  14. 14. Testing Leverage -Tools Write Testable Code - Miško Hevery This is the hard part - there are good tools for the rest Writing Tests (PHPUnit) Mocking Collaborators - $this->getMock(‘MyClass’) Scenario-based Tests - @dataProvider Bootstrapping Data (Fixturenator) Selenium RC - SauceLabs Hosted Browsers
  15. 15. fixturenator Test Data doesn’t always scale Makes it easy to decouple tests from test data Prototypal Test Data Generation Inspired by factory_girl
  16. 16. fixturenator - Define Objects // Static data for each instance Fixturenator::define('User', array('username' => 'joe')); Fixturenator::define('User', function($factory) { $factory->username = 'joe'; }); Fixturenator::define('User', create_function('$factory', ' $factory->username = 'joe'; '}); // Dynamism $user = Fixturenator::create('User', array('password' => 'return rand (1000,9999);')); $user = Fixturenator::create('User', array('email' => 'return "{$o- >username}@domain.com";')); // Sequences Fixturenator::createSequence('username', 'return "username{$n}";'); Fixturenator::getSequence('username')->next(); // => username1 Fixturenator::getSequence('username')->next(); // => username2
  17. 17. fixturenator - Build Object Graphs // Factory.php Fixturenator::define('ValidUser', array('username' => 'joe')); // Test.php // Returns an unsaved User instance $user = Fixturenator::create('ValidUser'); // Customize the generated object $user = Fixturenator::create('ValidUser', array('password' => '1234')); $this->assertTrue($user->validate()); $user->setPassword(NULL); // User requires password $this->assertFalse($user->validate());
  18. 18. Community Leverage It hurts when I.... Try to share my PHP libraries with other people Re-write code that I know already exists Try to fix bugs in projects that aren’t my own
  19. 19. Community Leverage - Tools Pearfarm (Gemcutter for PHP) A Community PEAR Server Trivially Easy to Make PEAR Packages “App Store” Effect GitHub Social Coding Infrastructure Easy to contribute / accept contributions “App Store” Effect
  20. 20. pearfarm $spec = Pearfarm_PackageSpec::create(array(Pearfarm_PackageSpec::OPT_BASEDIR => dirname(__FILE__))) ->setName('fixturenator') ->setChannel('apinstein.pearfarm.org') ->setSummary('A factory-based fixture generator.') ->setDescription('AWESOME.') ->setReleaseVersion('0.0.3') ->setReleaseStability('alpha') ->setApiVersion('0.0.3') ->setApiStability('alpha') ->setLicense(Pearfarm_PackageSpec::LICENSE_MIT) ->setNotes('http://github.com/apinstein/fixturenator') ->addMaintainer('lead', 'Alan Pinstein', 'apinstein', 'apinstein@mac.com') ->addFilesSimple('Fixturenator.php');
  21. 21. PHP really needs... CLI Framework (for building good tools) Project Management (rake/cap) PEAR/Dependency Management Efficient PEAR install/upgrades Non-PEAR code: php/lib/exec Better Community More Quality Contributions More Cooperation More Use of Modern Language Features

×