Search by

A PHP component/library. File value objects, plus CSV and ZIP creation and PSR-7 responses for sending a file to the browser.

Package info

github.com/webservco/file

Homepage

pkg:composer/webservco/file

Statistics

Installs: 475

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

v2.4.0 2026-11-03 08:39 UTC

This package is auto-updated.

Last update: 2026-11-03 08:41:44 UTC


README

A PHP component/library. Please see webservco/sandbox for an example project using these types of components.

File value objects, plus CSV and ZIP creation and PSR-7 responses for sending a file to the browser.

  • Requires: ext-zip (for ZipArchiveService), a PSR-17 implementation such as webservco/http
  • Related: webservco/log (writes its files with FileService)

Installation

composer require webservco/file

Usage

Download a CSV built from database rows

use WebServCo\File\Factory\Response\DownloadResponseFactory;
use WebServCo\File\Service\CSV\DataCreatorService;
use WebServCo\File\Service\CSV\FileCreatorService;

$fileCreatorService = new FileCreatorService(
    // \WebServCo\File\Contract\Service\CSV\DataCreatorServiceInterface: delimiter, enclosure.
    new DataCreatorService(',', '"'),
    // PSR-17: \Psr\Http\Message\StreamFactoryInterface
    $streamFactory,
);
// $rows: any Iterator, for example a generator over a query, or new ArrayIterator($array).
// true: use the keys of the first row as the header line.
// \WebServCo\File\ValueObject\CSVFile
$file = $fileCreatorService->createCsvFileFromIterator('report.csv', $rows, true);

// PSR-17: \Psr\Http\Message\ResponseFactoryInterface
$downloadResponseFactory = new DownloadResponseFactory($responseFactory);
return $downloadResponseFactory->createDownloadResponse($file);

Show a PDF in the browser

use WebServCo\File\Factory\FileFactory;
use WebServCo\File\Factory\Response\OutputResponseFactory;

$fileFactory = new FileFactory($streamFactory);
// \WebServCo\File\Contract\FileInterface
$file = $fileFactory->createPdfFromPath('/path/to/invoice.pdf', 'invoice.pdf');

$outputResponseFactory = new OutputResponseFactory($responseFactory);
return $outputResponseFactory->createOutputResponse($file);

Read a CSV file that may start with a byte order mark

use WebServCo\File\Service\File\ByteOrderMarkService;

$filePointerResource = fopen('/path/to/export.csv', 'r');
// Skips a UTF-8 byte order mark, if there is one; otherwise the file is read from its start.
(new ByteOrderMarkService())->skipUtf8ByteOrderMark($filePointerResource);
while (($line = fgetcsv($filePointerResource, 0, ',', '"', '')) !== false) {
    // ...
}
fclose($filePointerResource);

Contracts

Interface Implementation Purpose
Contract\FileInterface ValueObject\File, ValueObject\CSVFile, ValueObject\PdfFile Content type, name, size and data stream.
Contract\FileFactoryInterface Factory\FileFactory Creates files from a path or a string (generic, CSV, PDF).
Contract\Service\CSV\DataCreatorServiceInterface Service\CSV\DataCreatorService Turns an iterator of rows into CSV text.
none Service\CSV\FileCreatorService Turns an iterator of rows into a CSVFile.
none Factory\Response\DownloadResponseFactory Response with Content-Disposition: attachment.
none Factory\Response\OutputResponseFactory Response that shows the file inline.
none Service\Archive\ZipArchiveService Zips one file into a directory and returns the archive file name ({name}.zip).
none Service\File\FileService Creates directories and appends data to a file.
none Service\File\ByteOrderMarkService Skips a UTF-8 byte order mark at the start of an open file, before reading it.

Namespaces are relative to WebServCo\File\.

Notes

CSV data starts with a UTF-8 byte order mark. Excel needs it to show accented characters correctly. The header line comes from the first row's keys. Give every row the same keys.

fgetcsv doesn't skip that byte order mark: it stays in the first value, and a quoted first field keeps its quotes. To read such a file back, call ByteOrderMarkService::skipUtf8ByteOrderMark() right after opening it. ByteOrderMarkService::UTF8_BYTE_ORDER_MARK holds the mark that DataCreatorService writes.

ZIP archives are compressed with LZMA2. Some unzip tools, including older built-in ones, can't open them.

Development

# Start project.
ddev start
# Install dependencies.
ddev c u
# Run all validations.
ddev c c
# Run unit tests.
ddev c test:dox

License

MIT