So I am wanting to allow users to:
1. Upload a .csv file (mystudents.csv)
2. Import the rows in the .csv
3. Create a PHP array for all this
4. Insert this information into a database
I have the following code to upload the file and create the array.
public function studentImport()
{
ini_set('auto_detect_line_endings', TRUE);
$config['upload_path'] = './static/files/importFiles';
$config['allowed_types'] = '*';
$config['max_size'] = '800';
$this->load->library('upload', $config);
if ( ! $this->upload->do_upload())
{
var_dump($this->upload->display_errors());
}
else
{
$data = $this->upload->data();
$file_path = './static/files/importFiles/'.$data['file_name'];
$rows = array_map('str_getcsv', file($file_path));
if($rows){
$header = array_shift($rows);
$csv = array();
foreach($rows as $row) {
$csv[] = array_combine($header, $row);
}
var_dump($csv);
}
}
}
The file gets uploaded just fine, but the errors happens with the line: $rows = array_map('str_getcsv', file($file_path));
And that error is:
array_map() [function.array-map]: The first argument, 'str_getcsv', should be either NULL or a valid callback
What do I need to do to make this work out?
looks like the function str_getcsv is not available
Test it with
if (function_exists('str_getcsv')) {
print "str_getcsv defined\n";
} else {
print "str_getcsv not defined\n";
}
if function exists try
$csv= file_get_contents($file_path);
$array = str_getcsv($csv);
print json_encode($array);
or
$csv= file_get_contents($file_path);
$array = array_map('str_getcsv', explode("\n", $csv));
print json_encode($array);
Related
I'm looking to read a CSV export file with PHP. I have access to the File Path Variable called $file_path.
How would I sort the CSV export file by a specific column and then sort it again by a second column? and then save the CSV file to the same file name and file path.
UPDATE:
I got it to read the CSV, then sort it and also save it to the CSV. However, it's also sorting the headers. I am trying to use array_shift and array_unshift but when I use array_shift with a multi-layer array, I am getting an error. (unshift works fine though).
function wp_all_export_after_export($export_id, $exportObj)
{
// Check whether "Secure Mode" is enabled in All Export -> Settings
$is_secure_export = PMXE_Plugin::getInstance()->getOption('secure');
if (!$is_secure_export) {
$filepath = get_attached_file($exportObj->attch_id);
} else {
$filepath = wp_all_export_get_absolute_path($exportObj->options['filepath']);
}
$handle = fopen($filepath, 'r') or die('cannot read file');
$binNumber = array();
$category = array();
$rows = array();
$header = array();
//build array of binNumbers, Categories, and array of rows
while (false != ( $row = fgetcsv($handle, 0, ',') )) {
$binNumber[] = $row[3];
$category[] = $row[1];
$rows[] = $row;
}
fclose($handle);
$header = $rows[0];
array_shift($rows);
//sort array of rows by BinNumber & then Category using our arrays
array_multisort($binNumber,SORT_ASC, $category, SORT_ASC, $rows);
array_unshift($rows,$header);
$file = fopen($filepath,"w");
foreach ($rows as $line) {
fputcsv($file, $line);
}
fclose($file);
}
add_action('pmxe_after_export', 'wp_all_export_after_export', 10, 2);
I have a script which takes a zipped CSV file, unzips it, and removes duplicate entries. It was mostly working, until I moved the unzip code into a function. Now it fails to unzip the .zip file, but doesn't show an error.
Checked file/folder permissions, everything is 777 on dev machine.
<?php
//
//huge memory limit for large files
$old = ini_set('memory_limit', '8192M');
//
//create a string like the filename
$base_filename = 'csv-zip-file'.date('m').'_'.date('d').'_'.date('Y');
//
//if the file exists ...
//unzip it
//read it to an array
//remove duplicates
//save it as a new csv
if (file_exists($base_filename.'.zip')) {
$zip_filename = $base_filename.'.zip';
echo "The file <strong>$zip_filename</strong> exists<br>";
unzip($zip_filename);
$csv = csv_to_array();
$csv = unique_multidim_array($csv,"Project Id");
var_dump($csv);
} else {
echo "The file <strong>$base_filename.zip</strong> does not exist";
}
function unzip($file_to_unzip) {
$zip=new ZipArchive();
if($zip->open($file_to_unzip)==TRUE) {
$address=__DIR__;
$zip->extractTo($address);
$res=$zip->close();
echo 'ok';
}
else{
echo 'failed';
}
}
function unique_multidim_array($array, $key) {
$temp_array = array();
$i = 0;
$key_array = array();
foreach($array as $val) {
if (!in_array($val[$key], $key_array)) {
$key_array[$i] = $val[$key];
$temp_array[$i] = $val;
}
$i++;
}
return $temp_array;
}
function csv_to_array () {
// global $filename;
global $base_filename;
$rows = array_map('str_getcsv', file($base_filename.'.csv'));
//using array_pop to remove the copyright on final row
array_pop($rows);
$header = array_shift($rows);
$csv = array();
foreach ($rows as $row) {
$csv[] = array_combine($header, $row);
}
return $csv;
}
Interesting problem you have here.
Output $file_to_unzip right inside the function.
Does $zip->* have an last_error or last_response method? See
what the ZipArchive class IS returning.
Do you have access to the php error logs? Let's look there for any output.
I tried to convert an csv file to an array with str_getcsv in php. Afterwards I want to check if the form submit is in the csv file alreaddy.
My code:
//get form input
$email = $_POST["email"];
//create array
$csv = array('str_getcsv', file('file.csv'));
//functio to check csv content for $email
function val() {
if (in_array($email, $csv)) {
echo "Enthalten";
}
else {
echo "Nicht enthalten";
}
}
The check is working now. But the code inside of the else {} statement ist not.
<?php
$email = $_POST["email"];
$csv = array_map('str_getcsv', file('file.csv'));
foreach ($csv as $row) {
if (in_array($email, $row)) {
echo "Error";
} else {
// this code is working fine if seperated
$list = array (array($email),);
$fp = fopen('file.csv', 'a');
foreach ($list as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
// here is a working skript to send an email to the $email recipient
}
}
?>
array_map('str_getcsv', file('file.csv')) will return a multi-dimensional array. in_array() isn't going to work like this.
You'll need to iterate over each row in the CSV to look for the email.
//get form input
$email = $_POST["email"];
//create array
$csv = array_map('str_getcsv', file('file.csv'));
foreach ($csv as $row) {
if (in_array($email, $row)) {
echo "Enthalten";
} else {
echo "Nicht enthalten";
}
}
first convert your csv file into array.
$csv = array_map('str_getcsv', file('file.csv'));
secondly, use array_search for the email inside the array above. (e.g: http://php.net/manual/en/function.array-search.php)
$key = array_search($email, $csv);
if email exist, it will return you the key inside the array.
In a script I'm having I'm pulling a csv from a remote server using ftp. I save this file locally and then open the file. I loop through all the contents of the file matching a certain value against it. If it matches, the script can continue.
Enough talking. Lets show some code...
$filename = 'ftp://.....';
$localCsv = '/tmp/'.date('Ymd').'.csv';
if (!file_exists($localCsv)) {
$content = file_get_contents($filename);
file_put_contents($localCsv, $content);
}
Now that we have the file created. We can continue to loop.
$handle = fopen($localCsv, "r");
while(!feof($handle)) {
$rows[] = fgets($handle);
}
fclose($handle);
$results = array();
foreach ($rows as $rid => $row) {
$columns = explode("\t", $row);
$results[$columns[2]] = $columns;
}
if (array_key_exists($searchValue, $results)) {
... Continue script ...
}
There is just one tiny little problem with this method. It's so slow it's almost going backwards.
Heres all baked together, maybe thats faster?
$handle = fopen($localCsv, "r");
$results = array();
while(!feof($handle)) {
$columns = explode("\t", fgets($handle));
$results[$columns[2]] = $columns;
if ($columns[2] == $searchValue) {
//SEARCH HIT
}
}
fclose($handle);
If thats not working you could try the csv-specific methods that are in PHP
How can I get the contents of a CSV file into a MySQL database row by row? Ive tried a few methods but can never get more than one row returned, using fgetcsv. One method I've tried that seemed to come so close to working:
$fileName = $_FILES['SpecialFile']['name'];
$tmpName = $_FILES['SpecialFile']['tmp_name'];
$fileSize = $_FILES['SpecialFile']['size'];
if(!$fileSize)
{
echo "File is empty.\n";
exit;
}
$fileType = $_FILES['SpecialFile']['type'];
$file = fopen($tmpName, 'r');
if(!$file)
{
echo "Error opening data file.\n";
exit;
}
while(!feof($file))
{
$data = str_replace('"','/"',fgetcsv($file, filesize($tmpName), ","));
$linemysql = implode("','",$data);
$query = "INSERT INTO $databasetable VALUES ('$linemysql')";
return mysql_query($query);
}
fclose($file);
only enters one row, but if I print_r $data it returns all the rows. How do I get it to insert all th rows?
Another method:
$data = str_getcsv($csvcontent,"\r\n","'","");
foreach($data as &$Row)
{
$linearray = str_getcsv($Row,',',''); //parse the items in rows
$linemysql = implode("','",$linearray);
echo $query = "INSERT INTO $databasetable VALUES ('$linemysql')";
}
This almost works too, but there is text within the csv that also contains new lines, so I dont know howto split the actual rows and not the new lines in the text as well.??
this function return an array from csv file
function CSVImport($file) {
$handle = fopen($file, 'r');
if (!$handle)
die('Cannot open file.');
$rows = array();
//Read the file as csv
while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
$rows[] = $data
}
fclose($handle);
return $rows;
}
// this will return an array
// make some logic to read the array and save it
$csvArray = CSVImport($tmpName);
if (count($csvArray)) {
foreach ($csvArray as $key => $value) {
// $value is a row of adata
}
}
I think this is what you are looking for.
function getCSVcontent($filePath) {
$csv_content = fopen($filePath, 'r');
while (!feof($csv_content)) {
$rows[] = fgetcsv($csv_content,1000,";");
}
fclose($csv_content);
return $rows;
}
Make sure that you new line separator is ";" or give the correct one to fgetcsv(). Regards.