David Naughton: UMN Libraries Web Development
“There are only two kinds of programming languages: those people always bitch about and those nobody uses.”
“If someone can't find five things to hate about his favorite tool, he doesn't know it well enough to either advocate it or pull in the big dollars using it. He hasn't used it in enough different situations to fully explore it. He's advocating it as a culture or religion, which means that if I don't choose his favorite technology, I'm wrong.”
“I actually agree with the majority of what he said in his post [PHP: a fractal of bad design]. PHP is inconsistent. It is verbose. It does have a lot of weird behavior. It does have a lot of problems. It can be ugly. It can be really awkward to work around. It can leave a lot to be desired... But it's also incredibly powerful.”
“PHP is probably not the best language out there, and I'm the first one to scream about its quirks, but PHP is the best web platform... ever.”
Not sure I agree with that last phrase, but the title is accurate for most of us.
CPAN | 127,119 |
RubyGems | 65,484 |
npm | 46,451 |
PyPI | 36,377 |
PEAR | 595 |
“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, 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...)
“PHP sucks at sharing... Sharing is how open source works. Sucking at sharing is how open source dies.”
— 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();
}