note 105901 added to functions.anonymous

From: Date: Sat, 24 Sep 2011 04:54:18 +0000
Subject: note 105901 added to functions.anonymous
Groups: php.notes 
Request: Send a blank email to php-notes+get-183399@lists.php.net to get a copy of this message
<?php /* * When invoking an anonymous function through throughThroughFunction(), all variables are automatically binded to the inner function. In addition, variables created within the anonymous function are also "binded out" incorporating it to the scope where the anonymous function is being created. Enjoy! */ class ThroughThrogh { public $to_export = array(); public $to_import = array(); // we eval() these functions in order to cleanup verbosity. Cleaner this way even though we all heard about the nightmares of eval() const TX_START_X = 'foreach(get_defined_vars() as $k=>$v){$this->to_export[$k] =&${$k};};'; const TX_START_I = 'foreach($that->to_export as $name => &$variable) ${$name} = &$variable;'; const TX_END_X = 'foreach(get_defined_vars() as $k=>$v){if(!isset($that->to_export[$k])) $that->to_import[$k] =&${$k};};'; const TX_END_I = 'foreach($this->to_import as $name => &$variable) ${$name} = &$variable;'; public function hackClosure($closure, $inject_start, $inject_end) { $reflection = new ReflectionFunction($closure); $tmp = $reflection->getParameters(); $args = array('$that'); foreach ($tmp as $a) array_push($args, '$' . $a->getName() . ($a->isDefaultValueAvailable() ? '=\'' . $a->getDefaultValue() . '\'' : '')); $file = new SplFileObject($reflection->getFileName()); $file->seek($reflection->getStartLine() - 1); $code = ''; while ($file->key() < $reflection->getEndLine()) { $code .= $file->current(); $file->next(); } $start = strpos($code, '{') + 1; $end = strrpos($code, '}'); return create_function(implode(', ', $args), "$inject_start;" . substr($code, $start, $end - $start) . "$inject_end;"); } //here is where we invoke the function public function throughThroughFunction($that, $callback){ $this->to_export["that"] = $that; $inject_start = self::TX_START_I;// potentially you can add setup code in here $inject_end = self::TX_END_X;// potentially you can add cleanup code in here $callback = $this->hackClosure($callback, $inject_start, $inject_end); call_user_func($callback, $that); } //user test public function test(){ $outscope = "Source External Scope: test... not modified if seen at end of function\n"; $this->test = "Source External Scope: object attribute from outside anonymous function\n"; eval($this::TX_START_X); //required to export all variables from scope $this->throughThroughFunction($this, function(){ echo "Source Anonymous Function\n"; echo $outscope; echo $that->test; $that->test = "Source Anonymous Function Scope: wow! Object attribute modified from inside anonymous function\n"; $outscope = "Source Anonymous Function Scope: yey! Variable Modified from the scope of an anonymous function!\n"; $from_anonymous_function = "Source Anonymous Function Scope: No way! How did you do that?\n"; } ); eval($this::TX_END_I); //require to bring newly created variables from anonymous function into current scope echo "\nSource External Scope\n"; echo $from_anonymous_function; echo $outscope; echo $this->test; } } $demo = new ThroughThrogh(); $demo->test(); /* Output Source Anonymous Function Source External Scope: test... not modified if seen at end of function Source External Scope: object attribute from outside anonymous function Source External Scope Source Anonymous Function Scope: No way! How did you do that? Source Anonymous Function Scope: yey! Variable Modified from the scope of an anonymous function! Source Anonymous Function Scope: wow! Object attribute modified from inside anonymous function */ ---- Server IP: 64.71.164.2 Probable Submitter: 64.236.139.254 ---- Manual Page -- http://www.php.net/manual/en/functions.anonymous.php Edit -- https://master.php.net/note/edit/105901 Del: integrated -- https://master.php.net/note/delete/105901/integrated Del: useless -- https://master.php.net/note/delete/105901/useless Del: bad code -- https://master.php.net/note/delete/105901/bad+code Del: spam -- https://master.php.net/note/delete/105901/spam Del: non-english -- https://master.php.net/note/delete/105901/non-english Del: in docs -- https://master.php.net/note/delete/105901/in+docs Del: other reasons-- https://master.php.net/note/delete/105901 Reject -- https://master.php.net/note/reject/105901 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#183399) next »