Basic fileread question in PHP / - php

I have a 12 XML files from which I am extracting ONE CSV file, from which - I am extracting column 1 and appending values to a tt.txt file .
NOW, I need to extract the values from this .txt file... everytime data is written to it ...
But the problem is , when I use
$contents = fread ($fd,filesize ($filename));
fclose ($fd);
$delimiter = ',' ;
$splitcontents = explode($delimiter, $contents);
IT reads ONLY from the first value of the file , every time a tt.txt file is appended !
I hope u understand the problem .. What I need is , I want $contents to have only the new data that was appended... instead it reads from the start of the file everytime...
Is there a way to achieve this, or does php fail ?/
This prob is extraction from TXT file- > performing computations- > writing INTO a new txt file . The problem being that I can't read from a middle value to a new value.. PHP always reads from the start of a file.

I think you need to store the last file position.
Call filesize to get current length, read the file, later, check if filesize is different (or maybe you know this some other way, and use fseek to move the cursor in the file, then read from there.
IE:
$previousLength = 0;
// your loop when you're calling your new read function
$length = filesize($filename);
fseek($fd,$previousLength);
$contents = fread($fd,$length - $previousLength);
$previousLength = $length;

It is only reading the first field because PHP does not automatically assume that a newline character (\n) means a new record; you have to handle this, yourself.
Using what you already have, I would do the following:
$contents = fread($fd, filesize($filename));
close($fd);
/* Now, split up $contents by newline, turning this into an array, where each element
* is, in effect, a new line in the CSV file. */
$contents = explode("\n", $contents);
/* Now, explode each element in the array, into itself. */
foreach ($contents as &$c) {
$c = explode(",", $c);
}
In the future, if you want to go line-by-line, as you run the risk of hogging too many resources by reading the entire file in, use fgets().

I'm not great at arrays but it sounds to me like you need an associative array (I'm doing a similar thing with the following code.
$lines = explode("\n", $contents);
foreach ($lines as $line) {
$parts = explode(',', $line);
if (count($parts) > 0) {
$posts = array();
$posts[] = array('name' => $parts[3],'email' => $parts[4],'phone' => $parts[5],'link' => $parts[6],'month' => $parts[0],'day' => $parts[1],'year' => $parts[2]); }
foreach ($posts as $post):
$post = array_filter(array_map('trim', $post));

Related

multi-dimensional array possibly

I have two files that I need opened, I'm using php file to read them
$lines = file('/home/program/prog_conf.txt');
foreach ($lines as $line) {
$rows = preg_split('/\s+/', $line);
Followed by:
$lines = file('/home/domain/public_html/base/file2.cfg');
foreach ($lines as $line) {
$rows = preg_split('/=/', $line);
As I work with these two files, I need to pull info from the second one, which I seperated by =, however, I'm not sure this is the best thing to do. I wanted to add data checking from the database. The db details are in the second file like so:
dbname = databasename
dbuser = databaseuser
dbpass = databasepassword
If I echo the $rows[2], I get everything all the information I need on a single line, not on seperate lines. Meaning:
databasename databaseuser databasepassword
How do I split the information up so I can use the entries one by one?
How about:
$lines = file('/home/domain/public_html/base/file2.cfg');
$all_parts = array()
foreach ($lines as $line) {
//explode pulls apart a string based on the first value, so you could change that
//to a '=' if need be
array_merge($all_parts,explode(' ', $line));
}
This would get you all the parts of the file, one at a time, into an array. Which is what I think you wanted.
If not, just explode as needed
Maybe this aproach helps:
First as i see your second file has multiple lines, so what would do is something like this:
Assumin that every key as "db" in common we can do something like this.
$file = fopen("/home/domain/public_html/base/file2.cfg", "rb");
$contents = stream_get_contents($handle); // This function return better performance if the file isn't too large.
fclose($file);
// Assuming this is your return from the file
$contents = 'dbname = databasename dbuser = databaseuser dbpass = databasepassword';
$rows = preg_split('/db+/', $contents); // Splinting keys "db"
$result = array();
foreach($rows as $row){
$temp = preg_replace("/\s+/", '', $row); // Removing extract white spaces
$temp = preg_split("/=/", $temp); // Splinting by "="
$result[] = $temp[1]; // Getting the value only
}
var_dump ($result);
I hope this help you can try this code maybe with little modifications but works.

need to access 3 values in a php array that contains 20, is a 3d array and I need to access the same values 60 times

<?php
// Open the file
$filename = 'pvemail.txt';
$fp = fopen($filename, 'r');
// Add each line to an array
if ($fp) {
$array = explode("\n", fread($fp, filesize($filename)));
}
//print_r ($array);
for ($c = 0; $c < count($array); $c++){
$cell = explode(",", $array[$c]);
print_r ($cell);
echo '<br/>';
}
?>
I am currently working on this code. I have taken a text file generated from a Google report, and managed to explode it into an array, and then I've taken each element of the array and exploded that into another array. However, the problem I'm now having is I only want to retrieve 3 elements of the second exploded array and there are 20 elements to each array.
What would be the best way to go about this, should I use a for or foreach loop? I only need to print $cell[2], $cell[11] and $cell[12]. I have tried using:
echo ($cell[2] + " " + $cell[12] + " " + $cell[11]
($cell[11] and $cell[12] are in this order because 11 is a last name and 12 is a first name and I want the first name first so I've had to put them backwards) but when I run that piece of code it just outputs line breaks and 0's. I'm really just wondering what would be the most effective method of looping through the arrays, and should I do it within the loop that I have already established?
I was thinking that if I were to put it inside my existing for loop I could use an if/else loop, something like:
if($cell = $cell[2]){
echo ($cell[2])
};
but i'm not convinced this will work. Should I define a variable to store $cell[2], [11] and [12] in, and create my if loop based on that, and then I would only need to echo the variable? Is that likely to be effective? Any help would be appreciated, I've looked around on the forum for posts similar to this but I haven't been able to find anything.
20130912,b875c9b154cf7b8d,el#pv-eu.com,ACTIVE,30720,1054180015,,,20100902,‌​20130910,20130904,L,E,,,,20130911,2010-09-02 09:11:37,2013-09-10 23:51:21,2013-09-04 03:06:09,2013-09-11 00:41:24
20130912,66c63753b8188f17,lf#pv-eu.com,ACTIVE,30720,3699701524,,,20110315,201309‌​11,20130911,F,L,,,,19691231,2011-03-15 02:00:31,2013-09-11 00:50:17,2013-09-11 00:52:16,1969-12-31 16:00:00
20130912,bd5ef40689adf9ac,ah#pv-eu.com,ACTIVE,30720,3476851137,,,20110426,201309‌​11,20130910,H,A,,,,20110720,2011-04-26 01:47:56,2013-09-11 16:58:48,2013-09-10 06:20:26,2011-07-20
This is how the text file itself looks, although there is a lot more data. All I'm trying to pull is the email address and name.
Assuming pvemail.txt is a CSV file, does this solve your problem?
$content = file_get_contents('pvemail.txt');
$lines = explode("\n", $content);
header('Content-type: text/plain');
foreach($lines as $line) {
$values = explode(',', $line);
echo $values[2], ' ', $values[12], ' ', $values[11], "\n";
}
Using the 3 sample lines, the above code outputs this:
el#pv-eu.com E L
lf#pv-eu.com L F
ah#pv-eu.com A H

Subtraction between data in file1 and file2 using PHP

Suppose that I have 2 files:
File1.txt
10;30;15;40;12;14;15
23;32;10;50;12;54;60
File2.txt
2;4;5;6;7;8;9
3;6;7;8;9;0;7
I want to subtration between these 2 files. Ex 10 - 2........
PHP code:
$file1 = 'File1.txt';
$file2 = 'File2.txt';
if(file_exists($file1)){
$files = fopen($file1,'r');
while(!feof($files)){
$data = explode(";",fgets($files));
if($title ==""){
$title = $data[0];
}
if(!empty($data[3])){
$cate = $data[3];
$filepmta = fopen($file2,'r');
while(!feof($filepmta)){
$hourData = explode(";",fgets($filepmta));
if(!empty($hourData[3])){
if($title ==""){
$title = $hourData[0];
}
if(!empty($btnHour)){
echo $percentRed = ((int)$data[2] - (int)$hourData[2]);
//it loads page so long time so I don know what's error.
}
}
}
It loads the page is so long time.I don know how to fix this,Anyone know help me please,thanks.
I would recommend just simply opening both files and storing the contents of the file into memory. IE Create 2 simple loops (not nested) which iterates through both files respectively and saves the content to an array.
Then make one more loop after the first two. Iterate through the third loop based on the array size of the first two. (I'm assuming you can assume they are both the same size, but it will be a good idea to add checks to make sure loop 1 and loop 2 produce the same size/length arrays.
Within the 3rd loop iterate through both previously two generated arrays with the same index.
Pseudo Code // even tho I said I'd do pseudo code, I ended up doing it all. :-/
$file_values1 = $file_values2 = $answers = array();
while(!feof($file1)) $file_values1[] = explode(';', fgets($file)); // loop 1
while(!feof($file2)) $file_values2[] = explode(';', fgets($file)); // loop 2
foreach($file_values1 as $key1 => $sub_array) { // loop 3
foreach($sub_array as $key2 => $value) // loop 4; hehe, oh wellz
{
$answers[] = $file_values1[$key1][$key2] = $file_values2[$key1][$key2]
}
}
Basically, the nested loop 4, meh. There ARE faster answers. The 3rd loop can be improved upon, it's O(N^2). I'll leave that for you to optimize. No free lunches. :-)
fgets() doesn't move the file pointer after the last line, so you're staying on the last line, feof() still returns false and you're trapped in an infinite loop.
The common way of doing what you want is:
while (($line = fgets($handle)) !== false) {
echo $line;
}
Have a look at the code example in fgets() documentation, it's quite exhaustive.
You're making this way more complicated than it has to be.
Open your files and read them both in with file(), which will give you an array of lines in each file.
Iterate over both line arrays simultaneously with a MultipleIterator.
Convert each lines' contents to arrays with str_getcsv() and an array_map() trick.
Iterate over each line values with another MultipleIterator.
Compute the subtraction and print it.
That's all it takes! I've implemented the above algorithm below.
$file1 = 'File1.txt';
$file2 = 'File2.txt';
$file1 = file( $file1);
$file2 = file( $file2);
$iter = new MultipleIterator;
$iter->attachIterator( new ArrayIterator( $file1));
$iter->attachIterator( new ArrayIterator( $file2));
foreach( $iter as $element) {
list( $line1, $line2) = array_map( 'str_getcsv', $element, array( ';', ';'));
$val_iter = new MultipleIterator;
$val_iter->attachIterator( new ArrayIterator( $line1));
$val_iter->attachIterator( new ArrayIterator( $line2));
foreach( $val_iter as $value) {
list( $el1, $el2) = $value;
echo ($el1 - $el2); echo ";";
}
echo "\n";
}
You can see from this demo, which statically defines the files as arrays, that this produces:
8;26;10;34;5;6;6;
20;26;3;42;3;54;53;

csv file into array , translation system for a site

I need help to solve this problem:
I have a csv file like this
hello,ciao
goodbye,arrivederci
as you can see I try to create a translation system for a site
now I want this csv file into an array, the resultant array must be the same of $langArray
<?php $langArray = array([it]=>array([hello]=>ciao,[goodbye]=>arrivederci)); ?>
I already have a solution using a Json file to have an array like this, and is most usefull that a csv file and I can use translation system also with javascript. but I want to know the way to do that with a csv file thank you
For reading a CSV file you should use fopen and fgetcsv, or for the short version str_getcsv (needs current PHP or compat library):
$csv = array_map("str_getcsv", file("it.csv"));
Then building the associative map requires a manual loop:
foreach ($csv as $line)
$translate["it"][ $line[0] ] = $line[1];
You could use explode to split your data once for the new line, then once for the comma, and fill an array with it.
<?php
$translations = array();
$data = 'hello,ciao
goodbye,arrivederci';
$words = explode("\n", $data);
foreach($words as $w) {
$parts = explode(',', $w);
$translations[$parts[0]] = $parts[1];
}
print_r($translations);
?>
http://codepad.viper-7.com/gCKoI9
<?php
$languageArray = ARRAY();
$my_csv_it = 'hello,ciao goodbye,arrivederci';
$tmp_array_it = explode(' ', $my_csv_it);
foreach ($tmp_array_it AS $text) {
$pairs = explode(',',$text);
$languageArray['it'][$pairs[0]] = $pairs[1];
}
print_r ($languageArray);
?>

problem with PHP reading CSV files

I'm trying to read data from a.csv file to ouput it on a webpage as text.
It's the first time I'm doing this and I've run into a nasty little problem.
My .csv file(which gets openened by Excel by default), has multiple rows and I read the entire thing as one long string.
like this:
$contents = file_get_contents("files/data.csv");
In this example file I made, there are 2 lines.
Paul Blueberryroad
85 us Flashlight,Bag November 20,
2008, 4:39 pm
Hellen Blueberryroad
85 us lens13mm,Flashlight,Bag,ExtraBatteries November
20, 2008, 16:41:32
But the string read by PHP is this:
Paul;Blueberryroad 85;us;Flashlight,Bag;November 20, 2008, 4:39 pmHellen;Blueberryroad 85;us;lens13mm,Flashlight,Bag,ExtraBatteries;November 20, 2008, 16:41:32
I'm splitting this with:
list($name[], $street[], $country[], $accessories[], $orderdate[]) = split(";",$contents);
What I want is for $name[] to contain "Paul" and "Hellen" as its contents. And the other arrays to receive the values of their respective columns.
Instead I get only Paul and the content of $orderdate[] is
November 20, 2008, 4:39 pmHellen
So all the rows are concatenated. Can someone show me how i can achieve what I need?
EDIT: solution found, just one werid thing remaining:
I've solved it now by using this piece of code:
$fo = fopen("files/users.csv", "rb+");
while(!feof($fo)) {
$contents[] = fgetcsv($fo,0,';');
}
fclose($fo);
For some reason, allthough my CSV file only has 2 rows, it returns 2 arrays and 1 boolean. The first 2 are my data arrays and the boolean is 0.
You are better off using fgetcsv() which is aware of CSV file structure and has designated options for handling CSV files. Alternatively, you can use str_getcsv() on the contents of the file instead.
The file() function reads a file in an array, every line is an entry of the array.
So you can do something like:
$rows = array();
$name = array();
$street = array();
$country = array();
$rows = file("file.csv");
foreach($rows as $r) {
$data = explode(";", $r);
$name[] = $data[0];
$street[] = $data[1];
$country[] = $data[2];
}
I've solved it now by using this piece of code:
$fo = fopen("files/users.csv", "rb+");
while(!feof($fo)) {
$contents[] = fgetcsv($fo,0,';');
}
fclose($fo);
For some reason, allthough my CSV file only has 2 rows, it returns 2 arrays and 1 boolean. The first 2 are my data arrays and the boolean is 0.
The remark about fgetcsv is correct.
I will still answer your question, for educational purpose. First thing, I don't understand the difference between your data (with comas) and the "string read by PHP" (it substitutes some spaces with semi-colon, but not all?).
PS.: I looked at the source code of your message, it looks like an odd mix of TSV (tabs) and CSV (coma).
Beside, if you want to go this way, you need to split first the file in lines, then the lines in fields.
The best way is of course fgetcsv() as pointed out.
$f = fopen ('test.csv', 'r');
while (false !== $data = fgetcsv($f, 0, ';'))
$arr[] = $data;
fclose($f);
But if you have the contents in a variable and want to split it, and str_getcsv is unavailable you can use this:
function str_split_csv($text, $seperator = ';') {
$regex = '#' . preg_quote($seperator) . '|\v#';
preg_match('|^.*$|m', $text, $firstline);
$chunks = substr_count($firstline[0], $seperator) + 1;
$split = array_chunk(preg_split($regex, $text), $chunks);
$c = count($split) - 1;
if (isset($split[$c]) && ((count($split[$c]) < $chunks) || (($chunks == 1) && ($split[$c][0] == ''))))
unset($split[$c]);
return $split;
}

Categories