Prevents CSV Formula Injection
The EscapeFormula Formatter formats CSV records to reduce CSV Formula Injection in imported Spreadsheet programs.
Usage with CSV objects
The EscapeFormula class uses the formatter capabilities of the Writer object to escape formula injection.
public function __construct(string $escape = "'", array $special_chars = [])
public function escapeRecord(array $record): array
public function unescapeRecord(array $record): array
EscapeFormula::unescapeRecord is available since version 9.11.0
The EscapeFormula::__construct method takes two (2) arguments:
- the
$escapeparameter which will be used to prepend the record field, which defaults to'; - the
$special_charsparameter which is anarraywith additional characters that need to be escaped. By default, the following characters at the start of any record field content will be escaped+,-,=,@,\t,\r; - for more information see OWASP - CSV Injection
use League\Csv\EscapeFormula;
use League\Csv\Writer;
$formatter = new EscapeFormula();
$writer = Writer::from('php://temp', 'r+');
$writer->addFormatter($formatter->escapeRecord(...));
$writer->insertOne(['2', '2017-07-25', 'Important Client', '=2+5', 240, null]);
$writer->toString();
//outputting a CSV Document with all CSV Formula Injection escaped
//"2,2017-07-25,\"Important Client\",\"\t=2+5\",240,\n"
Conversely, if you obtain a CSV document containing escaped formula field you can use the Esca[eFormula::unescapeRecord to remove any escaping character.
use League\Csv\EscapeFormula;
use League\Csv\Reader;
$formatter = new EscapeFormula();
$reader = Reader::from('/path/to/my/file.csv');
$reader->addFormatter($formatter->unescapeRecord(...))
$reader->first();
// returns ['2', '2017-07-25', 'Important Client', '=2+5', '240', '']
// the escaping characters are removed.
Usage with PHP stream resources
You can use the EscapeFormula to format your records before calling fputcsv or SplFileObject::fputcsv.
use League\Csv\EscapeFormula;
$resource = fopen('/path/to/my/file', 'r+');
$formatter = new EscapeFormula("`");
foreach ($iterable_data as $record) {
fputcsv($resource, $formatter->escapeRecord($record));
}
Conversely, if you have a CSV document with escaped formula, you can access the original content using the new
EscapeFormula::unescapeRecord to remove any escaping character.
use League\Csv\EscapeFormula;
$resource = fopen('/path/to/my/file', 'r');
$formatter = new EscapeFormula("`");
while (($data = fgetcsv($resource)) !== false) {
$record = $formatter->unescapeRecord($data);
}