Splitting array if empty value - php

I am trying to split an array if one of the lines has an empty value. My array is being exported to a csv and has multiple lines of data, if the data is not complete it will be sent to a uncomplete csv and if it is complete it will be sent a complete csv.
This is what my array structure looks like the blank field on the first line is on email (this line should be split out of the array:
array(2) {
[0]=> array(6) {
["Username"]=> string(47) " STARRY NIGHT CINEMA - RISE OF THE GUARDIANS "
["Email"]=> string(0) ""
["Location"]=> string(1) "1"
["Type"]=> int(1)
["Title"]=> string(47) " STARRY NIGHT CINEMA - RISE OF THE GUARDIANS "
["Description"]=> string(491) "the Tooth Fairy"
}
[1]=> array(6) {
["Username"]=> string(26) "Maui Nui Botanical Gardens"
["Email"]=> string(18) "info#mnbg.org"
["Location"]=> string(1) "1"
["Type"]=> int(1)
["Title"]=> string(26) "Maui Nui Botanical Gardens"
["Description"]=> string(50) "Conserving Hawaiian Plants & Cultural Heritage"
}
}
Writing to my csv:
$fp = fopen('entries.csv', 'w');
foreach ($entries as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
if (!copy("http://www.simonstaton.co.uk/entries.csv", "entries.csv")) {
echo ("failed to copy file");
};
I have no idea where to start with this and as to what function I should use so any advice is greatly appreciated.
Simon

To separate the entries by complete or incomplete you can open two files for writing. One to contain each.
// filenames
$fn_complete = 'entries.csv';
$fn_incomplete = 'incomplete_entries.csv';
// file pointers
$fp_complete = fopen($fn_complete, 'w');
$fp_incomplete = fopen($fn_incomplete, 'w');
// write CSVs
foreach ($entries as $fields) {
if (in_array('', $fields))
fputcsv($fp_incomplete, $fields);
else
fputcsv($fp_complete, $fields);
}
fclose($fp_complete);
fclose($fp_incomplete);
if (!copy('http://www.simonstaton.co.uk/' . $fn_complete, $fn_complete)) {
echo ('failed to copy file ' . $fn_complete);
};
if (!copy('http://www.simonstaton.co.uk/' . $fn_incomplete, $fn_incomplete)) {
echo ('failed to copy file ' . $fn_incomplete);
};

You can check if any of the values in your array is empty like this:
in_array('', $array)
so it then you can do a simple if
if(in_array('', $array)) {
//Do whatever you have to do to slip your array. I don't understand exactly what you want the end result to look like .
}

First pack your CSV data into an array using fgetcsv(). Then use a loop to search for "".
Exemplar:
$row = 1;
if (($resource = fopen("example.csv", "r")) !== false) {
while (($data = fgetcsv($resource, 1000, ",")) !== false) {
$num = count($data);
$row++;
for ($c=0; $c < $num; $c++) {
if ($data[$c] == "") {
// operate
}
}
}
fclose($handle);
}
By the way, don't use the split() function. Use preg_split().
http://php.net/manual/en/function.fputcsv.php

Related

PHP Export to CSV is putting all in 1 column

First a disclaimer, I am a noob here. I am trying to output my results into an excel file, however for some reason I can't seem to figure it, all the results are entering into the same column
Here is the function that I am using to convert it to the file:
function createCSVFile($filename,$headings,$data) {
// Set Output Headers
header('Content-Type: text/csv; charset=utf-8');
header("Content-Disposition: attachment; filename={$filename}.csv");
$fp = fopen('php://output', 'w');
$head = array();
foreach ($headings as $heading) {
$head[] = $heading;
}
fputcsv($fp, $head);
$rowData = array();
// Put the data into the csv
foreach ($data as $row) {
foreach ($row as $item) {
$rowData[] = $item;
}
fputcsv($fp, $rowData);
unset($rowData);
}
}
Here is some sample data and the structure of what I am passing:
$filename
$filename = "Staff-list";
$headings
$headings = array("Username","First Name","Last Name","Start Date", "End Date");
$data
$data = getStaffDetails();
Which returns:
array(6) {
[0]=>
array(5) {
[0]=>
string(12) "James21"
[1]=>
string(3) "James"
[2]=>
string(9) "Michael"
[3]=>
string(10) "2016-06-01"
[4]=>
string(10) "0000-00-00"
}
[1]=>
array(5) {
[0]=>
string(14) "thombommom"
[1]=>
string(5) "Thomas"
[2]=>
string(7) "Bomarius"
[3]=>
string(10) "2016-12-01"
[4]=>
string(10) "0000-00-00"
}
}
And here is what it looks like in the ouput:
Update 1:
As per Marks solution below, I tried setting the deliminator in the PHP func to ; like so:
fputcsv($fp, $head,';');
However, now the output just has semi colons instead of commas
One of the reasons I hate windows so much is that with every version, something is different making it harder for devs. Argh.... Anyway, what you need to do is override system setting ("list separator character") with: 'sep=;'.
The first thing you should pass to fputcsv is:
$seperator = "sep=;";
fputcsv($fp, $seperator, ';', ' ');
Then Make your data an array of arrays with the first array being your headings like so:
$data = array(array("One","Two", "Three"), array('1','2','3'),array('1','2','3'),array('1','2','3'));
Just because you said you're a noob I'll give ya the whole function:
function createCSVFile($filename,$data) {
// Set Output Headers
header('Content-Type: text/csv; charset=utf-8');
header("Content-Disposition: attachment; filename={$filename}.csv");
$fp = fopen('php://output', 'w');
// This will override system setting ("list separator character") and Excel will open the file correctly.
$seperator = "sep=;";
fputcsv($fp, $seperator, ';', ' ');
// Get the array initialised.
$rowData = array();
// put the data into the csv
foreach ($data as $row) {
foreach ($row as $item) {
$rowData[] = $item;
}
fputcsv($fp, $rowData);
unset($rowData);
}
}
Keep me posted!

PHP while loop and array

I'm trying to loop through some CSV data and take out the $data[4] item. My eventual goal is to find the average and hopefully use PHP's array_sum. This seems to be working, except that every time I try and create this array, my while loop breaks each value into their own separate arrays ($real), not one array that I can work with. I have tried everything, including working with the arrays outside of the loop, but nothing has worked. Any help would be appreciated!
$symbol=array("XOM","CVX","RDS-A",
"PTR","TOT","SNP","COP",
"IMO","BP","E","STO","EC","SU","MRO");
for($i=0; $i<count($symbol);$i++)
{
$handle = #fopen("http://ichart.yahoo.com/table.csv?s={$symbol[$i]}&a=10&b=12&c=2013&d=10&e=12&f=2013&g=d&ignore=.csv", "r", false, $context);
if ($handle === false)
{
// trigger (big, orange) error
trigger_error("Could not connect to Yahoo!", E_USER_ERROR);
exit;
}
// download title of CSV file and throw away
$data=fgetcsv($handle);
//loop through data
while(($data = fgetcsv($handle)) !==FALSE)
{
$rows++;
$num=count($data);
$real=array($data[4]);
}
var_dump($real);
}
And here's my final output:
array(1) { [0]=> string(9) "92.669998" }
array(1) { [0]=> string(6) "120.00" }
array(1) { [0]=> string(9) "66.290001" }
array(1) { [0]=> string(10) "111.059998" }
array(1) { [0]=> string(5) "58.73" }
array(1) { [0]=> string(9) "82.449997" }
array(1) { [0]=> string(5) "72.82" }
array(1) { [0]=> string(9) "42.740002" }
array(1) { [0]=> string(5) "45.91" }
array(1) { [0]=> string(5) "47.98" }
array(1) { [0]=> string(9) "22.440001" }
array(1) { [0]=> string(5) "41.93" }
array(1) { [0]=> string(5) "34.82" }
array(1) { [0]=> string(5) "35.82" }
Not sure what $context is, but try this...
$symbol=array("XOM","CVX","RDS-A","PTR","TOT","SNP","COP","IMO","BP","E","STO","EC","SU","MRO");
$datas = array();
for($i=0; $i<count($symbol);$i++){
$handle = #fopen("http://ichart.yahoo.com/table.csv?s={$symbol[$i]}&a=10&b=12&c=2013&d=10&e=12&f=2013&g=d&ignore=.csv", "r", false, $context);
if ($handle === false){
// trigger (big, orange) error
trigger_error("Could not connect to Yahoo!", E_USER_ERROR);
exit;
}
// download title of CSV file and throw away
$data=fgetcsv($handle);
//loop through data
while(($data = fgetcsv($handle)) !==FALSE){
$rows++;
$datas[] = $data[4];
}
}
print_r($datas);

Upload multiple images giving a unique name based on the previous uploaded value

I'm trying to upload multiple images but give it a unique name based on the previous uploaded value.
Problem : If I add a Sleep(3), The sequence will be right but some images still wont be uploaded maybe because it's sleeping?
If i dont sleep , the value will be 1 then 2 2 2 2 2 2 2 2 3
How do I wait for move_uploaded_file to complete before moving on? it doesnt seem to be doing that.
$files = $_FILES['fileselect'];
foreach ($files as $file) {
//Check Database for Latest File "Name" Count
//TODO , verify Orderby
$node = DB::table('product_options')->where('product_id', Input::get('productID'))->orderby('created_at','desc')->first();
if($node){
//If extra image already exist
$keywords = preg_split("/[_]+/", $node->image);
var_dump($keywords);
$fn = Input::get('productID').'_'.($keywords[1]+1).'_extra'.'.jpg';
$returnID = Option::create(array('image'=>'productImg/'.$fn,'product_id' =>Input::get('productID')));
move_uploaded_file($file[0],'productImg/' . $fn);
echo("<p>File $fn uploaded.</p>");
}else{
$fn = Input::get('productID').'_1_extra'.'.jpg';
$returnID = Option::create(array('image'=>'productImg/'.$fn,'product_id' =>Input::get('productID')));
move_uploaded_file($file[0],'productImg/' . $fn);
echo ("<p>File $fn uploaded.</p>");
}
}
Without Sleep, Echo would return this
File 52_1_extra.jpg uploaded.
array(3) { [0]=> string(13) "productImg/52" [1]=> string(1) "1" [2]=> string(9) "extra.jpg" }
File 52_2_extra.jpg uploaded.
array(3) { [0]=> string(13) "productImg/52" [1]=> string(1) "1" [2]=> string(9) "extra.jpg" }
File 52_2_extra.jpg uploaded.
array(3) { [0]=> string(13) "productImg/52" [1]=> string(1) "1" [2]=> string(9) "extra.jpg" }
File 52_2_extra.jpg uploaded.
array(3) { [0]=> string(13) "productImg/52" [1]=> string(1) "1" [2]=> string(9) "extra.jpg" }
File 52_2_extra.jpg uploaded.
With Sleep Echo would return it in Sequence (Correct) BUT MISSING IMAGES (Half of it) inside my folder.
I think that you must control with a variable the increment, something like this:
$files = $_FILES['fileselect'];
$i = 0;
foreach ($files as $file) {
//Check Database for Latest File "Name" Count
//TODO , verify Orderby
$node = DB::table('product_options')->where('product_id', Input::get('productID'))->orderby('created_at','desc')->first();
if($node){
//If extra image already exist
$keywords = preg_split("/[_]+/", $node->image);
var_dump($keywords);
if($i == 0) {
$i += $keywords[1] + 1;
}
else {
++$i;
}
$fn = Input::get('productID').'_'. $i .'_extra'.'.jpg';
$returnID = Option::create(array('image'=>'productImg/'.$fn,'product_id' =>Input::get('productID')));
move_uploaded_file($file[0],'productImg/' . $fn);
echo("<p>File $fn uploaded.</p>");
}else{
$fn = Input::get('productID').'_1_extra'.'.jpg';
$returnID = Option::create(array('image'=>'productImg/'.$fn,'product_id' =>Input::get('productID')));
move_uploaded_file($file[0],'productImg/' . $fn);
echo ("<p>File $fn uploaded.</p>");
}
}

csv to array overide data

I want to make a array out of a csv file with the header as key. But when I insert the script into a database than it overrides the previous row of the csv file and only the last value gets stored in the database.
I think its because the array has a default value of 5. How can I change the value so that it creates a new value?
This is the script
<?php
// open the file.
if (($handle = fopen("test2.csv", "r")) !== FALSE) {
// read the column headers in an array.
$head = fgetcsv($handle, 1000, ";");
// read the actual data.
while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
// create a new array with the elements in $head as keys
// and elements in array $data as values.
$combined = array_combine($head,$data);
// print.
var_dump($combined);
}
// done using the file..close it,
}
?>
this is the output
array(5) { ["name"]=> string(5) "Harry" ["description"]=> string(4) "test" ["offer_url"]=> string(42) "demo.com/admin/offers/add" ["preview_url"]=> string(42) "demo.com/admin/offers/add" ["expiration_date"]=> string(9) "23-8-2013" }
array(5) { ["name"]=> string(5) "Gerry" ["description"]=> string(4) "test" ["offer_url"]=> string(42) "demo.com/admin/offers/add" ["preview_url"]=> string(42) "demo.com/admin/offers/add" ["expiration_date"]=> string(9) "23-8-2013" }
array(5) { ["name"]=> string(5) "merry" ["description"]=> string(4) "test" ["offer_url"]=> string(42) "demo.com/admin/offers/add" ["preview_url"]=> string(42) "demo.com/admin/offers/add" ["expiration_date"]=> string(9) "23-8-2013" }
you must go through multidimensional array and add additional index to the combined param like this - combined[]=...:
// create a new array with the elements in $head as keys
// and elements in array $data as values.
$combined[] = array_combine($head,$data);

First element in a while loop?

I am writing a PHP script that imports a csv and inserts into a table but i need to get the first row so i can have the field names..here is my csv
id artist song
11 NewBee great stuff
10 anotherNewbee even better
6 NewArtist New song
As you can see the first row is the name of the fields that i need. here is my loop
$handle = fopen('csvs/'.$_FILES["csv"]["name"], 'r');
while (($data = fgetcsv($handle, 1000, ',')) !== FALSE) {
print_r($data);
//do something with it but i need the first time around
array(3) { [0]=> string(2) "id" [1]=> string(6) "artist" [2]=> string(4) "song" }
array(3) { [0]=> string(2) "11" [1]=> string(6) "NewBee" [2]=> string(1) "great stuff" }
array(3) { [0]=> string(2) "10" [1]=> string(13) "anotherNewbee" [2]=> string(1) "even better"}
How do i get the first and put them in variables and continue the loop of the data using those fields in an insert statement
Would this work for you?
$row = 1;
while (($data = fgetcsv($handle, 1000, ',')) !== FALSE) {
if($row == 1) {
// do something
}
else
{
// do something
}
++$row;
}
Prior to your while block, just run the fgetcsv function a single time and store the field headings.
Either deepsat's or mattmoon9's methods will work fine. Here's what mattmoon9's answer would look like structured in code (also based on my comment on the answer):
$handle = fopen('csvs/'.$_FILES["csv"]["name"], 'r');
if (($columns = fgetcsv($handle, 1000, ',')) !== false) {
while (($data = fgetcsv($handle, 1000, ',')) !== false) {
// Process data
}
// Insert into database using $columns as table column names
} else {
// The file couldn't be parsed as CSV
}

Categories