How to parse a .csv file into a multidimensional array in PHP? - php

I'm a newbie in PHP and I'm trying to make a todo list that communicates with a .csv file,. So far I've managed to write a function that writes the user input into the csv file, but I'm stuck on writing a function that would parse (I'm not even sure if this is the correct term) every line of the .csv file into a multi dimensional array, so I could display every line of the list to my convenience in the PHTML file.
Here's what I have so far :
`<?php
//
// ─── DATA ────────────────────────────────────────────────────────────────────
//
$user_entry = array(
'title' => '',
'description' => '',
'date' => '',
'priority' => ''
);
// puts the data the users entered into an array
$user_entry['title'] = $_POST['title'];
$user_entry['description'] = $_POST['description'];
$user_entry['date'] = $_POST['date'];
$user_entry['priority'] = $_POST['priority'];
//
// ─── FUNCTIONS ──────────────────────────────────────────────────────────────────
//
function writeInList() {
//parses the $user_entry array into the .csv file
global $user_entry;
$file = fopen("todo.csv","a");
fputcsv($file, $user_entry, ",");
fclose($file);
}
function displayList() {
//That's where I'm stuck.
$file = fopen("todo.csv","r");
$fileCountable = file("todo.csv");
for ($i = 0; $i < count($fileCountable); $i++) {
$csvContent = fgetcsv($file, 1000, ",");
foreach ($csvContent as $value){
$var[$i] = $value;
}
echo '<br>';
}
fclose($file);
}
//
// ─── MAIN CODE ─────────────────────────────────────────────────────────────
//
writeInList();
include 'todolist.phtml';`
I'm sorry if it has been discussed before. I've searched a lot and found similar questions but can't get to make it work in my own code. Thanks a lot in advance if anyone takes the time to take a look at my code !
This is also my very first time posting here so I hope I'm doing it right.

You did pretty good. You can look at fgetcsv documentation for more. I would have change you function so it will get the argument as input (try avoid using global)
// insert data
function writeInList($user_entry, $path ) {
$file = fopen($path ,"a");
fputcsv($file, $user_entry, ",");
fclose($file);
}
//extract data
function getList($path, $limit = 100000) {
$file = fopen($path, "r");
if (!$file) return null; // or throw error or print to log
$allRows = []; //
while (($data = fgetcsv($file, $limit, ",")) !== FALSE) {
$allRows[] = $data; // as fgetcsv return array already exlode by ","
}
fclose($file);
return $allRows;
}
Now you have 2-Dim array return from getList. Use is as getList("todo.csv") and display as you pleased.
Hope that helps!

Related

Value's not visible when importing CSV after values are added by fputcsv with php

I'm trying to make a translation module for my web project and i hit a wall. I written two functions, one for importing the CSV data and the other for changing, deleting and adding new data to the CSV file.
Everything works like a charm except the adding part. It adds the data to the CSV file but when i want to import it in the website via PHP it doesn't display the added values. (It see that their should be values but it gives empty results in return) the function i use for reading the csv file is:
// Load in CSV (File name, delimiter, Fixed array[key,value] (optional))
function load__CSV($filename='', $delimiter=';', $fixed = null){
if(!file_exists($filename) || !is_readable($filename)) {
return FALSE;
}
$header = NULL;
$data = array();
if (($handle = fopen($filename, 'r')) !== FALSE) {
while (($row = fgetcsv($handle, 100000, $delimiter)) !== FALSE) {
if (!$header) {
$header = $row;
} else {
$data[] = array_combine($header, $row);
}
}
fclose($handle);
}
if($fixed != null) {
foreach($data as $entry){
$set_csv[$entry[''.$fixed[0].'']] = $entry[''.$fixed[1].''];
}
} else {
$set_csv = $data;
}
return $set_csv;
}
The function i use to add, edit or remove CSV content is:
// Change csv
function update__csv($csv = 'csv/language.csv',$key = array(2,''),$values = array([3,''],[4,'']),$status = 'change') {
$input = fopen(BASE_URL.$csv, 'r');
$output = fopen(BASE_URL.'csv/temporary.csv', 'w');
while (false !== ($data = fgetcsv($input, 10000, ";"))) {
if ($data[$key[0]] == $key[1]) {
foreach ($values as $value) {
$data[$value[0]] = $value[1];
}
if ($status == 'change' || $status == 'new') {
fputcsv($output, $data, ";");
}
} else {
fputcsv($output, $data, ";");
}
}
if($status == 'new'){
fputcsv($output, $values, ";");
}
fclose( $input );
fclose( $output );
unlink(BASE_URL . $csv);
rename(BASE_URL . 'csv/temporary.csv', BASE_URL . $csv);
}
If i add new values to the CSV file and then open the CSV on my PC and safe it again (without changing a thing) to CSV with UTF-8 encoding then it works as expected and loads the correct data. If i open the CSV in Notepad++ i see this difference between manual added items and php added items:
I tried other encoding methods but that is kinda new for me so i think i did something wrong. Thank you in advance for helping me!
I did find the answer after some more debugging. One value of the array didn't contain a string but a true or false statement. This meant that it didn't add the data the right way into the CSV file.
I fixed it by adding strval() to every variable before putting it into an array.

replace rows from one csv file to another csv where id of is the samePHP?

I have one excel orginal.csv file
ID Name Price
1 Xblue 12
2 Yblue 32
3 Zblue 52
And another copy.csv file
ID Name Price
1 Xblue 89
2 Yblue 43
3 Zblue 45
I want to replace rows from orginal.csv to copy.csv where ID is the same.
Can I do this manually or maybe somehow using PHP?
I search for some options on the internet, but I only found getcsv and readcsv functions that can't help me in this case. Cause this is something like updating CSV file.
It may end up in request timeout in PHP because it requires so many loops to do it. If someone can reduce the time complexity of this program then it will work. if it even works it will take a lot of time to do it.
while(! feof($f_pointer)){ //open old csv to update loop1
$ar=fgetcsv($f_pointer); // getting first row
for($i=0;$i<count($ar);$i++){ //loop2 first row array
$f_pointer2=fopen("new.csv","r"); open new csv to get data
while(! feof($f_pointer2)){ // loop3 to find ID in new csv
$ar2=fgetcsv($f_pointer2); //getting each row in array
for($j=0;$j<count($ar2);$j++){ //loop4 to compare id of old csv to new csv and update data
if($ar[i] == $ar2[j]){
foreach ($ar2 as $fields) { //loop5
fputcsv($f_pointer, $fields);
}
}
}
}
}
}
?>
I've created a little soulution. If order is important you don't have to index the array and loop through the copied array.
<?php
if(file_exists('output.csv'))
{
unlink('output.csv');
}
function fputcsv_eol($handle, $array, $delimiter = ',', $enclosure = '"', $eol = "\n") {
$return = fputcsv($handle, $array, $delimiter, $enclosure);
if($return !== FALSE && "\n" != $eol && 0 === fseek($handle, -1, SEEK_CUR)) {
fwrite($handle, $eol);
}
return $return;
}
function scanFile($sFilename, $iIndexColumn)
{
$rFile = fopen($sFilename, 'r');
$aData = array();
while(($aLine = fgetcsv($rFile)) !== false)
{
$aData[$aLine[$iIndexColumn]] = $aLine;
}
fclose($rFile);
return $aData;
}
$iIndexColumn = 0;
$iValueColum = 2;
$aOriginalData = scanFile('original.csv', 0);
$aCopyData = scanFile('copy.csv', 0);
foreach($aOriginalData as $iID => $aOriginalDatum)
{
if(array_key_exists($iID, $aCopyData))
{
$aCopyData[$iID] = $aOriginalDatum;
}
}
$rFile = fopen('output.csv', 'w');
foreach($aCopyData as $aCopyDatum)
{
fputcsv_eol($rFile, $aCopyDatum, ',', '"',"\r\n");
}
fclose($rFile);

Importing csv into mysql (List of Codes)

So I have a list of codes (100,000) to be exact and I got them delivered in a csv file.
I want to put theses codes in a database so I can later get them using my php script.
However my question is how do I get my codes from the file in the right table?
This is what my database looks like at the moment.
The codes from the file need to be inserted in table code.
Hope someone can help me out with this one.
You probably will find this helpful (pls adjust the table and others names):
LOAD DATA INFILE 'codes.csv'
INTO TABLE codes
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;
(#id,code,#active)
SET id = null;
SET active = '1'
More details:
http://www.mysqltutorial.org/import-csv-file-mysql-table/
Try this:
you can upload your csv file and post it. then use this function.
this is the PHP code:
function get_csv_file($filename){
if (($handle = fopen($filename, "r")) !== false) {
$filesize = filesize($filename);
$firstRow = true;
$aData = array();
while (($data = fgetcsv($handle, $filesize, ";")) !== false) {
if($firstRow) {
$aData = $data;
$firstRow = false;
} else {
for($i = 0;$i < count($data); $i++) { //only for csv file
if($data[$i] != '')
$aData[] = $data[$i];
}
}
}
//print_r($aData);
fclose($handle);
$finalscrap = array_unique($aData);
// echo "<pre>";
// print_r($finalscrap);
// echo "<pre/>";
return $finalscrap; //this is your record as array format
}
}

How to pass data from a CSV file in PHP

I know this is going to be super simple when someone shows me but I can't seem to work it out. I'm trying to read in a csv file like the below and then pass it to a function called 'row'. The CSV has 4 columns, I want to read in a row and then split the data on a ',' and put it into the line $this->Row(array('','','','')); where I then want to move onto the next line, until I've finished all lines, does anyone have any ideas?
1,1,1,1
2,2,2,2
3,3,3,3
function LoadData($file)
{
$lines = file($file);
$data = array();
foreach($lines as $line){
$data[] = explode(',',trim($line));
$this->Row(array('','','',''));
}
}
Try this :
<?php
function getCsv($file) {
if (($handle = fopen($file, "r")) !== FALSE) {
while ( ( $data = fgetcsv( $handle, 100, ',' ) ) !== FALSE ) {
$this->Row($data);
}
fclose($handle);
}
}
getCsv('/path/to/file.csv');
?>

Yii - How to upload a csv to save in database?

i'm with some troubles figuring out how to read the CSV file that I upload, probably i'm missing something in my Controller code.
public function actionImport() {
$model = new Produtos;
$this->render('import', array('model' => $model) );
if( isset($_FILES['csv_file']) ) {
$handle = fopen($_FILES['csv_file']['tmp_name'], 'r');
if ($handle) {
while( ($line = fgetcsv($handle, 1000, ";")) != FALSE) {
$model->codigo = $line[0];
$model->nome = $line[1];
$model->descricao = $line[2];
$model->stock = $line[3];
$model->data_reposicao = $line[4];
$model->save();
}
}
fclose($handle);
}
}
This is only saving me the last line in the CSV... please some help!
Any help will be really appreciated.
Thank you
I think You missed the name of file, try $_FILES['csv_file']['tmp_name']
http://php.net/manual/en/features.file-upload.post-method.php for reference.
Also Yii does provide file handling, check http://www.yiiframework.com/doc/api/1.1/CUploadedFile for reference
Don't forget to check whether your data is successfully validated or not.
Insert this code between yours:
$model->data_reposicao = $line[4];
if (!$model->validate())
throw new Exception("Validation failed.");
$model->save();
So you can see what's going wrong.
$_FILES is an array, which contains ['element_name']-array. In your case $_FILES is an array of $_FILES['csv_file']['name'], $_FILES['csv_file']['type'], $_FILES['csv_file']['error'], $_FILES['csv_file']['size'] and $_FILES['csv_file']['tmp_name'].
So for short; $_FILES['csv_file'] is an array.
you are saving the same model instance again and again... that is why only the last line gets saved... you will have to create a new model for every line, i.e. in your while loop, add $model = new Produtos;
You need to initialise your model object every time when you need to insert your row into table. The code should be like:
public function actionImport() {
$model = new Produtos;
$this->render('import', array('model' => $model) );
if( isset($_FILES['csv_file']) ) {
$handle = fopen($_FILES['csv_file']['tmp_name'], 'r');
if ($handle) {
while( ($line = fgetcsv($handle, 1000, ";")) != FALSE) {
$modeln = new Produtos;
$modeln->codigo = $line[0];
$modeln->nome = $line[1];
$modeln->descricao = $line[2];
$modeln->stock = $line[3];
$modeln->data_reposicao = $line[4];
$modeln->save();
}
}
fclose($handle);
}
}
I know this is an old post, but I just came across this and just wanted to help someone who might be having the same issue (b/w issue is not with CSV or file upload)
Issue is with how Yii handles saving
You need to set isNewRecord attribute to true and primary key to NULL of model object before saving to save a new record everytime.
$model->PRIMARYKEYCOLUMN = NULL; //Replace PRIMARYKEYCOLUMN with the name of column
$model->isNewRecord = true;
$model->save();
You need to do above step whenever you are saving rows in loop.
$handle = fopen($_FILES['Userimportcsv']['tmp_name']['csv_file'], 'r');
if($handle) {
$row = 1;
while( ($line = fgetcsv($handle, 1000, ",")) != FALSE) {
if($row>1) {
$newModel = new Countries;
$newModel->countryName = $line[0];
$newModel->status = $line[1];
$newModel->save();
}
$row++;
}
}
fclose($handle);

Categories