我正在尝试制作一个基准测试脚本,我可以输入简短的代码片段来快速评估我的预期。我认为它类似于jsPerf(但出于安全原因,密码保护)。
主循环应如下所示:
public function run(&$t, $count) {
//Run setup function
if(is_callable($this->setup))
call_user_func($this->setup);
//Save inital time
$t($this->name);
//THE MAIN LOOP
for($i=0; $i<$count; $i++) {
call_user_func($this->fn);
}
//Save end time
$t($this->name."_end");
//return time difference
return $t[$this->name."-".$this->name."_end"];
}
但是,这只适用于静态方法 - 在制作脚本时定义了函数:
//New instance of tester
$b = new Benchmarker();
$b->add(
//Name
"touch",
//closure
function() {
touch("file.txt");
},
//Code seen in final reports
"touch()"
);
如您所见,我使用的是call_user_func
,而不是eval
。除了它本身的邪恶功能这一事实外,我还是出于性能原因而避免使用它。如果我正在测试需要大约10ns才能处理的代码而且 eviluation 大约需要100ns,那么我的结果将是相当随机的。
这就是为什么我正在寻找一种将字符串转换为可调用对象的方法。您可以将其视为一次性评估。
$callable = string_to_callable("function() {echo \"Hello world!\";}");
$b->add(
//Name
"echo",
//callable object
$callable,
//Code seen in final reports
"echo \"...\""
);
这可能吗?
<子>注意:子>
我可以使用include
看到有趣的解决方法:
//Code received from the user
$code = "echo \"Hello world!\";";
//Random name for a new function
$rndname = "fn_".rand(0,100000); //There are smarter ways to do this of course
//String of the new function
$func = "function $rndname() {{$code}}";
//Define a filename
$f = $rndname.".php";
//Put the code in the file
file_put_contents($f, "<?php\n$func\n?".">");
//Include the new script
include $f;
//Call the function
call_user_func($rndname);
//Delete the file
unlink($f);
我真的希望我不需要上面的代码!
答案 0 :(得分:0)
除了创建新文件外,还有一个封闭技巧:
function string_to_callable($string) {
return eval("return function() {{$string}};");
}