Reading and writing files locally comes with many nuances and difficulties. It becomes even more complex when files are hosted on external servers like SFTP, AWS S3, Azure, and other providers. Flysystem provides an abstraction layer between an application and interacting with the filesystems. Explore how to use Flysystem Adapters for seamless file management for writing, reading, moving, copying, deleting, and other file interactions. See how to set permissions, configure adapters, get file information, stream files, write unit tests, and more in this technical dive into file management with Flysystem.
12. • “Flysystem is a
fi
le storage library for PHP. It provides one
interface to interact with many di
ff
erent types of
fi
lesystems. When you use Flysystem, you’re not only
protected from vendor lock-in, you’ll also have a
consistent experience for which ever storage is right for
you.”
30. Flysystem API
• Decent documentation online
- https://
fl
ysystem.thephpleague.com/docs/
- Make sure you are on the correction version of
documentation!
57. Implementation Strategies
• Mount Manager
- Scenario
‣ Many customers
‣ Reports created, stored locally
‣ Reports delivered based on con
fi
guration
‣ Variety of
fi
le storage locations
58. Implementation Strategies
• Mount Manager
- Interact with
fi
les in many storage services
- Specify adapter in location
‣ awss3://subfolder/
fi
le.txt
‣ local://path/to/
fi
le.txt
60. Implementation Strategies
class FileManager
{
public function __construct(
protected MountManager $mountManager
) {}
public function read(string $location): string
{
return $this->mountManager->read($location);
}
61. Implementation Strategies
class FileManagerFactory
{
public function __construct(
protected FileStorageAdapterFactory $adapterFactory
) {}
public function create(array $mounts): FileManager
{
$mountManageConfig = [];
foreach ($mounts as $storage => $config) {
$mountManageConfig[$storage] = new Filesystem(
$this->adapterFactory->create($storage, $config)
);
}
return new FileManager(new MountManager($mountManageConfig));
}
62. Implementation Strategies
class FileStorageAdapterFactory
{
public function create(string $adapter, array $config): FilesystemAdapter
{
return match ($adapter) {
'awss3' => new AwsS3V3Adapter($config['client'], $config['bucket']),
'local' => new LocalFilesystemAdapter($config['directory']),
};
}
65. Testing
• Historically problematic testing
fi
le interactions
- Test
fi
les
- Inject
fi
le content
- git ignore directory for testing
fi
les
- Skip testing that code
- Integration tests vs Unit tests
66. Testing
public function testRead(): void
{
$file = __DIR__ . '/TestingFile.txt';
$service = new FileStorageLocalLegacyService();
$contents = $service->read($file);
$this->assertSame(
'Test file contents 123 ...',
$contents
);
}
67. Testing
• Flysystem abstraction layer allows for testing
- Mock calls to
fi
le interactions
- Pushes for single purpose code
- Centralized
fi
lesystem management
74. Mark Niebergall @mbniebergall
• PHP since 2005
• Masters degree in MIS
• Senior Software Engineer
• Vulnerability Management project (security scans)
• Utah PHP Co-Organizer
• CSSLP, SSCP Certi
fi
ed and Exam Developer
• Endurance sports, outdoors