Unable to insert data in CSV file PHP - php

I am in process of inserting data in the desired CSV file from another CSV file.
CSV file is creating fine with out any problem but its is not insert array data in file.
It only inserts header on the first row.
Below is code I am trying:
date_default_timezone_set('America/New_York');
set_time_limit(0);
ini_set("memory_limit", -1);
$realPath = realpath( dirname(__FILE__) );
$path = $realPath.'/3pltracking/';
$files = scandir($path);
$FilePath = $path.$files[2];
$result = array();
$date = date('m-d-Y_his');
if (file_exists($FilePath))
{
if (($handle = fopen($FilePath, "r")) !== FALSE)
{
$i=0;
while (($data = fgetcsv($handle, 10000, ",")) !== FALSE)
{
$i++;
if($i==1) continue;
//$list = array('$data[2],$data[25],$data[4],$data[30],$data[41],$data[27]');
echo $data[2].",".$data[25].",".$data[4].",".$data[30].",".$data[41].",".$data[27];
echo "<br>";
$list = array($data[2].",".$data[25].",".$data[4].",".$data[30].",".$data[41].",".$data[27]);
// the problem is here I believe as it is empty array if I check it outside while loop
}
fclose($handle);
$headers = array('ReferenceNumber', 'TotalCartons', 'ShipCarrier', 'TrackingNum', 'FreightPP', 'TotalWeight');
$fp = fopen($realPath.'\3pltracking\TrackingFiles\Tracking_File_'.$date.'.csv', 'w');
fputcsv($fp, $headers);
foreach ($list as $line) {
$val = explode(",", $line);
fputcsv($fp, $val);
}
fclose($fp);
} else {
$body = "File Not Found";
}
}
Here is my CSV file data:
TransactionNumber,CustomerName,ReferenceNumber,PurchaseOrderNumber,ShipCarrier,ShipService,ShipBilling,ShipAccount,EarliestShipDate,CancelDate,Notes,ShipToName,ShipToCompany,ShipToAddress1,ShipToAddress2,ShipToCity,ShipToState,ShipToZip,ShipToCountry,ShipToPhone,ShipToFax,ShipToEmail,ShipToCustomerName,ShipToDeptNumber,ShipToVendorID,TotalCartons,TotalPallets,TotalWeight,TotalVolume,BOLNum,TrackingNum,TrailerNum,SealNum,ShipDate,ItemNumber,ItemQuantityOrdered,ItemQuantityShipped,ItemLength,ItemWidth,ItemHeight,ItemWeight,FreightPP,WarehouseID,LotNumber,SerialNumber,ExpirationDate,Supplier,Cost,FulfillInvShippingAndHandling,FulfillInvTax,FulfillInvDiscountCode,FulfillInvDiscountAmount,FulfillInvGiftMessage,SoldToName,SoldToCompany,SoldToAddress1,SoldToAddress2,SoldToCity,SoldToState,SoldToZip,SoldToCountry,SoldToPhone,SoldToFax,SoldToEmail,SoldToCustomerID,SoldToDeptNumber,FulfillInvSalePrice,FulfillInvDiscountPct,FulfillInvDiscountAmt
242328,PARADIGM TRENDS,123810,40-402849,CUSTOMER PICK UP,LTL,FreightCollect,,,,,HG BUYING- JEFFERSON DC 884,HG BUYING- JEFFERSON DC 884,125 LOGISTICS CENTER PKWY,,JEFFERSON,AL,30549,US,,,,,,,30,0,30,0.0174,,,,,,DOV3S,64,64,4,1,1,4,0,1,,,,,,0,0,,0,,,,,,,,,,,,,,,0,0,0
33,d,123810,40-402849,CUSTOMER PICK UP,LTL,FreightCollect,,,,,HG BUYING- JEFFERSON DC 884,HG BUYING- JEFFERSON DC 884,125 LOGISTICS CENTER PKWY,,JEFFERSON,AL,30549,US,,,,,,,30,0,30,0.0174,,,,,,DOV3S,64,64,4,1,1,4,0,1,,,,,,0,0,,0,,,,,,,,,,,,,,,0,0,0
44,PARAdgdfDIGM TRENDS,123810,40-402849,CUSTOMER PICK UP,LTL,FreightCollect,,,,,HG BUYING- JEFFERSON DC 884,HG BUYING- JEFFERSON DC 884,125 LOGISTICS CENTER PKWY,,JEFFERSON,AL,30549,US,,,,,,,30,0,30,0.0174,,,,,,DOV3S,64,64,4,1,1,4,0,1,,,,,,0,0,,0,,,,,,,,,,,,,,,0,0,0
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,BY3M,176,176,11,1,1,11,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0

