为何在此处使用clone关键字

时间:2015-08-02 00:13:38

标签: php spl

我正在观看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();

2 个答案:

答案 0 :(得分:3)

从php5开始,运算符In [3]: fetch(url.strip()) 2015-08-02 05:53:01 [scrapy] DEBUG: Redirecting (302) to <GET http://www.amazon.de/Instant-Video/b?ie=UTF8&node=3010075031> from <GET https://www.amazon.de/Instant-Video/b?ie=UTF8&node=3010075031> 2015-08-02 05:53:03 [scrapy] DEBUG: Crawled (200) <GET http://www.amazon.de/Instant-Video/b?ie=UTF8&node=3010075031> (referer: None) [s] Available Scrapy objects: [s] crawler <scrapy.crawler.Crawler object at 0x7fe36d76fbd0> [s] item {} [s] request <GET https://www.amazon.de/Instant-Video/b?ie=UTF8&node=3010075031> [s] response <200 http://www.amazon.de/Instant-Video/b?ie=UTF8&node=3010075031> [s] settings <scrapy.settings.Settings object at 0x7fe365b91c50> [s] spider <DefaultSpider 'default' at 0x7fe36420d110> [s] Useful shortcuts: [s] shelp() Shell help (print this help) [s] fetch(req_or_url) Fetch request (or URL) and update local objects [s] view(response) View response in a browser 创建对象的引用,因此如果没有=,您将把变量clone的指针/引用放入数组中。

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

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

更新:在这种情况下,实际上差异更深一些,请查看this articleforeach返回相同的对象,这就是为什么你必须在迭代期间克隆(及其当前)状态,但DirectoryIterator返回新对象,可以将其放入数组而不进行克隆。

答案 1 :(得分:0)

实际上,当你的逻辑在foreach循环中时,你可以在没有clone的情况下完成它:

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

sample from php.net manual