Skip to content

Instantly share code, notes, and snippets.

@tomnomnom
Created November 12, 2011 03:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomnomnom/1360001 to your computer and use it in GitHub Desktop.
Save tomnomnom/1360001 to your computer and use it in GitHub Desktop.
Mungeable PHP objects - playing with PHP 5.4 RC1
<?php
/**
* Playing with some of PHP 5.4 RC1's features
*
* A trait to make an object "mungeable"; i.e. so you can "munge"
* methods (closures/lambdas) and properties into it.
*
* All methods and properties will be public.
*
* This is pure experimentation. Please do not attempt to derive any
* kind of best practices from it or use it as evidence for me being
* a terrible programmer or an otherwise terrible person.
*
* Tom Hudson 2011-11-12
*/
trait Mungeable {
// Note the shiny new short array syntax!
protected $methods = [];
protected $properties = [];
/**
* Add a method to the object
*/
public function method($name, Closure $closure){
// bindTo causes "$this" in the closure body to refer to the bound object
$this->methods[$name] = $closure->bindTo($this);
return $this;
}
/**
* Add a property to the object
*/
public function property($name, $value = null){
$this->properties[$name] = $value;
return $this;
}
public function __get($key){
return isSet($this->properties[$key])?
$this->properties[$key] : null;
}
public function __set($key, $value){
return $this->properties[$key] = $value;
}
public function __call($method, $arguments){
if (!isSet($this->methods[$method])){
throw new \BadMethodCallException(
"{$method} is not a valid method."
);
}
return call_user_func_array(
$this->methods[$method], $arguments
);
}
}
/**
* I hate contrived examples as much as the next guy or gal,
* but what's a little Greeter class between friends?
*/
class Greeter {
// Use the Mungeable trait; obviously.
use Mungeable;
protected $name;
public function __construct($name){
$this->name = $name;
}
/**
* Real methods can live alongside "munged" methods
*/
public function hello(){
return "Hello, {$this->name}!\n";
}
}
// All very standard so far...
$tomGreeter = new Greeter('Tom');
echo $tomGreeter->hello(); // Hello, Tom!
// It is possible to add munged properties at run-time
$tomGreeter->property('relative', 'mother');
// We can also add munged methods that refer to said properties
$tomGreeter->method('askAboutRelative', function(){
return "How's your {$this->relative}?\n";
});
echo $tomGreeter->askAboutRelative(); // How's your mother?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment