Created
November 12, 2011 03:41
-
-
Save tomnomnom/1360001 to your computer and use it in GitHub Desktop.
Mungeable PHP objects - playing with PHP 5.4 RC1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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