Output contacts from csv file with PHP - php

I need to be able to output contacts via a loop on a page from a CSV file downloaded from Outlook.
If the user has the file on their local machine, I suppose I need some sort of upload mechanism, then let my script read uploaded file and then run the results via some loop and output one contact per line.
Each line will have a checkbox next to a contact and if checked, the form will post results and they will be written into db.
Normal format of Outlook .CSV example file here
I only need Name and email. First and last can be merged in just Name. I suppose i need to run some sort of email validation to reject malformed entries...
Just trying to understand what needs to be done.

You should look into fgetcsv, which can read your CSV file and return an array to you. This is really easy to work with.

$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
$row++;
for ($c=0; $c < $num; $c++) {
echo $data[$c] . "<br />";
}
}
fclose($handle);
}

For information about reading the csv file check out this http://php.net/manual/en/function.fgetcsv.php

Related

Edit CSV field value for entire column

I have a CSV that is downloaded from the wholesaler everynight with updated prices.
What I need to do is edit the price column (2nd column) and multiply the current value by 1.3 (30%).
My code to read the provided CSV and take just the columns I need is below, however I can't seem to figure out how to edit the price column.
<?php
// open the csv file in write mode
$fp = fopen('var/import/tb_prices.csv', 'w');
// read csv file
if (($handle = fopen("var/import/Cbl_4036_2408.csv", "r")) !== FALSE) {
$targetColumns = array(1, 2, 3); // get data from the 1st, 4th and 15th column
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$targetData = array(); // array that hold target data
foreach($targetColumns as $column){ // loop throught the targeted columns array
if($column[2]){
$data[$column] = $data[0] * 1.3;
}
$targetData[] = $data[$column]; // get the data from the column
}
# Populate the multidimensional array.
$csvarray[$nn] = $targetData; // add target data to csvarray
// write csv file
fputcsv($fp, $targetData);
}
fclose($handle);
fclose($fp);
echo "CSV File Written Successfully!";
}
?>
Could somebody point me in the right direction please, explaining how you've worked out the function too so I can learn at the same time.
You are multiplying your price column always as - $data[0] * 1.3.
It may be wrong here.
Other views:
If you are doing it once in a lifetime of this data(csv) handling, try to solve it using mysql itself only. Create the table similar to the database, import the .csv data into that mysql table. And then, SQL operate as you want.
No loops; no coding, no file read/write, and precise control over what you want to do with UPDATE. You just need to be aware of the delimiters (line separators eg. \r\n, column separators (eg. comma or tab or semicolon) and data encoding in double/single-quotes or not)
Once you modify your data, you can export it back to csv again.
If you want to handle the .csv file itself, open it in one connection (read only mode), and write to another file - saving the original data.
you say that the column that contains the price is the second but then use that index with zero. anyway the whole thing can be easier
$handle = fopen("test.csv", "r");
if ( $handle !== FALSE) {
$out = "";
while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
$data[1] = ((float)$data[1] * 1.3);
$out .= implode(";",$data) . "\n";
}
fclose($handle);
file_put_contents("test2.csv", $out);
}
this code open a csv file with comma as separator.
than read every line and for every line it's multiplies the second coloumn (index 1) for 1.3
this line
$out .= implode(";",$data) . "\n";
generate a line for new csb file. see implode on the officile documentation ...
after I close the connection to the file. and 'useless to have a connection with two files when you can do the writing of the second file in one fell swoop. the thing is true for small files

Importing data to MySQL from Excel in a PHP Website

I am building a website in which i want to give the users a choice to upload their excel file which has all the data.
Website is built on PHP, Database used- MySQL.
When a user uploads the excel sheet, all the data has to be imported into my Database. Now i want to do it programatically using PHP. Can anyone help me out with this. The code should also be able to extract data from multiple tabs in the excel file.
Thank you.
You can try with any of the below libraries if you want Excel file itself need to be imported.
http://phpexcel.codeplex.com/
http://sourceforge.net/projects/phpexcelreader/
Note :
Importing from Excel files is harder than improting from CSV files. So I suggest you to provide an option for importing into MySQL from CSV. (Users can convert XLS to CSV using Excel)
Look at PHP function fgetcsv at:
http://ca.php.net/manual/en/function.fgetcsv.php
Eg.
<?php
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
echo "<p> $num fields in line $row: <br /></p>\n";
$row++;
for ($c=0; $c < $num; $c++) {
echo $data[$c] . "<br />\n";
}
}
fclose($handle);
}
?>
First, try to avoid Excel format in favor of CSV. It is much faster and simpler.
Also, you can use PHPExcel library.
you should use PHPExcel
http://phpexcel.codeplex.com/
you can use following examples
http://phpexcel.codeplex.com/wikipage?title=Examples
you can also have a look at this link
https://code.google.com/p/php-excel-reader/wiki/Documentation

