On Jan 15, 2008 6:51 AM, Jochem Maas <jochem@xxxxxxxxxxxxx> wrote: > Nathan Nobbe schreef: > > when it comes to create_function(), id say its just as painful as > building > > functions with html or writing queries by hand. namely, its prone to a > lot > > of string escaping which produces awful hard to read code. i mean, the > > kind of code you write yourself and then look at a week later and say > > 'what a mess'... > > agreed - in fact I think I have resorted to create_function only once, > generally > when I 'need' it I just resort to writing a std. function that is defined > in > or around the code that uses it (as opposed to defining the function in a > suitable > functions-only include file) - and give it some oddball name that will > never > cause name collisions (e.g. A2mkITdoFooBarSWmagicLanternStuff1timeBla() - > completely > unreadable ofcourse but for a throw away used 5 lines up or down it will > do :-) > > > anyway, it occurs to me that the closest thing php has to functional > > languages, > > thats readily usable is the variable function mechanism > > http://www.php.net/manual/en/functions.variable-functions.php > > theres been discussion about it on the list in the past, though often it > is > > spoken of as a ghost feature. its quite nice. > > as an example, suppose you have a string > > $blah = 'myFunc'; > > then if myFunc is defined as a function, it can be invoked per > > $blah(/* params */); > > > > it creates the ability to do all sorts of powerful things, such as > > delegation > > whereby switch statements can be eliminated, callbacks, whereby a formal > > parameter could be a string that refers to a method name, and they work > > on object references as well. so you can get away w/ > > $this->$dynamicFuncName(/* params*/); > > there is a more generic form of callback .. as used by call_user_func*() > which, if used in conjunction with is_callable() can be a very neat way of > doing something that resembles meta-programming (okay I'm stretching the > boat here) > > at the very least it allows you a clean and tidy way of introducing > functionality > into your code that can be run automatically regardless and without > breakage, > in situations where you don't know at run time if the something will exist > (e.g. some optional CMS module) - following is a silly, contrived example > to > give some idea of what can be done: > > class foo { > private $handlers = array(); > static function setHandler($cb) { > if ($cb && is_callable($cb)/* && !in_array($cb, > self::$handlers) */) > self::$handlers[] = $cb; > } > > static function doStuff() { > foreach(self::$handlers as $cb) > call_user_func($cb); > } > } > > class bar { > function __construct() { > foo:setHandler( array($this, 'magic') ); > } > > function magic() { > /* er? */ > } > } > > and if you add interfaces and a bit of reflection into the game you can > get real funky ;-) > when i said a function would have to be loaded into the interpreter to avoid a runtime error upon invocation, i didnt mention that its best to programatically verify it can be called before letting the runtime error occur (of course you can let that happen if you prefer :)), to avoid it. anywho, i prefer the variable function construct more than call_user_func(), simply because it feels a bit more natural to me, but semantically, they are the same, they just have a different syntax is all. i suppose call_user_func() is a bit more clear and might help some people when drifting through the code of others. cool contrived example, btw ;) -nathan