SlideShare una empresa de Scribd logo
1 de 21
Descargar para leer sin conexión
Lean PHP Practices
           Alan Pinstein & Jason Ardell
             Atlanta PHP Users Group
                          April 1, 2009
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
Types of Leverage


Project Leverage
Testing Leverage
Community Leverage
Project Leverage

It hurts when I...
  Set up my project on a new machine
  Deploy new versions of my project
Stop doing that!
Project Leverage - Tools
 mp - Migrations for PHP (presentation)
 rake/cap => pantr is php
  gitflow
  user_management
  Dependency management

 runit - daemons / process supervision
 config-magic
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
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]
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
# 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
# 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
# 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##
$ 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
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
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
fixturenator

 Test Data doesn’t always scale
 Makes it easy to decouple tests from test data
 Prototypal Test Data Generation
 Inspired by factory_girl
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
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());
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
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
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');
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

Más contenido relacionado

La actualidad más candente

Php hypertext pre-processor
Php   hypertext pre-processorPhp   hypertext pre-processor
Php hypertext pre-processor
Siddique Ibrahim
 
Beginners PHP Tutorial
Beginners PHP TutorialBeginners PHP Tutorial
Beginners PHP Tutorial
alexjones89
 

La actualidad más candente (20)

PHP
PHPPHP
PHP
 
php
phpphp
php
 
Introduction to php
Introduction to phpIntroduction to php
Introduction to php
 
Php Presentation
Php PresentationPhp Presentation
Php Presentation
 
A History of PHP
A History of PHPA History of PHP
A History of PHP
 
Php technical presentation
Php technical presentationPhp technical presentation
Php technical presentation
 
PHP programmimg
PHP programmimgPHP programmimg
PHP programmimg
 
Php ppt
Php pptPhp ppt
Php ppt
 
Php Ppt
Php PptPhp Ppt
Php Ppt
 
Php hypertext pre-processor
Php   hypertext pre-processorPhp   hypertext pre-processor
Php hypertext pre-processor
 
PHP Function
PHP Function PHP Function
PHP Function
 
Php.ppt
Php.pptPhp.ppt
Php.ppt
 
PHP Tutorials
PHP TutorialsPHP Tutorials
PHP Tutorials
 
PHP-MySQL Database Connectivity Using XAMPP Server
PHP-MySQL Database Connectivity Using XAMPP ServerPHP-MySQL Database Connectivity Using XAMPP Server
PHP-MySQL Database Connectivity Using XAMPP Server
 
MySQL Presentation
MySQL PresentationMySQL Presentation
MySQL Presentation
 
01 Php Introduction
01 Php Introduction01 Php Introduction
01 Php Introduction
 
Php Ppt
Php PptPhp Ppt
Php Ppt
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
 
Beginners PHP Tutorial
Beginners PHP TutorialBeginners PHP Tutorial
Beginners PHP Tutorial
 
Introduction to php web programming - get and post
Introduction to php  web programming - get and postIntroduction to php  web programming - get and post
Introduction to php web programming - get and post
 

Destacado

PHP
PHPPHP
Unify Your Deliverables
Unify Your DeliverablesUnify Your Deliverables
Unify Your Deliverables
nathanacurtis
 

Destacado (20)

PHP presentation
PHP presentationPHP presentation
PHP presentation
 
Apache
ApacheApache
Apache
 
Php Tutorials for begginners
Php Tutorials for begginnersPhp Tutorials for begginners
Php Tutorials for begginners
 
Threads in PHP - Presentation
Threads in PHP - Presentation Threads in PHP - Presentation
Threads in PHP - Presentation
 
Core Php Component Presentation
Core Php Component PresentationCore Php Component Presentation
Core Php Component Presentation
 
PHP
PHPPHP
PHP
 
Php oop presentation
Php   oop presentationPhp   oop presentation
Php oop presentation
 
