问题 使用php变量$ _(美元符号后跟下划线)


就是它  是的,我可以使用 $_ 作为虚拟变量 foreach 循环,如果没有必要 $value 在 foreach($array as $key => $value)?除了以外,我找不到任何证明这一点的有用信息 PHP语法格式

当不使用该值时,foreach循环有一个特例   在循环内。在这种情况下,虚拟变量$ _(下划线)是   用过的:

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

这是出于性能原因而完成的,因为它比调用更快   array_keys()并循环其结果。


7399
2018-06-04 20:05


起源

花费更少的时间来测试而不是问
你有没有尝试过 foreach(array_keys($GLOBALS['TCA']) as $table) ?当然,仅使用未使用的值变量可能会减少资源消耗。 - Powerlord
我其实有一个 array($key => $arrayforlateruse, ... , ...)。 $arrayforlateruse 现在不需要变量。现在我知道放置 $_ 相反没有效果。 - BalticMusicFan


答案:


“_”是一个 有效的变量名称字符,因此您可以像使用任何其他变量一样使用它,并且没有特殊意义;这不是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

有两点需要注意:在最快和最慢之间我有差别 四十次 区别于 十万个电话 是1.63秒,这意味着16.3 微秒 对于较快和较慢版本之间的单个调用。

因此,如果这些版本中的一个显示出拯救你的承诺,比如每年五分钟的头痛,寻找漏洞或客户支持,那很可能就是  版本将证明是值得的投资。

另一方面,如果你真的需要一些叫做几个的东西 十亿 所以,那些微不足道的微秒加起来值得一试,那么你可能最好花一些时间将这部分代码移植(或移植)到一种语言本身更快或可以大规模制作的语言parallelize - 可能是C或Erlang;或重新考虑体系结构(例如,守护进程以节省开销,使用存储过程将麻烦卸载到RDBMS,缓存结果,......)。


13
2018-06-04 20:11





基本

PHP中的变量由美元符号后跟变量名称表示。变量名称区分大小写。

变量名称遵循与PHP中其他标签相同的规则。有效的变量名称以字母或下划线开头,后跟任意数量的字母,数字或下划线。

所以 $_ 只是一个随意的变量。使用之间真的没什么区别 $_ 和 $value, 除了那个 $_ 只是一种传统方式来指示在循环中实际未使用的值。

请注意这一点

$foo = array('a' => 1, 'b' => 2, 'c' => 3);
foreach ($foo as $key => $_) echo $_;

输出

123

1
2018-06-04 20:11





下面的测试表明使用 $_ 在这种情况下,作为变量名称似乎与使用任何其他变量名称没有任何不同。该值仍存储在变量中。

$tmp = array(1=>"one", 2=>"two", 3=>"three", 4=>"four", 5=>"five");
foreach ($tmp as $num=>$_) {
        echo "num is $num; dummy is $_<br>";
}

1
2018-06-04 20:12





正如其他人所说 $_ 是一个有效的变量名称。这似乎是Typo3编码指南。如果你不需要价值,为什么要预告?这看起来很神圣。您可以将键作为值获取。我会用:

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

1
2018-06-04 20:13



“如果你不需要价值,为什么要预告呢?” ......然而你还在使用 foreach。 - Powerlord
是的,我得到了 value。 - AbraCadaver