There are so many ways of going about this... including str_getcsv($csvData). However here we'd go for something old-school & a bit twisted;-). We would create a Function that uses Regex and a Looping Construct to build-up the relevant CSV Data Structure. The Function below illustrates how. Also note that although we mentioned that this is a somewhat twisted, old-school approach: don't be fooled... because it does its thing still ;-).
<?php
$csvSourceFile = __DIR__ . "/1.csv";
$csvPreferredColumns = array('ReferenceNumber', 'TotalCartons', 'ShipCarrier', 'TrackingNum', 'FreightPP', 'TotalWeight');
$newCsvStrut = processCSVData($csvSourceFile, $csvPreferredColumns, __DIR__ . "/test.csv");
/**
* #param $csvSource // PATH TO THE MAIN CSV FILE
* #param array $csvPreferredColumns // ARRAY OF HEADER COLUMN-NAMES TO BE EXTRACTED FROM MAIN CSV
* #param null $newCSVFileName // NAME OF THE NEW CSV FILE TO BE CREATED.
* #return string
*/
function processCSVData($csvSource, array $csvPreferredColumns, $newCSVFileName=null){
// GET THE CONTENTS OF THE CSV FILE & STORE IT IN A VARIABLE
$csvData = file_get_contents($csvSource);
// SPLIT THE CONTENTS OF THE CSV FILE LINE BY LINE: THAT IS; AT THE END OF EACH LINE
// THUS CONVERTING THE DATA TO AN ARRAY...
$arrCsvLines = preg_split("#\n#", $csvData);
//FILTER OUT UNWANTED EMPTY VALUES FROM THE ARRAY
$arrCsvLines = array_filter($arrCsvLines);
// CREATE SOME VARIABLES TO BE USED WITHIN THE LOOP...
$strDataFinal = "";
$arrDataMain = $arrDataFinal = array();
// IF THERE IS MORE THAN ONE LINE IN THE ARRAY WE CREATED ABOVE,
// THEN CONTINUE PROCESSING THE DATA...
if($arrCsvLines && count($arrCsvLines)>0){
// SINCE THE HEADER IS ALWAYS THE FIRST LINE IN THE CHAIN,
// WE EXPLICITLY EXTRACT IT AND STORE IT IN A VARIABLE FOR LATER USE
$arrCsvHeaders = preg_split("#\,([\s\t]+)?#", $arrCsvLines[0]);
// NOW WE LOOP THROUGH ALL THE LINES WE CREATED BY SPLITTING THE CONTENTS
// OF THE CSV FILE AT THE END-OF-LINE BOUNDARY
foreach($arrCsvLines as $key=>$arrCsvLine){
// WE DON'T WANT ANYTHING AT INDEX "0" SINCE IT IS THE HEADER
// AND WE ALREADY DEALT WITH IT ABOVE....
// SO IF THE INDEX $key IS NOT 0, WE CAN CONTINUE PROCESSING
if($key != 0){
$arrDataTemp = array();
$arrTempCsvData = preg_split("#\,([\s\t]+)?#", $arrCsvLine);
foreach($arrTempCsvData as $iKey=>$sData){
$arrDataTemp[$arrCsvHeaders[$iKey]] = $sData;
}
$arrDataMain[] = $arrDataTemp;
}
}
foreach($arrDataMain as $iKey=>$subData){
$arrTempFinal = array();
foreach($subData as $key=>$data){
if(in_array($key, $csvPreferredColumns)){
$arrTempFinal[$key] = $data;
}
}
$arrDataFinal[] = implode(",\t", $arrTempFinal);
}
$arrDataFinal = array_merge( array(implode(",\t", $csvPreferredColumns)), $arrDataFinal);
$strDataFinal = implode("\n", $arrDataFinal);
if($newCSVFileName){
file_put_contents($newCSVFileName, $strDataFinal);
}
}
return $strDataFinal;
}
var_dump($newCsvStrut);
// PRODUCES SOMETHING SIMILAR TO THE LINES BELOW:
string 'ReferenceNumber, TotalCartons, ShipCarrier, TrackingNum, FreightPP, TotalWeight
123810, CUSTOMER PICK UP, 30, 30, , 0
123810, CUSTOMER PICK UP, 30, 30, , 0
123810, CUSTOMER PICK UP, 30, 30, , 0
, , , , , ' (length=204)

