使用PHP变量$ _(美元符号后加下划线) [英] Use of php variable $_ (dollar sign followed by an underscore)

查看:189
本文介绍了使用PHP变量$ _(美元符号后加下划线)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是真的真的,如果不需要foreach($array as $key => $value)中的$value,我可以在foreach循环中将$_用作虚拟变量吗?除了 PHP语法格式.

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.

在不使用该值的情况下,foreach循环有一种特殊情况 在循环内.在这种情况下,虚拟变量$ _(下划线)为 已使用:

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 }

这样做是出于性能方面的考虑,因为它比调用速度更快 array_keys()并循环执行结果.

This is done for performance reasons, as it is faster than calling array_keys() and looping on its result.

推荐答案

"_"是有效的变量名字符,因此您可以像使用其他任何变量一样使用它,并且没有特殊意义;这不是Perl.

"_" 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.

<?php
    $_ = "Hello";
    $__ = "World";
    $___ = "foo";

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

将输出"Hello,World,foo".如预期的那样.还有,

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

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

将输出"abcGamma",表明$_变量在foreach中使用后仍保持定义;这不是某种奇怪的本地"广告.变量.

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.

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

这些是我的结果,经过格式化和排序:

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

有两点需要注意:在最快和最慢之间,我相差大约四十倍. 但是十万个呼叫之间的差值为1.63秒,这意味着速度较快和速度较慢的版本之间的单个通话为16.3 微秒.

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.

如果另一方面,如果您真的需要几次称为 billion 的东西,以使这些微不足道的微秒加起来值得解决,那么您最好花一些时间在将那段代码移植(或已经移植)到某种语言上,这种语言要么本质上就更快,要么可以进行大规模并行化-也许是C或Erlang;或重新考虑架构(例如,守护进程以节省开销,使用存储过程将麻烦转移到RDBMS,缓存结果等).

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, ...).

这些是在更新的64位计算机上的PHP 7.2.19的结果:

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

请注意,最快和最慢之间的差现在小于2倍.因此,对于使用最清晰,最容易理解的代码"的论点被引用.现在变得更强大.

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.

这篇关于使用PHP变量$ _(美元符号后加下划线)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