My ideal fix would be a function that can take a CSV file that does not have forced encapsulation (no quotes around values if the value has no spaces or is just a number) and convert it into a CSV file that makes sure every field is encapsulated with double quotes.
<?php
$raw_file = BASE_DIR."pathto/csv.csv";
$fixed_file = BASE_DIR."pathto/fixed.csv";
convert_file($raw_file, $fixed_file);
//move on with life!!
?>
Thanks for you help!
Use fgetcsv to get the contents of your original csv file and fputcsv (using the fourth parameter) to build the encapsulated file.
For example, supposing your column separator is ; :
<?php
$raw_file = BASE_DIR."pathto/csv.csv";
$fixed_file = BASE_DIR."pathto/fixed.csv";
// Getting contents
$raw_handle = fopen($raw_file, 'r');
$contents = array();
while (($data = fgetcsv($raw_handle, 0, ';')) !== false) {
$contents[] = $data;
}
fclose($raw_handle);
// Putting contents
$fixed_handle = fopen($fixed_file, 'w');
foreach ($contents as $line) {
fputcsv($fixed_handle, $line, ';', '"');
}
fclose($fixed_handle);
//move on with life!!
?>
Related
I'm not able to read a tabulator seperarated csv file (and yes, i know its csv and no tsv and the c is for tabulator...) with php and seperate it right. When i give out my imported Data with echo or readfile all the tabulators are replaced by a space and i can't use space as a sperator.
Actually i'm a bit confused that this problem is not very common when i use Google, so maybe i'm the problem...
The Problem exists with XAMPP v3.2.3 and PHP Version 7.3.5
$tempFile = fopen($tempFilePath, "r");
$uploadData = fread($tempFile, filesize($tempFilePath));
fclose($tempFile);
echo $uploadData;
$uploadData = str_replace('"','',$uploadData);
$uploadData = str_replace('\r\n','\n',$uploadData);
$uploadData = str_replace('\r','\n',$uploadData);
$uploadData = str_replace(';',',',$uploadData);
$uploadData = str_replace('\t',',',$uploadData); //Here i'm trying to replace the tabulator with a colon to work with it afterwards
When reading a CSV file in PHP, it is best to use the fgetcsv function. With it you can specify the deliminator of the file. The function will output a row of the file. Your deliminator should be "\t".
You should use fgetcsv function which already has functionality to read tsv.
Like this:
$uploadData = [];
if (($handle = fopen("test.csv", "r")) !== false) {
while (($data = fgetcsv($handle, 0, "\t")) !== false) {
$uploadData[] = $data;
}
fclose($handle);
}
If you want to convert tsv to csv you can use inverse function fputcsv:
$fh = fopen('file.csv');
foreach ($uploadData as $datum) {
fputcsv($fh, $datum);
}
fclose($fh);
If you want automatically detect csv delimiter maybe this article can help you.
i am having difficulties with extracting specific text from a text file. I have tried many different ways like using fopen or file to open the file but this wont allow me to use any of the string functions. So i have decided to use file_get_contents and extract the text i want with the string methods as follows:
<?php
$data = [];
$file =
file_get_contents("data.txt", 0, NULL, 148);
list($id, $data_names) = preg_split('[:]', $file);
array_push($names, $data_names);
echo $emails[0];
?>
I used preg_split to split the text i want at a specific character (:) and i put the data in an array. Which worked for the first line but i don't know how to go about doing it for the rest of the lines, i've tried a while loop but that just ends up in an infinite loop.
data.txt formatted like this:
1:hannah.Smith
2:Bob.jones
3:harry.white
....
Any suggestions on how to do this or a better approach would be greatly appreciated.
There is a function for that. This isn't CSV but change the delimiter. To just get the names:
$handle = fopen("data.txt", "r"));
while(($line = fgetcsv($handle, 0, ":")) !== FALSE) {
$names[] = $line[1];
}
To index the names by the ids:
while(($line = fgetcsv($handle, 0, ":")) !== FALSE) {
$names[$line[0]] = $line[1];
}
To get the ids and names in a multidimensional array, use:
while(($names[] = fgetcsv($handle, 0, ":")) !== FALSE) {}
Well you are not assigning the return value of file_get_contents to a variable. So the contents of the file are not being used.
You can use the file function. It reads the contents of a file to an array. Each element of the array is a line in the file. You can then loop over the array and parse each line. For example:
$names = array();
$file = file_get_contents("data.txt");
for ($count = 0; $count < count($file); $count++) {
list($id, $name) = $file[$count];
$names[] = $name;
}
/** print the contents of the names array */
print_R($names);
I am getting the contents of a CSV file and displaying (it works).
if (($handle = fopen($url, 'r')) === false) {
die('Error opening file');
}
$headers = fgetcsv($handle, 1024, ',');
$complete = array();
while ($row = fgetcsv($handle, 1024, ',')) {
$complete[] = array_combine($headers, $row);
}
fclose($handle);
However, in this CSV file there is a field that has contents for example like this:
"123456,123456,123456,123456"
I think my code isn't processing because of the double quotes, I think I need to convert to single quotes. If thats the case how would I integrate the following (I was thinking something like):
str_replace('"',"'", $url);
Look at the other parameters for fgetcsv()
By default the enclosure character is set to ", which means anything between quotes should be considered a single value. Replace that parameter with what you actually use as the enclosure character in the csv and it will work.
Something like (if your enclosure character is '):
while ($row = fgetcsv($handle, 1024, ',', "'")) {
Better than to read it wrong and try to fix it afterwards with str_replace.
I have a CSV file and we know excel does its thing with commas in a field by enclosing them in double quotation marks for instance i have a file
Product Name,Product Code
Product 1,AAA
"Prod,A,B",BBB
How can I use RegExp to replace the quotation marks with "." instead but only within quotation marks so i get
Product Name,Product Code
Product 1,AAA
Prod.A.B,BBB
as output
CSV handling functions (fgetcsv(), fputcsv()) are much better for this - they will handle edge cases and will likely be far more reliable than any regex you can come up with.
// Open the file
$fp = fopen($pathToCsvFile, 'r+');
// Create an array of modified data
$tmp = array();
while (($row = fgetcsv($fp, 8192)) !== FALSE) {
foreach ($row as &$field) $field = str_replace(',', '.', $field);
$tmp[] = $row;
}
// Truncate the file and put the pointer at the beginning
ftruncate($fp, 0);
rewind($fp);
// Write the modified data back and close the file
foreach ($tmp as $row) {
fputcsv($fp, $row);
}
fclose($fp);
EDIT Following your comment about not wanting to read from/write to disk, you can do this:
// Lets say the raw CSV data is held in this variable as a string
$rawCsvData = 'Product Name,Product Code
Product 1,AAA
"Prod,A,B",BBB';
// Open a virtual file pointer to memory and fill it with your data
$fp = fopen('php://memory', 'w+');
fwrite($fp, $rawCsvData);
// Start from the beginning of the pointer
rewind($fp);
// ... INSERT CODE FROM ABOVE HERE (minus the fopen()/fclose())
$modifiedCsvData = stream_get_contents($fp);
fclose($fp);
This will do multiple replaces, and remove the quotes.
<?php
$data = 'Product Name,Product Code
Product 1,AAA
"Prod,A,B",BBB';
$rgx = '/"(.+?)"/';
preg_match_all($rgx, $data, $matches);
$x = 0; $max = count($matches[0]);
while($x < $max){
$replace = str_replace(",", ".", $matches[1][$x]);
$data = str_replace($matches[0][$x], $replace, $data);
$x++;
}
echo $data;
?>
whats wrong with this, when i echo out a row from the csv file and concat anything to the end of the row, it doesnt show up, instead all the rows are echo'ed and the concated string only shows up once at the very end, is this some kind of buffering thing that wont let me concat strings with stuff from my csv file, its running on my local wamp server, and i have tryed different line delimiter in my expload function, im sure the file only uses \n at the end of a line
im trying to parse a csv file row by row so i can check the content of it before i use it to construct an sql statement and insert it into my database.
$file = fopen($filename, "r")
$filesize = filesize($filename);
$filecontent = fread($file, $filesize);
fclose($file);
$rows = explode("\n", trim($filecontent));
foreach ($rows as $row)
{
echo $row . '<br />';
}
You are splitting the string by the string \n. Unless the actual string "\n" appears anywhere in the file, this will probably do nothing. You probably meant "\n" (double quotes), which makes this an actual line break.
Your overall process is terribly inefficient though. You should use fgetcsv and process the file line by line, instead of reading it into memory all at once.
$handle = fopen('test.csv', 'r');
while (($row = fgetcsv($handle)) !== false) {
foreach ($row as $field) {
echo $field . '<br />';
}
}
fclose($handle);
Use fgetcsv() function to convert a CSV file to an array:
$csvFile = "test.csv";
$csvSeparator = ",";
$csvFileLength = filesize($csvFile);
$handle = fopen($csvFile, "r");
$csvData = fgetcsv($handle, $csvFileLength, $csvSeparator);
fclose($handle);
Dump the data to show the structure:
var_dump($csvData);
Now you can convert the data to use in database.