I need to store a string in a MySQL database. The values will later be used in a CSV. How do I escape the string so that it is CSV-safe? I assume I need to escape the follow
Use fputcsv() to write, and fgetcsv() to read.
fputcsv()
is not always necessary especially if you don't need to write any file but you want to return the CSV as an HTTP response.
All you need to do is to double quote each value and to escape double quote characters repeating a double quote each time you find one.
Here a few examples:
hello -> "hello"
this is my "quote" -> "this is my ""quote"""
catch 'em all -> "catch 'em all"
As you can see the single quote character doesn't need any escaping.
Follows a full working example:
<?php
$arrayToCsvLine = function(array $values) {
$line = '';
$values = array_map(function ($v) {
return '"' . str_replace('"', '""', $v) . '"';
}, $values);
$line .= implode(',', $values);
return $line;
};
$csv = [];
$csv[] = $arrayToCsvLine(["hello", 'this is my "quote"', "catch 'em all"]);
$csv[] = $arrayToCsvLine(["hello", 'this is my "quote"', "catch 'em all"]);
$csv[] = $arrayToCsvLine(["hello", 'this is my "quote"', "catch 'em all"]);
$csv = implode("\r\n", $csv);
If you get an error is just because you're using an old version of PHP. Fix it by declaring the arrays with their old syntax and replacing the lambda function with a classic one.
For those of you trying to sanitise data using PHP and output as a CSV this can be done using PHP's fputcsv() function without having to write to a file as such:
<?php
// An example PHP array holding data to be put into CSV format
$data = [];
$data[] = ['row1_val1', 'row1_val2', 'row1_val3'];
$data[] = ['row2_val1', 'row2_val2', 'row2_val3'];
// Write to memory (unless buffer exceeds 2mb when it will write to /tmp)
$fp = fopen('php://temp', 'w+');
foreach ($data as $fields) {
// Add row to CSV buffer
fputcsv($fp, $fields);
}
rewind($fp); // Set the pointer back to the start
$csv_contents = stream_get_contents($fp); // Fetch the contents of our CSV
fclose($fp); // Close our pointer and free up memory and /tmp space
// Handle/Output your final sanitised CSV contents
echo $csv_contents;
Don't store the data CSV escaped in the database. Escape it when you export to CSV using fputcsv. If you're storing it CSV escaped you're essentially storing garbage for all purposes other than CSV exporting.