I have this script that I did, it basically grabs all the files in my "logs" folder and merge them all in one array file, my only problem is that, sometimes the script breaks if there is blank line or empty line! how can I tell it to automatically skip blank empty lines and go to next? blank lines are not necessarily at the top or bottom! could be in the middle of the csv file
<?php
$csv = array();
$files = glob('../logs/*.*');
$out = fopen("newfile.txt", "w");
foreach($files as $file){
$in = fopen($file, "r");
while (($result = fgetcsv($in)) !== false)
{
$csv[] = $result;
}
fclose($in);
fclose($out);
}
print json_encode(array('aaData' => $csv ));
?>
As you can read in the documentation for fgetcsv():
A blank line in a CSV file will be returned as an array comprising a single null field, and will not be treated as an error.
Checking for that before adding it to your data array should be sufficient:
while (($result = fgetcsv($in)) !== false) {
if (array(null) !== $result) { // ignore blank lines
$csv[] = $result;
}
}
This works 100% tested, simplest way. The explanation is that blank lines make fgetcsv return a non-empty array with just a null element inside.
if ($result[0] == NULL)
continue;
In short
$csv = array_map('str_getcsv', file($file_path, FILE_SKIP_EMPTY_LINES|FILE_IGNORE_NEW_LINES));
Explanation
file reads the content of the file into an array. The FILE_SKIP_EMPTY_LINES will skip the empty lines in the file.
array_map will apply the function str_getcsv on each element of the array. str_getcsv will parse the string input for fields in
csv format and return an array containing the fields.
Read more about str_getcsv
Read more about file
Read more about array_map
Related
I am making a redeem key page for educational purposes with PHP just to see what it is capable of. I am storing the keys in a txt file as such:
key1
key2
And so on.
I have tried the following to loop through the txt file, insert the values into and array and work off of there. Here is what I have:
$gkey = $_GET["key"];
$file = fopen("./generatedkeys.txt", "a");
$generatedk = array();
// generate table from data in txt file
while(! feof($file)) {
$generatedk[] = fgets($file);
}
foreach ($generatedk as $key){
if ($key == hash("sha256", $gkey)){
// Removing of key from data in txt file
$contents = file_get_contents($file);
$contents = str_replace($key, '', $contents);
file_put_contents($file, $contents);
fclose($file);
$accfile = fopen("./accs.txt", "a");
fwrite($accfile, hash("sha256", $key).",".hash("sha256", $hwid)."\n");
break;
}
}
The code above however doesn't seem to be working. The key is simply not detected and not removed from generatedkeys.txt. (Not sure if there is any errors since I cannot see any).
Is there any obvious mistakes?
Any help is appreciated. Thank you.
I think this should make the process simpler, using file to read the whole file in one go into an array and then using array_search() to find if the key exists (it returns false if not found, so !== false).
Then if found, it just appends the used key to the other file, unsets the array entry for the key and overwrites the original file...
$gkey = $_GET["key"];
$generatedk = file("./generatedkeys.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if ( ($entry = array_search(hash("sha256", $gkey), $generatedk)) !== false ) {
// Add key used, with whatever content you want
file_put_contents("./accs.txt", $gkey.PHP_EOL, FILE_APPEND);
// Remove found key from list in input file
unset($generatedk[$entry]);
// Overwrite input file with adjusted array
file_put_contents("./generatedkeys.txt", implode(PHP_EOL, $generatedk));
}
Your code will make some empty lines when erases key from file.
And you passed return value of fopen() as a parameter of file_get_contents(). the return value is resource on file, but file_get_contents() needs string(file path).
You can check following.
$gkey = $_GET["key"];
$file_path="./generatedkeys.txt";
$file = fopen($file_path, "a");
$generatedk = array();
// generate table from data in txt file
while(! feof($file)) {
$generatedk[] = fgets($file);
}
fclose($file);
for($i=0; $i<count($generatedk); $i++){
$key=$generatedk[$i];
if ($key == hash("sha256", $gkey)){
// Removing of key from data in txt file
array_splice($generatedk, $i, 1);
file_put_contents($file_path, implode("\n", $generatedk));
$accfile = fopen("./accs.txt", "a");
fwrite($accfile, hash("sha256", $key).",".hash("sha256", $hwid)."\n");
fclose($accfile);
break;
}
}
I hope it will be working well.
Thanks.
The numbers in my file are 5X5:
13456
23789
14789
09678
45678
I'm trying to put it into this form
array[0]{13456}
array[1]{23789}
array[2]{14789}
array[3]{09678}
array[4]{45678}
My code is:
$fileName = $_FILES['file']['tmp_name'];
//Throw an error message if the file could not be open
$file = fopen($fileName,"r") or exit("Unable to open file!");
while ($line = fgets($file)) {
$digits .= trim($line);
$members = explode("\n", str_replace(array("\r\n","\n\r","\r"),"\n",$digits));
echo $members;
The output I'm getting is this:
ArrayArrayArrayArrayArray
fgets gets a line from the file pointer, so theoretically there should be no "\r" or "\n" characters in $line. explode will still work, even if the delimiter is not found. You'll just end up with an array with one item, the entire string. You can't echo an array, though. (That's why you're seeing Array for each line; it's the best PHP can do when you use echo on an array.)
If I were you, I would rather just use file() instead.
$members = array_map('trim', file($fileName, FILE_IGNORE_NEW_LINES));
With the example file you showed, this should result in
$members = ['13456', '23789', '14789', '09678', '45678'];
You can simply put the lines into an array and use print_r instead of echo to print that array
while ($line = fgets($file)) {
$members[] = $line;
}
print_r($members);
It should depend on the file that you are dealing with.
FileType:
text -> fgets($file)
CSV -> fgetcsv($file)
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);
I have a CSV file which is generated dynamically. I want to remove the first line of CSV and then save it again.
I have googled and was able to get first line of csv but the part of writing it again after removing is where I am stuck.
Here is example
line1,data1
line2,data2
line3,data3
What I want to acheive
line2,data2
line3,data3
That is first line removed and file saved again
Here is my code
$file = fopen('words.csv', 'r');
$data = fgetcsv($file,10000,",");
$data = array_shift($data);
$file = fopen('words.csv', 'w');
fputcsv($file,$data,",");
fclose($file);
I get this:
! ) Warning: fputcsv() expects parameter 2 to be array, string given in C:\wamp\www\scrape\test.php on line 7
And output file is empty.
Ahmar
// Read the file
$file = fopen('words.csv', 'r');
// Iterate over it to get every line
while (($line = fgetcsv($file)) !== FALSE) {
// Store every line in an array
$data[] = $line;
}
fclose($file);
// Remove the first element from the stored array / first line of file being read
array_shift($data);
// Open file for writing
$file = fopen('words.csv', 'w');
// Write remaining lines to file
foreach ($data as $fields) {
fputcsv($file, $fields);
}
fclose($file);
You have some errors in your code. The first one is that fgetcsv function only gets one line so if you want to extract all the lines you need a loop. The same happens with fputcsv function.
The other one is that array_shift function returns the shifted value so you are assigning to $data the string you don't need.
So, I think your code must be like:
$file = fopen('words.csv', 'r');
$data=array();
while (($data_tmp = fgetcsv($file, 1000, ",")) !== FALSE) {
$data[] = $data_tmp;
}
fclose($file);
array_shift($data);
$file = fopen('words.csv', 'w');
foreach($data as $d){
fputcsv($file,$d);
}
fclose($file);
I have a big CSV file. I want to separate this file into separate files based on the value in one of the fields.
This is what I have done. Using fgetcsv I convert the CSV into an array, and using in_array, I check the content and display if it contains the string within the array.
I will be getting the comparison string from another text file iteratively to check whether it is contained in the csv. In this case I have specified it as "Testing".
Below is the code:
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
if(in_array("Testing", $data))
{
var_dump($data);
}
}
fclose($handle);
}
This is working, but now I am stuck. How do I write $data into another CSV file? Or is there a better way to do this?
It's actually pretty simple and if the string just has to be on the line, you don't even need fgetcsv. Just
$srcFile = new SplFileObject('test.csv');
$destFile = new SplFileObject('new.csv', 'w+');
foreach ($srcFile as $line) {
if (strpos($line, 'testing') !== FALSE) {
$destFile->fwrite($line);
}
}
This will create two file objects. The first one holding the content of your source file. The second one creating an all new file for the lines containing your search string. We then just iterate over each line and check if the search string exists. If so, we write it to destination file.
The source file will not be touched this way. If you want to have one file with the search string and one file without, just create a third SplFileObject and add an else block to the if writing the line to that one then. In the end, delete the source csv file.
You have to do some tricky thing I am providing some basic idea for doing so, here is the code:
//opening file
if ($fp = fopen('log.csv', 'r')) {
$line_number = 0;
//loop for Reading file as line by line csv file
while ($line = fgetcsv($fp, 0, ';')) {
if ($line_number++ == 0) {
continue;
}
//array data string to make possible to provide file name
//according to column name required
$date = explode(' ', $line[0]);
//Change the column name according to your needs
$file = $date[0] .'.log';
file_put_contents(
//change the folder name according to your needs
'monthly/'. $file,
//printing data in appended file
implode(';', $line) ."\n",
FILE_APPEND
);
}
//closing file
fclose($fp);
}
It reads CSV file line by line, extracts date part from the first column and creates new file and appends data to it.
Note:
folder "monthly" must be writable