Related

How to extract specific text from a text file in php?

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);

Convert a CSV file to force encapsilation

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!!
?>

PHP Formatting A Column (dollar sign) In csv Upload Script

I have a script that uploads a csv file with 3 columns (phone, name, amount). The script removes any formatting on the phone, ie; ()- and puts the file on the server. The amount column in the file shows the amount like 125.00 and I need it to show $125.00. Any help would be much appreciated.
$file_destination = '/****/****/****/***/' . $file_name_new;
$contents = file_get_contents($file_tmp);
$contents = str_replace("(","",$contents);
$contents = str_replace(")","",$contents);
$contents = str_replace("-","",$contents);
file_put_contents($file_tmp, $contents);
if(move_uploaded_file($file_tmp, $file_destination)) {
Whether you want to reformat the values strictly for output or store the new formatted data in your CSV file, it's probably going to be more effective to use fgetcsv and fputcsv. Those functions are designed for properly reading in and writing out CSV formatted files.
Example
$rows = [];
if (($handle = fopen($file_tmp, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
list($phone, $name, $amount) = $data;
$phone = str_replace(['(',')','-'], '', $phone);
$amount = sprintf('$%.2f', $amount);
// you can build a new array with the updated values
$rows[] = [$phone, $name, $amount];
// or output directly
echo "$phone | $name | $amount";
}
fclose($handle);
}
// if you want to save the destination with the updated information...
$fp = fopen($file_destination, 'w');
foreach ($rows as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);

File manupulation search and replace csv php

I need a script that is finding and then replacing a sertain line in a CSV like file.
The file looks like this:
18:110327,98414,127500,114185,121701,89379,89385,89382,92223,89388,89366,89362,89372,89369
21:82297,79292,89359,89382,83486,99100
98:110327,98414,127500,114185,121701
24:82297,79292,89359,89382,83486,99100
Now i need to change the line 21.
This is wat i got so far.
The first 2 to 4 digits folowed by : ar a catergory number. Every number after this(followed by a ,) is a id of a page.
I acces te id's i want (i.e. 82297 and so on) from database.
//test 2
$sQry = "SELECT * FROM artikelen WHERE adviesprijs <>''";
$rQuery = mysql_query ($sQry);
if ( $rQuery === false )
{
echo mysql_error ();
exit ;
}
$aResult = array ();
while ( $r = mysql_fetch_assoc ($rQuery) )
{
$aResult[] = $r['artikelid'];
}
$replace_val_dirty = join(",",$aResult);
$replace_val= "21:".$replace_val_dirty;
// file location
$file='../../data/articles/index.lst';
// read the file index.lst
$file1 = file_get_contents($file);
//strip eerde artikel id van index.lst
$file3='../../data/articles/index_grp21.lst';
$file3_contents = file_get_contents($file3);
$file2 = str_replace($file3_contents, $replace_val, $file1);
if (file_exists($file)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";
}
if (file_exists($file3)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";
}
// replace the data
$file_val = $file2;
// write the file
file_put_contents($file, $file_val);
//write index_grp98.lst
file_put_contents($file3, $replace_val);
mail('info#', 'Aanbieding catergorie geupdate', 'Aanbieding catergorie geupdate');
Can anyone point me in the right direction to do this?
Any help would be appreciated.
You need to open the original file and go through each line. When you find the line to be changed, change that line.
As you can not edit the file while you do that, you write a temporary file while doing this, so you copy over line-by-line and in case the line needs a change, you change that line.
When you're done with the whole file, you copy over the temporary file to the original file.
Example Code:
$path = 'file';
$category = 21;
$articles = [111182297, 79292, 89359, 89382, 83486, 99100];
$prefix = $category . ':';
$prefixLen = strlen($prefix);
$newLine = $prefix . implode(',', $articles);
This part is just setting up the basics: The category, the IDs of the articles and then building the related strings.
Now opening the file to change the line in:
$file = new SplFileObject($path, 'r+');
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
$file->flock(LOCK_EX);
The file is locked so that no other process can edit the file while it gets changed. Next to that file, the temporary file is needed, too:
$temp = new SplTempFileObject(4096);
After setting up the two files, let's go over each line in $file and compare if it needs to be replaced:
foreach ($file as $line) {
$isCategoryLine = substr($line, 0, $prefixLen) === $prefix;
if ($isCategoryLine) {
$line = $newLine;
}
$temp->fwrite($line."\n");
}
Now the $temporary file contains already the changed line. Take note that I used UNIX type of EOF (End Of Line) character (\n), depending on your concrete file-type this may vary.
So now, the temporary file needs to be copied over to the original file. Let's rewind the file, truncate it and then write all lines again:
$file->seek(0);
$file->ftruncate(0);
foreach ($temp as $line) {
$file->fwrite($line);
}
And finally you need to lift the lock:
$file->flock(LOCK_UN);
And that's it, in $file, the line has been replaced.
Example at once:
$path = 'file';
$category = 21;
$articles = [111182297, 79292, 89359, 89382, 83486, 99100];
$prefix = $category . ':';
$prefixLen = strlen($prefix);
$newLine = $prefix . implode(',', $articles);
$file = new SplFileObject($path, 'r+');
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
$file->flock(LOCK_EX);
$temp = new SplTempFileObject(4096);
foreach ($file as $line) {
$isCategoryLine = substr($line, 0, $prefixLen) === $prefix;
if ($isCategoryLine) {
$line = $newLine;
}
$temp->fwrite($line."\n");
}
$file->seek(0);
$file->ftruncate(0);
foreach ($temp as $line) {
$file->fwrite($line);
}
$file->flock(LOCK_UN);
Should work with PHP 5.2 and above, I use PHP 5.4 array syntax, you can replace [111182297, ...] with array(111182297, ...) in case you're using PHP 5.2 / 5.3.

Parse CSV file of links to php array, feed these links to simplehtmldom

I have a php code that will read and parse csv files into a multiline array, what i need to do next is to take this array and let simplehtmldom fire off a crawler to return some company stocks info.
The php code for the CSV parser is
$arrCSV = array();
// Opening up the CSV file
if (($handle = fopen("NASDAQ.csv", "r")) !==FALSE) {
// Set the parent array key to 0
$key = 0;
// While there is data available loop through unlimited times (0) using separator (,)
while (($data = fgetcsv($handle, 0, ",")) !==FALSE) {
// Count the total keys in each row $data is the variable for each line of the array
$c = count($data);
//Populate the array
for ($x=0;$x<$c;$x++) {
$arrCSV[$key][$x] = $data[$x];
}
$key++;
} // end while
// Close the CSV file
fclose($handle);
} // end if
echo "<pre>";
echo print_r($arrCSV);
echo "</pre>";
This works great and parses the array line by line, $data being the variable for each line. What i need to do now is to get this to be read via simplehtmldom, which is where it breaks down, im looking at using this code or something very similar, im pretty inexperienced at this but guess i would be needing a foreach statement somewhere along the line.
This is the simplehtmldom code
$html = file_get_html($data);
$html->find('div[class="detailsDataContainerLt"]');
$tickerdetails = ("$es[0]");
$FileHandle2 = fopen($data, 'w') or die("can't open file");
fwrite($FileHandle2, $tickerdetails);
fclose($FileHandle2);
fclose($handle);
So my qyestion is how can i get them both working together, i jave checked out simplehtmldom manual page several times and find it a littlebit vague in this area, the simplehtmldom code above is what i use in another function but by direclty linking so i know that it works.
regards
Martin
Your loop could be reduced to (yes, it's the same):
while ($data = fgetcsv($handle, 0, ',')) {
$arrCSV[] = $data;
}
Using SimpleXML instead of SimpleDom (Since it's standard PHP):
foreach ($arrCSV as $row) {
$xml = simplexml_load_file($row[0]); // Change 0 to the index of the url
$result = $xml->xpath('//div[contains(concat(" ", #class, " "), " detailsDataContainerLt")]');
if ($result->length > 0) {
$file = fopen($row[1], '2'); // Change 1 to the filename you want to write to
if ($file) {
fwrite($file, (string) $result->item(0));
fclose($file);
}
}
}
that should do it if I understood correctly...

Categories