Using fseek to start reading a CSV after a certain number of lines

I am using the current code to read a csv file and add it to an array:
echo "starting CSV import<br>";
$current_row = 1;
$handle = fopen($csv, "r");
while ( ($data = fgetcsv($handle, 10000, ",") ) !== FALSE )
{
$number_of_fields = count($data);
if ($current_row == 1) {
//Header line
for ($c=0; $c < $number_of_fields; $c++)
{
$header_array[$c] = $data[$c];
}
} else {
//Data line
for ($c=0; $c < $number_of_fields; $c++)
{
$data_array[$header_array[$c]] = $data[$c];
}
array_push($products, $data_array);
}
$current_row++;
}
fclose($handle);
echo "finished CSV import <br>";
However when using a very large CSV this times out on the server, or has a memory limit error.
I'd like a way to do it in stages, so after the first say 100 lines it will refresh the page, starting at line 101.
I will probably be doing this with a meta refresh and a URL parameter.
I just need to know how to adapt that code above to start at the line I tell it to.
I have looked into fseek() but I'm not sure how to implement this here.
Can you please help?
The timout can be circumvented using
ignore_user_abort(true);
set_time_limit(0);
When experiencing problems with the memory limit, it may be wise to take a step back and look at what you're actually doing with the data you're processing. Are you pushing the data into a database? calculate something off the data but don't need to store the actual data, …
Do you really need to push (array_push($products, $data_array);) the rows into an array (for later processing)? can you instead write to the database directly? or calculate directly? or build an html <table> directly? or whatever the hell you're doing right then an there, within the while() loop, without pushing everything into an array first?
If you're able to chunk the processing, I guess you don't need that array at all. Otherwise you'd have to restore the array for every chunk - not solving the memory issue one bit.
If you can manage to change your processing algorithm to waste less memory / time, you should seriously consider that over any chunked processing requiring a round-trip to the browser (for so many performance and security reasons…).
Anyways, you can, at any time, identify the current stream offset with ftell() and re-set to that position using fseek(). You'd only need to pass that integer to your next iteration.
Also there is no need for your inner for() loops. This should produce the same results:
<?php
$products = array();
$cols = null;
$first = true;
$handle = fopen($csv, "r");
while (($data = fgetcsv($handle, 10000, ",")) !== false) {
if ($first) {
$cols = $data;
$first = false;
} else {
$products[] = array_combine($cols, $data);
}
}
fclose($handle);
echo "finished CSV import <br>";

filegetcsv causing infinite loop

