Skip to content

Instantly share code, notes, and snippets.

@nfeldman
Created June 29, 2011 02:02
Show Gist options
  • Save nfeldman/1052756 to your computer and use it in GitHub Desktop.
Save nfeldman/1052756 to your computer and use it in GitHub Desktop.
more magic method abuse, more JSesque than ever
<?php
/**
* Objects of this class are superficially similar to JavaScript objects.
While you can never have quite the simplicity of the object literal in PHP
you can get pretty close. We're going to duplicate these two variations in
PHP as closely as we can.
// test one
var foo = {};
foo.hello = function (say) {
return 'Hello, ' + (say || 'world') + '!';
}
foo.prefix = 'Mr. ';
console.log(foo.hello('sailor')); // Hello, sailor!
console.log(foo.hello(foo.prefix + 'sailor')); // Hello, Mr. sailor!
// test two
var bar = {
hello: function (say) {
return 'Hello, ' + (say || 'world') + '!';
},
prefix: 'Mr. '
}
console.log(bar.hello('sailor')); // Hello, sailor!
console.log(bar.hello(foo.prefix + 'sailor')); // Hello, Mr. sailor!
*
*/
class DynamicObject {
private $properties = array();
public function __construct($assoc = array()) {
if ($assoc)
$this->add($assoc);
}
public function __set($name, $value = null) {
return !$value && is_array($name) ? $this->add($name) : $this->properties[$name] = $value;
}
public function __get($prop) {
return $this->properties[$prop] ? is_callable($this->properties[$prop]) ? 'function()' : $this->properties[$prop] : false;
} // todo: reflection or toString or something, for now, punt like Firebug--->^^^^^^^^^^^
public function __call($name, $args) {
return $this->properties[$name](implode(',', $args), $this);
}
private function add($assoc) {
foreach ($assoc as $k => $v)
$this->properties[$k] = $v;
}
}
// test one
$foo = new DynamicObject();
$foo->hello = function ($hello = 'world') {
return 'Hello, ' . $hello . "!\n";
};
$foo->prefix = 'Mr.';
echo $foo->hello($foo->prefix . ' sailor'); // Hello, Mr. sailor!
echo $foo->prefix; // Mr.
// test two
$bar = new DynamicObject(array(
'prefix' => 'Mr. ',
'hello' => function ($hello = 'world') {
return 'Hello, ' . $hello . "!\n";
}));
echo $bar->hello($bar->prefix . ' sailor'); // Hello, Mr. sailor!
echo $bar->prefix; // Mr.
// We can't do have an implicit 'this' when in an object context, because PHP
// doesn't work that way. But we have two options.
// Option One
$bar->dayAbbrs = array('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun');
$bar->getDayAbbr = function ($idx) {
echo $bar->dayAbbrs[--$idx];
};
$bar->getDayAbbr(3); // Wed
// Option Two
// Since we do always pass $this as the last argument when using __call, we can
// take advantage of that
$bar->monthAbbrs = array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
$bar->getMonthAbbr = function ($idx, $self) {
echo $self->monthAbbrs[--$idx];
};
$bar->getMonthAbbr(12); // Dec
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment