目的是创建一个Reader类,它是 League Flysystem 文档之上的包装器
Reader应该提供方便的方式来读取目录中的所有文件,无论文件的物理形式是什么(本地文件或存档中的文件)
由于 DI 方法,包装器不应在其内部创建依赖项实例,而是将这些依赖项作为参数放入构造函数或其他 setter 方法。
这是一个如何单独使用League Flysystem(没有提到的包装器)从磁盘读取常规文件的示例:
<?php
use League\Flysystem\Filesystem;
use League\Flysystem\Adapter\Local;
$adapter = new Local(__DIR__.'/path/to/root');
$filesystem = new Filesystem($adapter);
$content = $filesystem->read('path-to-file.txt');
正如您所看到的,首先您创建了一个本地适配器,它在其构造函数中需要路径,然后您在其构造函数中创建需要适配器实例的文件系统。
两者的参数:Filesystem和Local不是可选的。从这些类创建对象时必须传递它们。这两个类也没有这些参数的任何公共设置器。
我的问题是如何使用依赖注入来编写包装 Filesytem 和 Local 的 Reader 类?
我通常会做类似的事情:
<?php
use League\Flysystem\FilesystemInterface;
use League\Flysystem\AdapterInterface;
class Reader
{
private $filesystem;
private $adapter
public function __construct(FilesystemInterface $filesystem,
AdapterInterface $adapter)
{
$this->filesystem = $filesystem;
$this->adapter = $adapter;
}
public function readContents(string $pathToDirWithFiles)
{
/**
* uses $this->filesystem and $this->adapter
*
* finds all files in the dir tree
* reads all files
* and returns their content combined
*/
}
}
// and class Reader usage
$reader = new Reader(new Filesytem, new Local);
$pathToDir = 'someDir/';
$contentsOfAllFiles = $reader->readContents($pathToDir);
//somwhere later in the code using the same reader object
$contentsOfAllFiles = $reader->readContents($differentPathToDir);
但这不起作用,因为我需要将本地适配器传递给 Filesystem 构造函数,为了做到这一点,我需要首先传递给本地适配器路径,这完全违背了读者使用便利性的全部要点,即只是将路径传递给 dir where所有文件都是,Reader 只需要一个方法 readContents() 就可以提供这些文件的内容。
所以我被困住了。是否可以将 Reader 实现为 Filestem 及其本地适配器的包装器?
我想避免使用关键字 new 并以这种方式获取依赖对象的紧密耦合:
<?php
use League\Flysystem\Filesystem;
use League\Flysystem\Adapter\Local;
class Reader
{
public function __construct()
{
}
public function readContents(string $pathToDirWithFiles)
{
$adapter = new Local($pathToDirWithFiles);
$filesystem = new Filesystem($adapter);
/**
* do all dir listing..., content reading
* and returning results.
*/
}
}
问题:
有没有办法编写一个使用 Filesystem 和 Local 作为依赖注入方式的依赖项的包装器?
除了包装器(适配器)之外,还有其他模式可以帮助构建 Reader 类而不与文件系统和本地紧密耦合吗?
暂时忘记 Reader 类:如果 Filesystem 在其构造函数中需要 Local 实例,而 Local 在其构造函数中需要字符串(目录路径),那么是否可以在 Dependency Injection Container(Symfony 或 Pimple)中合理地使用这些类方法?DIC 不知道将什么路径 arg 传递给本地适配器,因为该路径将在稍后的代码中进行评估。