Skip to content

Instantly share code, notes, and snippets.

@johnkary
Last active August 29, 2015 14:14
Show Gist options
  • Save johnkary/344902d13e6d87fac6e8 to your computer and use it in GitHub Desktop.
Save johnkary/344902d13e6d87fac6e8 to your computer and use it in GitHub Desktop.
http://3v4l.org/tTreF -- 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
<?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;
// ... is variadic function syntax. See: http://php.net/manual/en/functions.arguments.php#functions.variable-arg-list
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) {
$mailer->setLazy(true);
}
}
function SuperLazy() {
return function(\Mailer\Mailer $mailer) {
$mailer->setLazy(true);
};
}
}
namespace {
use function \Mailer\Options\SuperLazy;
// Anonymous functions configure Mailer
// Wire up as many as needed for optional settings and pass as constructor arguments
$tls = function (\Mailer\Mailer $mailer) {
echo 'LOL Lets do some TLS --';
};
// Any one of these $lazy vars can be passed as options arguments
// 1. Anonymous function
$lazy1 = function (\Mailer\Mailer $mailer) {
$mailer->setLazy(true);
};
// 2. Object that responds to being used like a function via __invoke()
$lazy2 = new \Mailer\Options\Lazy;
// 3. Namespaced function (must return an anonymous function)
$lazy3 = SuperLazy();
$mailer = new \Mailer\Mailer('www.gmail.com', $tls, $lazy3); // Add any function options to your liking
echo $mailer->isLazy() ? 'Yes lazy' : 'No lazy';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment