使用vfsStream将文件插入到特定目录/节点中


Insert a file into specific directory/node using vfsStream

vfsStream的用例如下:

$directories = explode('/', 'path/to/some/dir');
$structure = [];
$reference =& $structure;
foreach ($directories as $directory) {
    $reference[$directory] = [];
    $reference =& $reference[$directory];
}
vfsStream::setup();
$root = vfsStream::create($structure);
$file = vfsStream::newFile('file')
    ->at($root) //should changes be introduced here?
    ->setContent($content = 'Some content here');

vfsStream::inspect(new vfsStreamStructureVisitor())->getStructure()的输出为

Array
(
    [root] => Array
    (
        [path] => Array
        (
            [to] => Array
            (
                [some] => Array
                (
                    [dir] => Array
                    (
                    )
                )
            )
        )
        [file] => Some content here
    )
)

是否可以将文件插入特定目录,例如dir目录下?

是的,显然可以使用addChild()方法向vfsStreamFirectory添加子级:

然而,我在API文档中找不到允许轻松遍历结构以添加内容的简单方法。这里有一个可怕的技巧对于这个特殊的情况,如果每个路径元素有一个以上的文件夹,它就会失败。

基本上,我们必须递归地遍历每个级别,验证名称是否是我们想要添加文件的名称,然后在找到文件时添加。

use org'bovigo'vfs'vfsStream;
use org'bovigo'vfs'vfsStreamDirectory;
use org'bovigo'vfs'visitor'vfsStreamStructureVisitor;
$directories = explode('/', 'path/to/some/dir');
$structure = [];
$reference =& $structure;
foreach ($directories as $directory) {
    $reference[$directory] = [];
    $reference =& $reference[$directory];
}
vfsStream::setup();
$root = vfsStream::create($structure);
$file = vfsStream::newFile('file')
    ->setContent($content = 'Some content here');
$elem = $root;
while ($elem instanceof vfsStreamDirectory)
{
    if ($elem->getName() === 'dir')
    {
        $elem->addChild($file);
    }
    $children = $elem = $elem->getChildren();
    if (!isset($children[0]))
    {
        break;
    }
    $elem = $children[0];
}
print_r(vfsStream::inspect(new vfsStreamStructureVisitor())->getStructure());

答案在github上给出;从而代替

->at($root)

应该使用

->at($root->getChild('path/to/some/dir')).