【问题标题】:Why use clone keyword here为什么在这里使用 clone 关键字
【发布时间】:2015-08-02 00:13:38
【问题描述】:

我正在看 SPL 的教程,这是让我感到困惑的代码

<?php

$directory = new DirectoryIterator('common/images');

foreach ($directory as $file)
{
    if($file->isFile())
        $files[] = clone $file;
}

echo $files[1]->getFileName();

如果我不在 foreach 循环中使用 clone 关键字,我将看不到文件名。为什么当我将整个对象推入 $files 数组时会这样。

谢谢

更新部分

虽然上面的代码我必须使用clone 关键字。根据下面的答案,我们正在使用clone 创建对象的副本而不是引用。在这种情况下,这似乎不是一个正当理由。考虑以下示例,它不需要 clone 关键字并且按预期工作

<?php

$filesystem = new FilesystemIterator('common/images');
foreach ($filesystem as $file)
{
    $files[] = $file;
}

echo $files[0]->getFileName();

【问题讨论】:

    标签: php spl


    【解决方案1】:

    从 php5 开始,操作符 = 会创建对对象的引用,因此如果没有 clone,您会将变量 $file 的指针/引用放入数组中。

    但是这个变量只在循环中使用,并且会/可能在foreach之后被销毁,因为它超出了范围。

    这就是为什么您需要创建它的副本以放入数组并在循环后访问它。

    更新:实际上在这种情况下差异更深一点,请查看this articleDirectoryIterator 返回相同的对象,这就是为什么您必须在迭代期间克隆(及其当前)状态,但 FilesystemIterator 返回新对象,无需克隆即可放入数组。

    【讨论】:

    • 虽然我理解你的逻辑。但是因为我将整个 $file 变量放在 $files 中。是不是我们这里不需要复制或引用,实际上是一个包含 $file 对象的新变量。
    • 你能看看更新的部分吗?在浏览完更新的示例后,我不接受您的回答。
    【解决方案2】:

    实际上你可以在没有clone 的情况下做到这一点,而你的逻辑在 foreach 循环中:

    <?php
      $dir = new DirectoryIterator(dirname(__FILE__));
      foreach ($dir as $fileinfo) {
        echo $fileinfo->getFilename() . "\n";
      }
    ?>
    

    sample from php.net manual

    【讨论】:

    • 我知道,问题在于将它放入数组中。
    猜你喜欢
    • 2020-05-20
    • 1970-01-01
    • 2021-09-06
    • 2016-01-22
    • 2018-02-11
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    相关资源
    最近更新 更多