【问题标题】:What is the meaning of three dots (...) in PHP?PHP中三个点(...)是什么意思?
【发布时间】:2017-04-28 16:28:04
【问题描述】:

在我的服务器上安装 Magento 2 时,出现错误。查了代码,发现有三个点(...),就是报错。我包含了我在下面找到的代码:

return new $type(...array_values($args));

【问题讨论】:

标签: php syntax operators


【解决方案1】:

...$str 称为splat operator in PHP

此功能允许您为函数捕获可变数量的参数,如果您愿意,还可以结合传入的“普通”参数。举个例子最容易看出:

function concatenate($transform, ...$strings) {
    $string = '';
    foreach($strings as $piece) {
        $string .= $piece;
    }
    return($transform($string));
}

echo concatenate("strtoupper", "I'd ", "like ", 4 + 2, " apples");
// This would print:
// I'D LIKE 6 APPLES

函数声明中的参数列表中包含... 运算符,它的基本意思是“...以及其他所有内容都应放入$strings”。您可以将 2 个或更多参数传递给此函数,第二个和后续参数将添加到 $strings array,准备使用。

【讨论】:

  • 谢谢 :),我为什么要使用 SPLAT 运算符,而不是这个,我可以将数组中的所有字符串作为第二个参数传递???
  • @bikash.bilz 我会为回答者发言:我认为这只是syntactic sugar。 splat 运算符使您免于使用[] 包围参数。这没什么好处,但我认为它看起来不错。
  • 您也可以键入提示可变参数。所以在 PHP 7.2 上,你可以定义function myFunc($foo, string ...$bar)。然后$bar 给你的函数一个字符串数组,没有别的,保证在运行时。您不能使用单个数组参数来做到这一点。
  • 这不仅仅是语法糖,因为它允许在需要固定数量字符串的上下文中使用数组。使用固定数量的字符串需要您在每次字符串数量可能发生变化时重构源代码。
  • 一个简单的例子是用于查询数据库的函数签名。 function get_data($fname,$lname,$age) 必须更改,如果您希望除了这三个 function get_data(...$fields) 之外的字段不必更改,您只需在 $fields 中指定您想要的字段。 @heykatieben
【解决方案2】:

ellipsis (...) PHP token 有两种用途——将它们视为打包一个数组和解包一个数组。这两个目的都适用于函数参数。


打包

定义函数时,如果您需要为函数提供动态数量的变量(即,您不知道在代码中调用该函数时将提供多少参数)使用ellipsis (...) token 来捕获提供给该函数的所有剩余参数到函数块内可访问的数组中。省略号 (...) 捕获的动态参数的数量可以为零或更多。

For example:

// function definition
function sum (...$numbers) { // use ellipsis token when defining function
    $acc = 0;
    foreach ($numbers as $nn) {
        $acc += $nn;
    }
    return $acc;
}

// call the function
echo sum(1, 2, 3, 4); // provide any number of arguments

> 10

// and again...
echo sum(1, 2, 3, 4, 5);

> 15

// and again...
echo sum();

> 0

在函数实例化中使用打包时,省略号 (...) 会捕获所有剩余参数,即,您仍然可以拥有任意数量的初始、固定(位置)参数:

function sum ($first, $second, ...$remaining_numbers) {
    $acc = $first + $second;
    foreach ($remaining_numbers as $nn) {
        $acc += $nn;
    }
    return $acc;
}

// call the function
echo sum(1, 2); // provide at least two arguments

> 3

// and again...
echo sum(1, 2, 3, 4); // first two are assigned to fixed arguments, the rest get "packed"

> 10

解压

或者,在调用函数时,如果您提供给该函数的参数先前组合成一个数组,请使用 ellipsis (...) token 将该数组转换为提供给函数的单个参数 - 每个数组元素都分配给相应的函数函数定义中命名的参数变量。

For example:

function add ($aa, $bb, $cc) {
    return $aa + $bb + $cc;
}

$arr = [1, 2, 3];
echo add(...$arr); // use ellipsis token when calling function

> 6

$first = 1;
$arr = [2, 3];
echo add($first, ...$arr); // used with positional arguments

> 6

$first = 1;
$arr = [2, 3, 4, 5]; // array can be "oversized"
echo add($first, ...$arr); // remaining elements are ignored

> 6

在使用array functions 操作数组或变量时,解包特别有用。

例如解包array_slice的结果:

function echoTwo ($one, $two) {
    echo "$one\n$two";
}

$steaks = array('ribeye', 'kc strip', 't-bone', 'sirloin', 'chuck');

// array_slice returns an array, but ellipsis unpacks it into function arguments
echoTwo(...array_slice($steaks, -2)); // return last two elements in array

> sirloin
> chuck