Trying to use filegetcsv to parse a CSV file and do stuff with it, using the following code found all over the Internet, including the PHP function definition page:
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
print_r($data);
}
fclose($handle);
}
But the code gives me an infinite loop of warnings on the $data = line:
PHP Warning: fgetcsv() expects parameter 1 to be resource, boolean given in...
I know the file I'm opening is a valid file, because if I add a dummy character to the file name I get a different error and no loop.
The file is in a folder with full permissions.
I'm not using a CSV generated by an Excel on Mac (there's a quirky error there)
PHP version 5.1.6, so there should be no problem with the function
I know the file's not too big, or malformed, because I kept shrinking the original file to see if that was a problem and finally just created a custom file in Notepad with nothing more than two lines like:
Value1A,Value1B,Value1C,Value1D
Still looping and giving no data. Here's the full code I'm working with now (using a variable that's greater than the number of lines so I can prove that it would loop infinitely without actually giving my server an infinite loop)
if ($handle = fopen($_SERVER['DOCUMENT_ROOT'].'/tmp/test-csv-file.csv', 'r') !== FALSE) {
while ((($data = fgetcsv($handle, 1000, ',')) !== FALSE) && ($row < 10)) {
print_r($data);
$row++;
}
fclose($handle);
}
So I really have two questions.
1) What could I possibly be overlooking that is causing this loop? I'm half-convinced it's something really "face-palm" simple...
2) Why is the recommended code for this function something that can cause an infinite loop if the file exists but there is some unknown problem? I would have thought the purpose of the !== FALSE and so forth would be to prevent that kind of stuff.
There's no question about what's going on here: the file is not opened successfully. That's why $handle is a bool instead of a resource (var_dump($handle) to confirm this yourself).
fgetcsv then returns null (not false!) because there's an error, and your test doesn't pick this up because you are testing with !== false. As the documentation states:
fgetcsv() returns NULL if an invalid handle is supplied or FALSE on
other errors, including end of file.
I agree that returning null and false for different error conditions is not ideal, and furthermore that it's against the precedent established by lots of other functions, but that's just how it is (and things could be worse). As things stand, you can simply change the test to
while ($data = fgetcsv($handle, 1000, ","))
and it will work correctly in both cases.
Update:
You are the victim of assignment inside an if condition:
if ($handle = fopen($_SERVER['DOCUMENT_ROOT'].'/tmp/test-csv-file.csv', 'r') !== FALSE)
should have been
// wrap the assignment to $handle inside parens!
if (($handle = fopen($_SERVER['DOCUMENT_ROOT'].'/tmp/test-csv-file.csv', 'r')) !== FALSE)
I 'm sure you understand what went wrong here. This is the reason why I choose to never, ever, make assignments inside conditionals. I don't care that it's possible. I don't care that it's shorter. I don't even care that sometimes it's quite less "elegant" to write the loop if the assignment is taken out. If you value your sanity, consider doing the same.
$row = 1;
if (($handle = fopen($_FILES['csv-file']['tmp_name'], "r")) !== FALSE) {
$data = fgetcsv($handle , 1000 , ",");
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
echo "<p> $num fields in line $row: <br /></p>\n";
$row++;
for ($c=0; $c < $num; $c++) {
echo $data[$c] . "<br />\n";
}
}
fclose($handle);
}
Try given Code Snippet once,because as i have noticed you are missing some important things in your code.

Collecting Stackoverflow Q and A's in a text file

I think my method is lame, but I cannot think of a better way to do this.
I use Ultraedit text editor to hold all the stuff I cull out of Stackoverflow for PHP and MySQL in a text file. This is my strict format for each new entry:
#################################################
TITLE: THIS IS MY TITLE (ALL IN CAPS, FOLLOWD BY A DOTTED LINE)
-------------------------------------------------
...probably a question first (if necessary), then another shorter dotted line
-------------------
...answer(s)...
#################################################
So, here is an actual entry:
#################################################
TITLE: READING FIRST 5 FIELDS OF CSV FILE INTO PHP
-------------------------------------------------
(...with fgetcsv...)
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
echo "<p> $num fields in line $row: <br /></p>\n";
// iterate over each column here
for ($c=0; $c < $num; $c++) {
// handle column data here
echo $data[$c] . "<br />\n";
// exit the loop after 3rd column parsed
if ($c == 2) break;
}
++$row;
}
fclose($handle);
-----------------
(...without fgetcsv...)
$lines = file('data.csv');
$linecount = count($lines);
for ($i = 1; $i < $linecount; $i++){
$fields = explode(',', $lines[$i]);
$sno = $fields[0];
$name = $fields[1];
$ph = $fields[2];
$add = $fields[3];
}http://stackoverflow.com/users/login?returnurl=%2fquestions%2fask
#################################################
I can get a list of titles by searching for "TITLE: *", etc. My text file now contains about 15,000 lines. Is there a better way to do this? I have asked StackOverflow before about snippet software, but after a thorough search, there is really nothing out there that fits my needs.
In a way, I'm surprised that there is not a PHP/MySQL application for doing this (collecting snippets). I can't do it because I don't have the knowledge or talent. The snippet collector in my IDE will not suffice.
Thanks!
why not build yourself a little application with a small sql backend (say SQLCE or SQLITE)?
You could build it so that you have the following tables:
Title
Code Snippet
Original Question Url
and then you can relate in the TAGS of the question via another Table to allow better searching/cross referencing.
I have used InfoSelect software for years for this purpose, and have many megabytes of searchable notes and code snippets. It isn't exclusively for code snippets. It's the software equivalent of keeping notes on index cards and being able to arrange them in hierarchies, or do a search on them.
Another similar tool is OneNote which is part of Microsoft Office.
If you remove the condition that your tool should be specifically for tracking code snippets, you may be able to broaden your choices.

Categories