php变量前边下划线_使用PHP变量$ _(美元符号后加下划线)

bd96500e110b49cbb3cd949968f18be7.png

Is that really true that i can use $_ as a dummy variable in foreach loop if there is no need for $value in foreach($array as $key => $value)? I could not find any useful information that proves this except PHP syntax formatting.

There's a special case for foreach loops when the value is not used

inside the loop. In this case the dummy variable $_ (underscore) is

used:

foreach ($GLOBALS['TCA'] as $table => $_) { // Do something with $table }

This is done for performance reasons, as it is faster than calling

array_keys() and looping on its result.

解决方案

"_" is a valid variable name character, so you can use it as you would any other variable and has no special significance; this isn't Perl.

$_ = "Hello";

$__ = "World";

$___ = "foo";

print "{$_}, {$__}, {$___}\n";

?>

will output "Hello, World, foo" as expected. Also,

foreach ( [ 'a' => 'Alpha', 'b' => 'Beta', 'c' => 'Gamma' ] as $letter => $_ ) {

print $letter;

}

print $_;

will output "abcGamma", showing that the $_ variable remains defined after being used in the foreach; it's not some weird kind of "local" variable.

As for the performances, I don't think it makes much difference, but that's your call. Rather, I'd try and not use global variables, to avoid polluting the global scope.

Tests and rants more or less at random

n.b. a recent PHP required, I think

feel free to correct/add/suggest improvements

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();

}

These are my results, formatted and sorted:

- 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

Two things need noting: between the fastest and slowest I have a difference of about forty times. But the difference over one hundred thousand calls is 1.63 seconds, which means 16.3 microseconds for a single call between the faster and the slower versions.

So if one of these versions show promise of saving you, say, five minutes a year of head-scratching, bug-hunting or customer support, it's likely that going for that version will prove a worthwhile investment.

If, on the other hand, you really need something called several billion times, so that those paltry microseconds add up to something worth tackling, then probably you'd be better off investing some time in porting (or having ported) that section of code to a language which is either inherently faster or can be made to massively parallelize - maybe C, or Erlang; or re-thinking the architecture (e.g. daemonize a process to save on the overhead, use stored procedures to offload the hassle to the RDBMS, cache results, ...).

UPDATE FOR PHP 7.2

These are the results for PHP 7.2.19 on a newer 64bit machine:

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

Note that the difference between fastest and slowest is now less than a factor of 2; therefore, the argument for "go with the clearest, easiest to understand code" is now even stronger.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值