"_" 是一个有效的变量名字符,因此您可以像使用任何其他变量一样使用它,并且没有特殊意义;这不是 Perl。
<?php
$_ = "Hello";
$__ = "World";
$___ = "foo";
print "{$_}, {$__}, {$___}\n";
?>
预期输出将是"Hello, World, foo"。此外,
foreach ( [ 'a' => 'Alpha', 'b' => 'Beta', 'c' => 'Gamma' ] as $letter => $_ ) {
print $letter;
}
print $_;
将输出"abcGamma",显示$_
变量在foreach
后仍然保持定义;它不是某种奇怪的“本地”变量。
至于性能,我不认为这会有太大的影响,但这取决于你。相反,我建议不要使用全局变量,以避免污染全局范围。
随机测试和牢骚
注:我认为需要最新版本的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
需要注意的是:最快和最慢之间相差大约40倍。但是,在超过十万次调用的情况下,速度差距只有1.63秒,这意味着较快版本和较慢版本之间单次调用的时间差为16.3微秒。
因此,如果其中一种版本表现出能够节省你每年五分钟头痛、解决错误或客户支持的优点,那么选择那个版本很可能是值得投资的。
另一方面,如果你真的需要多次调用(例如数十亿次),使得那些微不足道的微秒时间总和值得处理,那么你最好花些时间将代码段移植到一种本质上更快或可以实现大规模并行化的语言中——也许是C语言,或者Erlang;或者重新思考架构(例如守护进程来节省开销,使用存储过程将麻烦转移到RDBMS中,缓存结果等)。
PHP 7.2的更新:
以下是在较新的64位机器上运行PHP 7.2.19的结果:
passing parameter and array_keys 0.57718586921692
foreach access to global 0.65028595924377
passing parameter 0.65098810195923
foreach access to GLOBALS 0.69678092002869
walking passed parameter w/ anon func 0.84391593933105
walking passed parameter w/lambda 1.0423438549042
请注意,最快和最慢之间的差距现在不到2倍;因此,“选择最清晰、最易理解的代码”的论点现在甚至更加强有力。
foreach(array_keys($GLOBALS['TCA']) as $table)
吗?虽然只使用未使用的值变量可能更节省资源。 - Powerlordarray($key => $arrayforlateruse, ... , ...)
。$arrayforlateruse
是现在不需要的变量。现在我知道用$_
替换它没有影响。 - BalticMusicFan$_
,其中必须提供一个变量,但不会被使用 - 类似于Go,但在Go中,未使用的变量会导致错误; PHP不必那么严格,但使用$_
可以向语法检查器和IDE发出信号,表明变量是有意不使用的,并且它们可以为此变量禁用“未使用的变量”警告。 - rob74