OSS, PHP, and PIE

Presented by Larry Garfield (@Crell)

Pollution

Pollution in the world
Pollution in the computer world

We have too much code

in the world

No Silver Bullet

1986

Fred Brooks
The Mythical Man Month
The most radical possible solution for constructing software
is not to construct it at all.

— "No Silver Bullet", 1986.

Commercial Off The Shelf (COTS)

The best way to attack the essence of building software
is not to build it at all.

— "'No Silver Bullet', Refired", 1995.

Hey, look, Open Source!

The logo of the Open Source Initiative

The way to be more productive is to write less code

The way to be more productive is to reuse more code

If a software engineer, a potential consumer of standardized software components, perceives it to be more expensive to find a component that meets his needs, and so verify, than to write one anew, a new, duplicative component will be written. Notice we said perceives above. It doesn't matter what the true cost of reconstruction is.

— Van Snyder, JPL
as quoted in "'No Silver Bullet', Refired", 1995.

Sharing must be easy or it won't happen

Sharing is how Open Source works

Sucking at sharing is how
Open Source dies

The olden days

PEAR

PEAR
  • PHP Extension and Application Repository
  • Founded 2000 on the "new" PHP 4
  • Required root to use properly (WTF?)
  • Complex process for adding packages
  • Easy to get wrong

Why we can't have nice things

Where do I find code?
PEAR and, um, blogs?
How do I get code?
Paste into your repository (or have root)
How do I load your code?
Manual includes
How do I load everyone's code?
Lots of manual includes
Name clashes?
YourProject_Before_Every_Single_Function()
How can I collaborate on code?
Sourceforge?
Can I exchange code?
LOLz

PHP sucked at sharing

Result

This is my island

There are many like it, but this one is mine

Drupal.org download page

2% of the web cares

Joomla.org download page

3% of the web cares

Wordpress.org download page

18% of the web cares

CakePHP download page

Who cares?

This was the best we could do

NIH is normal

PHP is the web

80% of the web cares

Source: W3Techs
The average PHP programmer has written 2.5
frameworks in his career.

— Urban legend statistics

You're not a real PHP developer until you've written your own CMS.

Sharing is how Open Source works

Sucking at sharing is how
Open Source dies

That was then

PHP is 18 years old

and is finally growing up

Step 0

Class autoloading

PHP 5.0, 2004

First version

function __autoload($class) {
  $file = some_logic($class);
  include $file;
}

Useful version

spl_autoload_register('myproject_autoloader');

function myproject_autoloader($class) {
  $file = some_logic($class);
  include $file;
}

Why we can't have nice things

Where do I find code?
PEAR and, um, blogs?
How do I get code?
Paste into your repository (or have root)
How do I load your code?
Autloading
How do I load everyone's code?
Lots of manual includes
Name clashes?
YourProject_Before_Every_Single_Function()
How can I collaborate on code?
Sourceforge?
Can I exchange code?
LOLz

Step 1

GitHub

2008

GitHub's OctoCat

Build software better, together

The Symfony project on GitHub

Like Drupal.org, but for everyone!

Better than Sourceforge et al by a wide margin.

Why we can't have nice things

Where do I find code?
PEAR and, um, blogs?
How do I get code?
Paste into your repository (or have root)
How do I load your code?
Autloading
How do I load everyone's code?
Lots of manual includes
Name clashes?
YourProject_Before_Every_Single_Function()
How can I collaborate on code?
GitHub
Can I exchange code?
LOLz

Step 2

Namespaces

PHP 5.3, June 2009

Before

class Zend_Form {}

class Application_Form_Guestbook extends Zend_Form {}

class sfForm() {}

Oh PEAR...

class Structures_DataGrid_DataSource_CSV {}

class Structures_DataGrid_DataSource_CSV_Memory
    extends Structures_DataGrid_DataSource_CSV {}

After

namespace Zend\Form;

class Factory{}
namespace Zend\Form;

use Zend\Captcha;

$factory = new Factory();
$captcha = new Captcha();
namespace Zend\Form;

use Zend\Captcha;
use Guzzle\Http\Client;

$factory = new Factory();
$captcha = new Captcha();
$guzzle = new Client();

Why we can't have nice things

Where do I find code?
PEAR and, um, blogs?
How do I get code?
Paste into your repository (or have root)
How do I load your code?
Autloading
How do I load everyone's code?
Lots of manual includes
Name clashes?
Namespaces
How can I collaborate on code?
GitHub
Can I exchange code?
LOLz

Step 3

The PHP Standards Group

php|tek, May 2009

The smoke filled room where FIG was founded.

(Smoke not guaranteed)

We're going to have these namespace things,
let's use them the same way for a change!

PSR-0

  • One autoloading standard/convention
  • Java-inspired
  • PEAR-inspired
  • Rudimentary, but enough

<vendor>\Package\Whatever

PSR-0

$root = '/some/root/path';