Beginning web programming with PHP [PHP 101-02]
Beginning web programming with PHP [PHP 101-02]Beginning web programming with PHP [PHP 101-02]
Beginning web programming with PHP [PHP 101-02]
 
Devise | Presentation for Alpharetta PHP / Laravel Group
Devise | Presentation for Alpharetta PHP / Laravel GroupDevise | Presentation for Alpharetta PHP / Laravel Group
Devise | Presentation for Alpharetta PHP / Laravel Group
 
Unify Your Deliverables
Unify Your DeliverablesUnify Your Deliverables
Unify Your Deliverables
 
PHP .ppt
PHP .pptPHP .ppt
PHP .ppt
 
Responsive Web Design
Responsive Web DesignResponsive Web Design
Responsive Web Design
 
Internationalisation with PHP and Intl
Internationalisation with PHP and IntlInternationalisation with PHP and Intl
Internationalisation with PHP and Intl
 
Introduction of Html/css/js
Introduction of Html/css/jsIntroduction of Html/css/js
Introduction of Html/css/js
 
Php string function
Php string function Php string function
Php string function
 
PHP Tour 2016 Phinx Presentation
PHP Tour 2016 Phinx PresentationPHP Tour 2016 Phinx Presentation
PHP Tour 2016 Phinx Presentation
 
Wordpress Underscores & foundation5
Wordpress Underscores & foundation5Wordpress Underscores & foundation5
Wordpress Underscores & foundation5
 
Php string
Php stringPhp string
Php string
 
Design for Developers: Introduction to Bootstrap 3
Design for Developers: Introduction to Bootstrap 3Design for Developers: Introduction to Bootstrap 3
Design for Developers: Introduction to Bootstrap 3
 
HTML CSS & Javascript
HTML CSS & JavascriptHTML CSS & Javascript
HTML CSS & Javascript
 

Similar a Lean Php Presentation

Behavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWestBehavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWest
Joshua Warren
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
Michelangelo van Dam
 
From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012
Carlos Sanchez
 
From Dev to DevOps - Apache Barcamp Spain 2011
From Dev to DevOps - Apache Barcamp Spain 2011From Dev to DevOps - Apache Barcamp Spain 2011
From Dev to DevOps - Apache Barcamp Spain 2011
Carlos Sanchez
 

Similar a Lean Php Presentation (20)

Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
Advanced Eclipse Workshop (held at IPC2010 -spring edition-)
 
Harmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and PuppetHarmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and Puppet
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
 
Behavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWestBehavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWest
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
A General Purpose Docker Image for PHP
A General Purpose Docker Image for PHPA General Purpose Docker Image for PHP
A General Purpose Docker Image for PHP
 
Php task runners
Php task runnersPhp task runners
Php task runners
 
From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012
 
From Dev to DevOps - Apache Barcamp Spain 2011
From Dev to DevOps - Apache Barcamp Spain 2011From Dev to DevOps - Apache Barcamp Spain 2011
From Dev to DevOps - Apache Barcamp Spain 2011
 
Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)
Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)
Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
 
Workshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfastWorkshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfast
 
2019 11-bgphp
2019 11-bgphp2019 11-bgphp
2019 11-bgphp
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
 
Simplify your professional web development with symfony
Simplify your professional web development with symfonySimplify your professional web development with symfony
Simplify your professional web development with symfony
 
Introduction to PowerShell
Introduction to PowerShellIntroduction to PowerShell
Introduction to PowerShell
 
DevOps in PHP environment
DevOps in PHP environment DevOps in PHP environment
DevOps in PHP environment
 

Último

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Último (20)

Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 

Lean Php Presentation

  • 1. Lean PHP Practices Alan Pinstein & Jason Ardell Atlanta PHP Users Group April 1, 2009
  • 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. Types of Leverage Project Leverage Testing Leverage Community Leverage
  • 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. 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. 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. 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. 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. # 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. # 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. # 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. $ 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. 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. 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. 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. 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. 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. 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. 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. 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. 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