真的是真的,如果$_
中foreach
不需要$value
,我可以将foreach($array as $key => $value)
用作虚拟变量}?除了PHP syntax formatting之外,我找不到任何证明这一点的有用信息。
当不使用值时,foreach循环有一个特例 在循环内。在这种情况下,虚拟变量$ _(下划线)是 使用:
foreach ($GLOBALS['TCA'] as $table => $_) { // Do something with $table }
这是出于性能原因而完成的,因为它比调用更快 array_keys()并循环其结果。
答案 0 :(得分:15)
“_”是有效的变量名称字符,因此您可以像使用任何其他变量一样使用它,并且没有特殊意义;这不是Perl。
<?php
$_ = "Hello";
$__ = "World";
$___ = "foo";
print "{$_}, {$__}, {$___}\n";
?>
将按预期输出“Hello,World,foo”。此外,
foreach ( [ 'a' => 'Alpha', 'b' => 'Beta', 'c' => 'Gamma' ] as $letter => $_ ) {
print $letter;
}
print $_;
将输出“abcGamma”,表示$_
变量在foreach
中使用后仍保持定义;它不是一种奇怪的“本地”变量。
至于表演,我觉得它没什么区别,但那是你的号召。相反,我会尝试不使用全局变量,以避免污染全局范围。
<强> n.b。最近需要PHP,我认为
随时纠正/添加/建议改进
define('INNER_LOOP', 10000);
define('OUTER_LOOP', 10);
$TCA = [
'customers' => '',
'relations' => '',
'invoices' => '',
'books' => '',
'parts' => '',
'records' => '',
'calories' => '',
'bounties' => '',
'cats' => '',
'cowabunga' => '',
'amenities' => '',
];
$tests = [
"foreach access to global" => function() {
global $TCA;
for ($i = 0; $i < INNER_LOOP; $i++) {
foreach ($TCA as $table => $_) {
$t = $table . 'x';
}
}
},
"foreach access to GLOBALS" => function() {
for ($i = 0; $i < INNER_LOOP; $i++) {
foreach ($GLOBALS['TCA'] AS $table => $_) {
$t = $table . 'x';
}
}
},
"passing parameter" => function($TCA) {
for ($i = 0; $i < INNER_LOOP; $i++) {
foreach ($TCA AS $table => $_) {
$t = $table . 'x';
}
}
},
"passing parameter and array_keys" => function($TCA) {
$keys = array_keys($TCA);
for ($i = 0; $i < INNER_LOOP; $i++) {
foreach ($keys AS $table) {
$t = $table . 'x';
}
}
},
"walking passed parameter w/lambda" => function($TCA) {
for ($i = 0; $i < INNER_LOOP; $i++) {
array_map(
function($table) {
$t = $table . 'x';
},
array_keys($TCA)
);
}
},
"walking passed parameter w/ anon func" => function($TCA) {
$handler = function($table) {
$t = $table . 'x';
};
$keys = array_keys($TCA);
for ($i = 0; $i < INNER_LOOP; $i++) {
array_map($handler, $keys);
}
},
];
function timeFunc($function, $obj) {
$time = microtime(true);
for ($i = 0; $i < OUTER_LOOP; $i++) {
$function($obj);
}
return (microtime(true) - $time);
}
foreach ($tests as $name => $test) {
print "$name: " . timeFunc($test, $TCA) . "\n";
flush();
}
这些是我的结果,格式化和排序:
- passing parameter and array_keys: 0.04573917388916
- foreach access to global: 0.067629098892212
- passing parameter: 0.08098292350769
- foreach access to GLOBALS: 0.082289934158325
- walking passed parameter w/ anon func: 1.6233508586884
- walking passed parameter w/lambda: 1.6796138286591
有两点需要注意:在最快和最慢之间,我有大约四十的差异。 但 十万次通话的差异为1.63秒,这意味着对于较快和较慢版本之间的单次通话,为16.3 微秒。 / p>
因此,如果这些版本中的一个显示出拯救你的承诺,比如每年五分钟的头痛,寻找错误或客户支持,那么那个版本可能会证明是值得投资。
另一方面,如果你真的需要一些叫做十亿次次的东西,那么那些微不足道的微秒加起来值得一试,那么你可能最好还是花一些时间在将该部分代码移植(或移植)到一种本质上更快或可以大规模并行化的语言 - 可能是C或Erlang;或重新思考架构(例如,守护进程以节省开销,使用存储过程将麻烦卸载到RDBMS,缓存结果,......)。
答案 1 :(得分:1)
来自Basics:
PHP中的变量由美元符号后跟变量名称表示。变量名称区分大小写。
变量名遵循与PHP中其他标签相同的规则。有效的变量名称以字母或下划线开头,后跟任意数量的字母,数字或下划线。
所以$_
只是一个任意变量。使用$_
和$value
之间没有区别,只是$_
只是一种传统的方式来表示在循环中实际没有使用的值。
注意这个
$foo = array('a' => 1, 'b' => 2, 'c' => 3);
foreach ($foo as $key => $_) echo $_;
输出
123
答案 2 :(得分:1)
下面的测试表明,在这种情况下使用$_
作为变量名称似乎与使用任何其他变量名称没有任何不同。该值仍存储在变量中。
$tmp = array(1=>"one", 2=>"two", 3=>"three", 4=>"four", 5=>"five");
foreach ($tmp as $num=>$_) {
echo "num is $num; dummy is $_<br>";
}
答案 3 :(得分:1)
正如其他人所说,$_
是一个有效的变量名。这似乎是Typo3编码指南。如果你不需要价值,为什么要预告?这看起来很神圣。您可以将键作为值获取。我会用:
foreach (array_keys($GLOBALS['TCA']) as $table) {
// Do something with $table
}