<?php
/**
* PHP 5.6 example of "Functional Options" as presented by Rob Pike
* in his article "Self-referential functions and the design of options"
* http://commandcenter.blogspot.com.au/2014/01/self-referential-functions-and-design.html
*/
namespace Mailer {
class Mailer {
private $host;
private $lazy = false;
public function __construct($host, ...$options) {
$this->host = $host;
foreach ($options as $option) {
$option($this);
}
}
// Wish this could be a private function and still be
// invoked by an options function so it's not mutable from the outside
public function setLazy($lazy) {
$this->lazy = $lazy;
}
public function isLazy() {
return $this->lazy;
}
}
}
namespace Mailer\Options {
class Lazy {
public function __invoke(Mailer $mailer) {
$mailer->setLazy(true);
}
}
function SuperLazy() {
return function(\Mailer\Mailer $mailer) {
$mailer->setLazy(true);
};
}
}
namespace {
use function \Mailer\Options\SuperLazy;
$tls = function (\Mailer\Mailer $mailer) {
echo 'LOL Lets do some TLS --';
};
// Any one of these $lazy vars can be passed as an option
$lazy1 = function (\Mailer\Mailer $mailer) {
$mailer->setLazy(true);
};
$lazy2 = new \Mailer\Options\Lazy;
$lazy3 = SuperLazy(); // Ughhh, I want to do `$lazy3 = SuperLazy;` but PHP won't let me
$mailer = new \Mailer\Mailer('www.gmail.com', $tls, $lazy3);
echo $mailer->isLazy() ? 'Yes lazy' : 'No lazy';
}