spl_autoload_register(function($class_name) use ($root) {
  $className = ltrim($className, '\\');
  if ($lastNsPos = strrpos($className, '\\')) {
    $namespace = substr($className, 0, $lastNsPos);
    $className = substr($className, $lastNsPos + 1);
    $fileName  = str_replace('\\', '/', $namespace) . '/';
  }
  $fileName .= str_replace('_', '/', $className) . '.php';

  $require $root . '/' . $fileName;
}

new Guzzle\Http\Client();
// require('/some/root/path/Guzzle/Http/Client.php');

Worst

Launch

Ever

Thrown off lists.php.net, moved to Google Groups

Admitted a few new projects

Slept through 2010

Debated a lot in 2011

Why we can't have nice things

Where do I find code?
PEAR and, um, blogs?
How do I get code?
Paste into your repository (or have root)
How do I load your code?
Autloading
How do I load everyone's code?
PSR-0
Name clashes?
Namespaces
How can I collaborate on code?
GitHub
Can I exchange code?
LOLz

Step 4

Composer

2011/2012

Composer logo

Symfony 2.0

  • Initial alpha, Symfony Live Paris, February 2010
  • PHPBB: We're rebuilding on it!
  • Symfony2 uses 3rd party libs (Doctrine, Monolog)

Dependency Hell

Dependencies are hell

We need a dependency system!

It's dumb to make it Symfony specific

—Jordi Boggiano

April 2011

Nils Aderman (PHPBB): libzypp -> PHP

Jordi Boggiano (Monolog): Packagist, front-end for PEAR

With their powers combined...

Composer is a tool for dependency management in PHP. It allows you to declare the dependent libraries your project needs and it will install them in your project for you.

Uhh, what?

  • No more Copy/Paste of libraries
  • Resolves dependencies
  • Each project defines its own requirements
  • Performs build tasks

September 2011

Packagist.org

I'd say until early 2012 it was pretty unusable, yet people used it. I guess that's how badly it was needed.

— Jordi Boggiano

Symfony 2.1

September 2012

Composer from the ground up

Package count

Number of packages on Packagist over time

April 2013: 10,000 packages

(Not just Symfony!)

Get Composer


# Quick-n-easy:
$ curl -sS https://getcomposer.org/installer | php

# Global
$ curl -sS https://getcomposer.org/installer | php -- --install-dir=bin

composer.json

Base manifest file for your project

{
    "name": "crell/myapp",
    "description": "This app is amazing.",
    "require": {
        "guzzle/guzzle": "3.4.*"
    },
    "autoload": {
        "psr-0": {
            "MyName\\MyPackage": "src/"
        }
    }
}

composer install

Installs all dependencies for your project


$ composer.phar install
Loading composer repositories with package information
Installing dependencies (including require-dev)
  - Installing symfony/event-dispatcher (v2.3.1)
    Downloading: 100%

  - Installing guzzle/guzzle (v3.4.3)
    Downloading: 100%

symfony/event-dispatcher suggests installing symfony/dependency-injection ()
symfony/event-dispatcher suggests installing symfony/http-kernel ()
Writing lock file
Generating autoload files

index.php

use Guzzle\Http\Client;

require_once __DIR__ . '/vendor/autoload.php';

// Every class is now yours to command!

// Autoload on demand! Your work: zero.
$client = new Client('https://api.github.com');
$request = $client->get('/user')->setAuth('user', 'pass');
$response = $request->send();
echo $response->getBody();

Why we can't have nice things

Where do I find code?
Packagist.org
How do I get code?
Composer
How do I load your code?
Autloading
How do I load everyone's code?
PSR-0
Name clashes?
Namespaces
How can I collaborate on code?
GitHub
Can I exchange code?
LOLz

Step 5

Common interfaces

2012-Present

PHP-FIG

The organization formerly known as the
PHP Standards Group and now represented by this web site

Became useful in 2012

Renamed to PHP Framework Interoperability Group, June 2012

New (first?) actual process definition, July 2013

PSR-3

Standard logger interface

Inspired by Monolog ... and Drupal

PSR-3

namespace Psr\Log;

interface LoggerInterface {
  public function log($level, $message, array $context = array());

  public function emergency($message, array $context = array());
  public function alert($message, array $context = array());
  public function critical($message, array $context = array());
  public function error($message, array $context = array());
  public function warning($message, array $context = array());
  public function notice($message, array $context = array());
  public function info($message, array $context = array());
  public function debug($message, array $context = array());
}

Cache PSR

Stay tuned... ;-)

Yes, we can have nice things

Where do I find code?
Packagist.org
How do I get code?
Composer
How do I load your code?
Autloading
How do I load everyone's code?
PSR-0
Name clashes?
Namespaces
How can I collaborate on code?
GitHub
Can I exchange code?
PHP-FIG standard interfaces

The way to be more productive is to write less code

The way to be more productive is to reuse more code

The way to be more productive is to share more code

Druplicon
 

The mission...

Drupal needs to evolve, and quickly, from a first-class web CMS into a first-class REST server that includes a first-class web CMS.
Hey, look, a first-class REST server!
Symfony

Drupal 8

  • Symfony2 (HttpFoundation, HttpKernel, DependencyInjection, EventDispatcher, Routing, Serializer, Validator, Yaml)
  • Symfony CMF
  • Zend Feed
  • Doctrine Annotations
  • Guzzle
  • EasyRDF
  • Assetic
  • Twig
  • PHPUnit

Drupal in Symfony

  • Flash Messages
  • BinaryFileResponse
  • Context support in Validator/Serializer
  • Routing improvements
  • Symfony CMF Router
  • Many other odds and ends

More collaboration

  • Doctrine Annotations Performance
  • Guzzle restructuring
  • Zend Feed dependencies

Symfony and Zend

Zend ProxyManager in DependencyInjection Component

Great news for Symfony!

We work better together

Of course we're still using Composer wrong

And we have no one blame but fear of the unknown

Drupal + Symfony = Drufony

The new normal

Given 2 ways to solve a problem,
choose the approach that results in less code

in the world

Not Invented Here

Proudly Invented Elsewhere

Proudly Invented Elsewhere is tasty.

We are no longer islands.

Drupal Island
If you want to go fast, go alone. If you want to go far, go together.

Our world is changing fast.

Let's go somewhere together.