On Github nihiliad / umn-code-people-php-2013
David Naughton: UMN Libraries Web Development
Not sure I agree with that last phrase, but the title is accurate for most of us.
— Jordi Boggiano, Composer Co-Creator
packagist.org: 18,500 packages.
Almost doubled since April!
After installing Composer...
$ cd app-package-dir/ $ vi composer.json
Declare a dependency:
{ "require": { "guzzle/guzzle": "v3.7.4" } }
Install it:
$ composer install
Composer automatically generates a PSR-0-compliant autoloader.
require 'app-package-dir/vendor/autoload.php'; $client = new \Guzzle\Http\Client('http://guzzlephp.org'); $request = $client->get('/'); $response = $request->send();
{ "require": { "umnlib/config": "*" }, "repositories": [ { "type": "vcs", "url": "git@github.umn.edu:Libraries/config-php.git" } ] }
(Composer can search multiple repository types for packages: packagist.org, github, PEAR...)
— Larry Garfield
Drupal core contributor, Drupal 8 Web Services Lead, Senior Architecht and Consultant at Palantir.net
Composer: There's a Module (or Library) for That
DrupalCon Portland 2013
PHP Standard Requests, e.g. PSR-0
Drupal, Symfony, almost all major projects participate.
phpDocumentor has won, set the PHPDoc standard, and is now available via Composer!
/** * Short description. * * Long description. This text may contain * multiple lines and even some _markdown_. * * * Markdown style lists function too * * Just try this out once * * @param int $example Example function/method parameter description. * @param string $example2 Second example. */
Define your own DocBlock annotations with the Doctrine ORM's annotations component:
namespace MyProject\Entities; use Doctrine\ORM\Mapping AS ORM; use Symfony\Component\Validation\Constraints AS Assert; /** * @ORM\Entity * @MyProject\Annotations\Foobarable */ class User {}
...or anonymous functions, introduced in 5.3:
$input = array(1, 2, 3, 4, 5); $output = array_filter($input, function ($v) { return $v > 2; }); // or... $max_comparator = function ($v) { return $v > 2; }; $output = array_filter($input, $max_comparator);
Don't use create_function!
$max_comparator = create_function('$v', 'return $v > 2;');
Lamdbas with state, i.e. anonymous functions that are "closed over" variables from the surrounding scope:
$x = 1; $incrementor = function() use (&$x) { return ++$x; } $incrementor(); // 2 $incrementor(); // 3 $incrementor(); // 4
Lambdas and closures allow functional programming, even the infamous Y-Combinator:
function Y($F) { $func = function ($f) { return $f($f); }; return $func(function ($f) use($F) { return $F(function ($x) use($f) { $ff = $f($f); return $ff($x); }); }); }
New in 5.4, traits provide OO reuse without inheritance, like interfaces, but with implementation:
class Base { public function sayHello() { echo 'Hello '; } } trait SayWorld { public function sayHello() { parent::sayHello(); echo 'World!'; } } class MyHelloWorld extends Base { use SayWorld; } $o = new MyHelloWorld(); $o->sayHello(); // Hello World!
For the theory, see Traits - Composable Units of Behavior.
New in 5.5, generators allow for very simple and easy implementation of iterators:
function fibonacci() { $last = 0; yield 0; $current = 1; yield 1; while (true) { $current = $last + $current; $last = $current - $last; yield $current; } } // Prints the first sixteen Fibonacci numbers: foreach (fibonacci() as $n => $Fn) { echo "F[$n] = $Fn\n"; if ($n == 15) break; // Prevent an infinite loop! }
An equivalent way to generate the Fibonacci numbers, by calling methods from the Iterator interface, which Generator implements:
$generator = fibonacci(); $reflector = new ReflectionClass($generator); $reflector->getName(); // Generator $reflector->getInterfaceNames(); // Iterator, Traversable while ($generator->valid()) { $n = $generator->key(); $Fn = $generator->current(); echo "F[$n] = $Fn\n"; if ($n == $limit) break; // Prevent an infinite loop! $generator->next(); }