【讨论】:

  • Unpack 对于 Doctrine 的 OrX 功能非常有用
  • 这是唯一清楚解释运算符双重用法的答案。希望我能不止一次地投票。
【解决方案3】:

每个答案都指向同一篇博文,除此之外,这里是关于可变长度参数列表的官方文档:

http://php.net/manual/en/functions.arguments.php#functions.variable-arg-list

在 PHP 5.6 及更高版本中,参数列表可能包含 ... 标记,以表示函数接受可变数量的参数。参数将作为数组传递给给定的变量

看来“splat”算子不是正式名称,还是很可爱!

【讨论】:

    【解决方案4】:

    PHP 7.4 中,省略号也是 扩展运算符

    $parts = ['apple', 'pear'];
    $fruits = ['banana', 'orange', ...$parts, 'watermelon'];
    // ['banana', 'orange', 'apple', 'pear', 'watermelon'];
    

    来源:https://wiki.php.net/rfc/spread_operator_for_array

    【讨论】:

      【解决方案5】:

      要使用此功能,只需警告 PHP 它需要使用 ... operator 将数组解包到变量中。更多详情请参阅here,一个简单的示例可能如下所示:

      $email[] = "Hi there";
      $email[] = "Thanks for registering, hope you like it";
      
      mail("someone@example.com", ...$email);
      

      【讨论】:

        【解决方案6】:

        意思是它把一个关联数组分解成一个列表。所以你不需要输入N个参数来调用一个方法,只需一个。 if 方法允许一个分解的参数并且如果参数是相同的类型。

        对我来说,splat 运算符最重要的是它可以帮助输入提示数组参数:

        $items = [
            new Item(), 
            new Item()
        ];
        
        $collection = new ItemCollection();
        $collection->add(...$items); // !
        
        // what works as well:
        // $collection->add(new Item());
        // $collection->add(new Item(), new Item(), new Item()); // :(
        
        class Item  {};
        
        class ItemCollection {
        
            /**
             * @var Item[]
             */
            protected $items = [];
        
            public function add(Item ...$items)
            {
                foreach ($items as &$item) {
                    $this->items[] = $item;
                }
            }
        } 
        

        它在类型控制上节省了一些精力,尤其是在处理大量集合或非常面向对象时。

        需要注意的重要一点是...$array 确实分解了一个数组,尽管它的项目类型不同,所以你也可以采取丑陋的方式:

        function test(string $a, int $i) {
            echo sprintf('%s way as well', $a);
        
            if ($i === 1) {
                echo('!');
            }
        }
        
        $params = [
            (string) 'Ugly',
            (int) 1
        ];
        
        test(...$params);
        
        // Output:
        // Ugly way as well!
        

        但请不要。

        【讨论】:

        • 没那么难看。就像 Doctrine 的 OrX 函数需要一个列表,但是你需要传递一个数组(因为你不知道你将传递多少个元素)。我发现这种方式比使用 call_user_func_array
        • @ErdalG。但这是我假设的一种类型条件对象的数组?
        • 好吧,老实说,我不记得 3 年前脑子里的例子了,哈哈(我还是应该写的)。它一定是生成的表达式的一些艺术数组。对于一组独特的条件,您显然可以用->in() 或类似方法替换
        【解决方案7】:

        这就是所谓的“splat”运算符。基本上,那件事转化为“任意数量的论点”; PHP 5.6 引入

        更多详情请参阅here

        【讨论】:

          【解决方案8】:

          似乎没有人提到它,所以留下来[它还将帮助谷歌(和其他 SE)指导开发人员要求 PHP 中的休息参数] :

          As indicated here 它在 JS 上称为 Rest Parameters,我更喜欢这个有意义的命名而不是那个 splat 的东西!

          在 PHP 中,...args 提供的功能称为Variadic functions,它是在 PHP5.6 上引入的。使用func_get_args() 实现了相同的功能。

          为了正确使用它,您应该在任何有助于减少样板代码的地方使用剩余参数语法。

          【讨论】:

          • 加一个帮助谷歌在 PHP 中找到 Rest 参数
          【解决方案9】:

          PHP 8.1 中,这种语法“(...)”被用作创建可调用对象的新方法。

          PHP 8.1 之前:

          $callable = [$this, 'myMethod'];
          

          PHP 8.1 之后:

          $callable = $this->myMethod(...);
          

          来源:https://wiki.php.net/rfc/first_class_callable_syntax

          【讨论】:

          • 这不是作者原始问题的答案,但它可能与谷歌搜索“php 3 dots”的任何人有关
          猜你喜欢
          • 2021-11-19
          • 2017-02-09
          • 2019-10-24
          • 1970-01-01
          • 2016-08-17
          • 2013-07-11
          • 2017-06-30
          相关资源
          最近更新 更多