On Github nihiliad / code-people-cutting-edge-php
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();
}