note 105901 added to functions.anonymous
| From: | hernan_javier_saab at yahoo dot com | 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