I've got a form which submits data to a csv file.
When a user inputs a comma to a field, it destroys my csv structure.
I want to convert inputted commas so that they can get displayed as a character.
I tried this:
$_POST["field"] = str_replace(",", "','", $_POST["field"]);
Use html encoding for instant relief , but still my recommendation to use phpExcel
$comma=",";
$_POST["field"] = str_replace(",", $comma, $_POST["field"]);
You can use fputcsv() to write, and fgetcsv() to read the file, it automatically converts your string.
A simple example for writing the data:
$csv = fopen('file.csv', 'w');
$array = array($csv);
fputcsv($csv, $array);
And reading the data:
$csv = fopen('file.csv','r');
print_r(fgetcsv($csv));
Probably not the best answer, but it does work.
You could replace the comma with a random string when inputting to the CSV as below:
$commastring = str_replace(",", "/zwdz/", $tempstring);
and then when you need to output the comma somewhere on your website (if a database website) you can do the opposite str_replace
You can escape coma like this:
$_POST["field"] = str_replace(",", "\,", $_POST["field"]);
Or you can put string in quotes
$_POST["field"] = "'".$_POST["field"]."'";
Related
I have a link on a page that, when clicked, exports an array of data to csv using fputcsv. When Excel displays the data, there is a column that looks like an integer, but it's not, and Excel is converting it to scientific notation. How do I export the data so that this column is displayed as characters (not a scientific number) ?
The code I'm using for export is from Alain Tiemblo's answer here:
Link to Code
function array2csv(array &$array)
{
if (count($array) == 0) {
return null;
}
ob_start();
$df = fopen("php://output", 'w');
fputcsv($df, array_keys(reset($array)));
foreach ($array as $row) {
fputcsv($df, $row);
}
fclose($df);
return ob_get_clean();
}
Not sure about Excel, but LibreOffice and OpenOffice will import fields as strings if the CSV field is quoted. For example, you want your CSV to be something like:
foo,bar,"12345",baz
(You may also have to check "Quoted field as text" option in the file open dialog.)
Edit: PHP's fputcsv() function will only use quote wrappers if it needs to, so you'll likely have to manually force quotes around the actual field value yourself:
$field = 12345;
$quoted_field = '"' . $field . '"';
Edit 2: If you don't need to worry about escaping, this might work for you instead of fputcsv():
fwrite($fp, '"' . implode($fields, '","') . '"' . "\n");
Try to force your int into a string before your fputcsv.
For example
$foo = "$foo";
http://php.net/manual/en/language.types.type-juggling.php
But then again Excel might make up its own mind when converting your CSV to an Excel format...
Also this question might help: Excel CSV - Number cell format
You could cast the value to string using strval.
converting integer to string using :-
string, strval or enclosing value in double/single quotes , or even concat space with the variable does not work because CSV doesn't hold field type information.
The only way I found is to add some character or symbol to forcefully make it string but that will show in output too.
I'm sending comma separated values through a URL (key, value). I'm encoding them with Javascript's escape() and then replacing the commas within each value with %2c . The problem is at the PHP end the commas that are encoded are turned into "," BEFORE explode() takes place and then my string containing commas is broken up and it doesn't save right.
How can I stop PHP from converting my encoded bits back into unencoded bits?
My JS for each input is:
fieldData += $(this).attr("id")+","+escape($(this).html()).replace(/,/g,"%2c")+",";
My PHP is:
$fieldData = explode(",", $_POST['fieldData']);
Tried (along with other things):
$fieldData = explode(",", urlencode($_POST['fieldData']));
I would suggest using base64encode/decode for this.
The javascript would look something like this: http://jsfiddle.net/Y6yuN/
<script src='http://javascriptbase64.googlecode.com/svn/trunk/base64.js'></script>
fieldData += $(this).attr("id")+","+escape(Base64.encode($(this).html()))+",";
The escape is for the trailing =
So you would end up with comma delimited base64 encoded strings.
On the PHP side:
$fieldData = explode(",", $_POST['fieldData']);
foreach ($fieldData as $k => $v){
$fieldData[$k] = base64_decode(urldecode($v));
}
Your post is not really well explained, but I think you want to decode the data passed by JS. So, the code should be:
$fieldData = explode(",", urldecode($_POST['fieldData']));
Try to write it better if I am wrong!
How'd I go about reading a tab delimited .txt file and then coding it so it puts each column of data(that is seperated with a tab) into a php variable.
for example....
505050 somedata moredata
and then, writing these variables to
$id
$somedata
$moredata
I read into fgetcsv and making an array although it seemed to make the whole line an array i need to split it into variables so that i can write it to individual columns in the MySQL database,
Can anyone give me any pointers?
Thanks so much...
A combination of fgetcsv() and list() will be the most efficient way to split this into named variables:
list($id, $somedata, $moredata) = fgetcsv($fp, 0, "\t");
However, you do not need to have them as named variables in order to insert them in MySQL, you can just use the raw array returned by fgetcsv():
$row = fgetcsv($fp, 0, "\t");
$query = "
INSERT INTO `tablename`
(`id`, `somedata`, `moredata`)
VALUES
('{$row[0]}', '{$row[1]}', '{$row[2]}')
";
Don't forget to escape the data before using it in a query ;-)
explode() will split a string. Try this:
list($id, $somedata, $moredata) = explode("\t", $string);
Where $string is the string you want to split. For more info about explode() and list(), just look up on php.net.
You can use explode():
http://php.net/manual/en/function.explode.php
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 following: comma, single quote, double quote.
PHP's addslashes function does:
single quote ('), double quote ("), backslash () and NUL (the NULL byte).
So that won't work. Suggestions? I'd rather not try to create some sort of regex solution.
Also, I need to be able to unescape.
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.
Currently I am working on a PHP script to output a CSV file from entries in a MySQL database. My problem lies in how to correctly output the values. Many of the entries in the MySQL database will contain commas and quotes, which destroy the format of the CSV file if I just plainly print them out to the file.
I'm aware that I can surround the text in quotes, but the entries that contain quotes would mess up the format of the file.
My question is, what can I do to keep this from happening?
Also, do new lines affect the interpretation of the file?
In addition, I'd rather not use the fputcsv function in PHP. I'm attempting to make the PHP script output the contents of the file (with appropriate headers) rather than write to a new file.
Thanks in advance!
Regards,
celestialorb
I think your dismissal of fputcsv might have been premature. In the comments of the fputcsv manual there's an example where they use fputcsv to output to the browser instead of a file.
http://php.net/manual/en/function.fputcsv.php
Here is that code, plus some headers to show that it does indeed prompt the user to download a csv file.
$mydata = array(
array('data11', 'data12', 'data13'),
array('data21', 'data22', 'data23'),
array('data31', 'data32', 'data23'));
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"my-data.csv\"");
outputCSV($mydata);
function outputCSV($data) {
$outstream = fopen("php://output", 'w');
function __outputCSV(&$vals, $key, $filehandler) {
fputcsv($filehandler, $vals, ';', '"');
}
array_walk($data, '__outputCSV', $outstream);
fclose($outstream);
}
The process is called escaping, and most parsers (included PHP's) use the backslash to escape characters:
"This string contains literal \"quotes\" denoted by backslashes"
You can escape characters in a string with addcslashes:
// escape double-quotes
$string = addcslashes('this string contains "quotes"', '"');
echo $string; // 'this string contains \"quotes\"'
Given an array of data you want to separate by commas, you can do the following:
// Escape all double-quotes
foreach ($data as $key => $value)
$data[$key] = addcslashes($value, '"');
// Wrap each element in double quotes
echo '"' . implode('", "', $data), '"';
I have found tab separated value files to be helpful in these situations. TSV is less susceptible to the issues with commas etc in your data.