PHP 4中是否有技巧来实现返回函数的函数?我希望以下代码可以工作:
function xxx($a) {
return function($b) {
print "a=$a, b=$b \n";
}
}
$f1 = xxx(1);
$f1(2);
不幸的是,在PHP 4中没有运气。可能它适用于PHP 5,但我仅限于PHP 4.
我尝试使用OO解决方法,但又失败了(类声明可能没有嵌套):
class Closure {
function run($a) {
print "raise: NotImplementedException, instead: $a\n";
}
}
class WantCheckNesting extends Closure {
function run($a, $b) {
class Nested extends Closure {
function run($c) {
print "a=$a, b=$b, c=$c\n";
}
}
$o = new Nested();
return $o;
}
}
$d = new WantCheckNesting();
$e = $d->run(2, 3);
$e->run(4);
有一个函数“create_function”,但它非常有限:正文必须是一个字符串。
还有其他想法吗?
答案 0 :(得分:4)
您可以在PHP 4中使用的唯一工具是create_function,并且可以将函数定义编写为字符串。
<?php
function getMyFunc($a){
return create_function('$b', 'print "a='.$a.', b=$b";');
}
$f1 = getMyFunc(1);
$f1(2);
?>
...但即使这对于您发布的示例来说很简单,对于更复杂的情况来说也绝对不实用。
答案 1 :(得分:0)
在PHP4中,您可以使用这样的变量函数,前提是您的函数已在范围内定义(因此不是真正的闭包)。
这是一个很难的代码。 这个测试没有多少。 这不是快速的(如果可能的话,甚至比关闭更慢)。 这只是为了好玩,并证明如果你真的需要它可以“某种程度上”。
需要可写的tmp /目录。
<?php
function xxx($a) {
$sid = GetUniversalSessionId();
$tmpfname= 'tmp/'.$sid.'.php';
$handle = fopen($tmpfname, "w");
fwrite($handle, '<?php
function func_'.($sid).'($b) {
$a='."'".str_replace("\'","\\'",str_replace("\\","\\\\",$a))."'".';
print "a=$a, b=$b \n";
}
?>');
fclose($handle);
include($tmpfname);
unlink($tmpfname);
return 'func_'.($sid);
}
$result=xxx(32);
$result(20);
// This is just to get a unique identifier for every connection and every function call:
// UNIVERSALSESSIONIDS v1.3
if(defined('UNIVERSALSESSIONIDS')) return;
define('UNIVERSALSESSIONIDS', TRUE);
function GetTimeStart() {
return strtotime('2006-07-10');
}
function GetUniversalSessionId() {
return GetCodedSid(letterNumBase(),16);
}
function GetCodedSid($baseChars,$Pad=0) {
$Zero=$baseChars{0};
list ($usec, $sec) = explode (' ', microtime());
$new_sid = ($sec-GetTimeStart()) . str_pad ((int)($usec * 100000000), 8, '0', STR_PAD_LEFT) . str_pad (rand (0, 9999), 4, '0', STR_PAD_LEFT);
$new_sid=ConvertDecToAnyStr($new_sid,$baseChars);
$new_sid=str_pad ($new_sid, $Pad, $Zero, STR_PAD_LEFT);
return $new_sid;
}
function divide($decstr,$decnum) {
$Start='';
$Result='';
$WRITE=FALSE;
do {
$Start.=substr($decstr,0,1);
$decstr=substr($decstr,1);
$DecStart=intval($Start);
$Rest=$DecStart%$decnum;
$PartDiv=($DecStart-$Rest)/$decnum;
if($PartDiv>0) $WRITE=TRUE;
if($WRITE) $Result.=$PartDiv;
$Start=$Rest;
} while ($decstr!='');
if($Result=='') $Result='0';
return array($Result,$Rest);
}
function bigBase() {
global $gSavedBigBase;
if(isset($gSavedBigBase)) return $gSavedBigBase;
$BigBase='';
for($i=33;$i<=128;$i++) $BigBase.=chr($i);
$gSavedBigBase=$BigBase;
return $BigBase;
}
function letterNumBase() {
global $gSavedBigBase2;
if(isset($gSavedBigBase2)) return $gSavedBigBase2;
$BigBase='';
for($i=ord('0');$i<=ord('1');$i++) $BigBase.=chr($i);
for($i=ord('A');$i<=ord('Z');$i++) $BigBase.=chr($i);
$BigBase.='_';
// for($i=ord('a');$i<=ord('z');$i++) $BigBase.=chr($i);
$gSavedBigBase2=$BigBase;
return $BigBase;
}
function ConvertDecToAny($decstr,$decbase) {
$Result=array();
do {
$Div=divide($decstr,$decbase);
$decstr=$Div[0];
$Rest=$Div[1];
$Result[]=$Rest;
} while($decstr!='0');
return $Result;
}
function ConvertDecToAnyStr($decstr,$baseChars='01') {
$decbase=strlen($baseChars);
$Result='';
do {
$Div=divide($decstr,$decbase);
$decstr=$Div[0];
$Rest=$Div[1];
$Result=$baseChars{$Rest}.$Result;
} while($decstr!='0');
return $Result;
}
?>