【问题标题】:Insert a file into specific directory/node using vfsStream使用 vfsStream 将文件插入特定目录/节点
【发布时间】:2015-12-31 10:41:55
【问题描述】:

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 目录下?

【问题讨论】:

  • 最简单的方法是,在阅读了一些文档之后,似乎实际上在一开始就在结构中构建了文件。为什么建结构的时候不能定义呢?
  • @FélixGagnon-Grenier 是的,这是可能的;但是我寻求给定情况的解决方案。想知道这是否可以通过任何方式实现?

标签: php unit-testing oop phpunit vfs-stream


【解决方案1】:

是的,显然可以使用addChild() 方法将孩子添加到vfsStreamFirectory

但是我在API Docs 中没有找到简单的方法可以轻松遍历结构以添加内容。 对于这种特殊情况,这是一个可怕的hacky,例如,如果每个路径元素有多个文件夹,它将失败。

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

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 问题。
【解决方案2】:

答案给了on github;因此而不是

->at($root)

应该使用

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

【讨论】:

  • 这会导致我最后出现以下错误TypeError: Argument 1 passed to org\bovigo\vfs\vfsStreamAbstractContent::at() must implement interface org\bovigo\vfs\vfsStreamContainer, instance of org\bovigo\vfs\vfsStreamFile given 有什么建议吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-08
相关资源
最近更新 更多