#!/usr/bin/php
<?php
define("KPA_PEOPLE","/devel/pic/snk_db2/KPA-migration/Keywords/gettingTheKeywordsAndFiles/KPA_People.txt");
$hndl_kpa_people=fopen(KPA_PEOPLE,"r+") or die("Failed opening ".KPA_PEOPLE);
while($line=fgets($hndl_kpa_people)!==FALSE){
echo "\nline: ".$line."\n";
}
?>
Context:
The file looks like this in the file system:
-rw-r--r-- 1 snkdb snkdb 6096 dec 25 14:08 KPA_People.txt
(I'm the user snkdb)
The file's contents looks like:
et|2
Elisabet|3
okända|4...
The result looks like:
line: 1
line: 1
line: 1...
the expected result was:
et|2
Elisabet|3
okända|4...
as far as I understand the "while($line=fgets($hndl_kpa_people)!==FALSE)"
follows the convention in the manual and looks like it works in earlier scripts.
Any thoughts would be appreciated!
In the following line:
while($line=fgets($hndl_kpa_people)!==FALSE)
PHP is first evaluating the expression fgets($hndl_kpa_people)!==FALSE and then assigns it to the variable $line.
Furthermore, it is redundant to evaluate if something inside the while loop is different from false, since while loop runs while the condition it's evaluating is true.
So the line should be:
while($line = fgets($hndl_kpa_people))
You can read more on Operator Precedence in the official documentation: https://www.php.net/manual/en/language.operators.precedence.php
You can read more about while loop here: https://www.php.net/manual/en/control-structures.while.php
Edit: Since there is a confusion in the comments whether reading an empty line will return false - it will not. Take the following simple example:
<?php
$file = fopen('sample.txt', "r+");
$counter = 0;
while ($line = fgets($file)) {
print_r("Counter: $counter - Line: " . $line);
$counter++;
}
fclose($file);
with the following sample file:
test 123
test 234
test 345
The result from execution is:
Counter: 0 - Line: test 123
Counter: 1 - Line:
Counter: 2 - Line: test 234
Counter: 3 - Line: test 345
Related
I have to write a function that return the sum of all the numbers in a file.
The text file is numbers.txt:
1
1
2
3
5
8
13
21
The code I write is:
function sumFromFileInput($fileName) {
$total = 0;
$file = fopen("numbers.txt", "r");
while ($number = fgets($file)) {
$total += $number;
}
fclose($file);
return $total;
}
The output should be 54 whereas my output is 124712203354.
Please help me to figure out what I did wrong.
You can use file() for this purpose and simplifiy your code:
$trimmed = file('<provide file path here>', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$sum = array_sum($trimmed);
echo $sum;
In case you added values as string into file then you need to convert them to Integer first.
Add below line before array_sum() line:
$trimmed = array_map('intval', $trimmed);
function sumFromFileInput($fileName) {
$total = 0;
$file = fopen("numbers.txt", "r");
while (!feof($file)) { #this will give you a true value until it reaches end of the numbers.txt last line
$total += (int) fgets($file); # this will read file lines one by one
}
fclose($file);
return $total;
}
What happens if you modify your code to be like this:
function sumFromFileInput($fileName) {
$total = 0;
$file = fopen("numbers.txt", "r");
while ($number = fgets($file)) {
// Making sure to add integer values here
$total += (int)$number;
}
fclose($file);
return $total;
}
I have the feeling that your number values from your input file are being read in as strings instead of ints. Using something like (int) should be able to help with this type of issue. You could also potentially use (integer) or intval() instead of (int) for the conversion part. More info about this can be found here.
Update:
After seeing CBroe's comment, I removed my earlier part about the string concatenation conjecture.
When checking the sumFromFileInput() function locally and using var_dump($number) to show the $number variable's type, I can verify that it is a string. This is why I still recommend using something like (int), like in my added lines of code earlier in this answer. Without doing that, I get PHP notices in PHP 7.3.19 for these values that read like: PHP Notice: A non well formed numeric value encountered in [...].
Interestingly enough, though, I still get a total of 54 (as an int) with your original posted code. This gets me to thinking: it would be interesting to see the code you used to call your sumFromFileInput() function, because perhaps that might help explain why your output was what now appears to me to be a running sum total of the $total.
Also, this might not be as important, but it looks like your $fileName parameter isn't currently being used in your sumFromFileInput() function. Maybe this could be connected in the future?
I have a php (v. 7.0.16) script running on the command line with this:
$ct = 1;
foreach($sort_this as $cur_site_id => $dx){
$cur_location = $locations[$cur_site_id]['location'];
$msg = "\033[A\33[2K\r" . 'getting data for %25s (' . $cur_site_id . ') store: %7s %01.2f' . "\n";
echo printf($msg, $cur_location, ($ct . ' / ' . count($sort_this)), number_format((($ct / count($sort_this)) * 100), 2));
$ct++;
}
This loop runs about 40 iterations. The printf statement works with 1 small problem. On the line after the "getting data" line I see a number that increments from 7x-7y as it runs (sometimes it starts at 71, sometimes at 77, etc.). I can't figure out what's causing this number to be printed. So when the loop starts I see something like this on the screen:
getting data for DENVER (531) store: 42 / 42 0.00
77
and when it finishes something like this:
getting data for SEATTLE (784) store: 42 / 42 100.00
79
I found how to print to the same line and clear the data here:
Erase the current printed console line
Is there a way to prevent the 7x codes from showing? Also, what are they?
The problem is on this line:
echo printf(...)
printf() generates a string using its arguments (format and values) and prints it. It returns the number of printed characters (the length of the string it generated).
Your code then passes this value to echo that prints it. This is the source of the extra number in the range of 70-77.
You should either remove the echo or use sprintf() instead of printf().
sprintf() generates the string the same was printf() does but it doesn't print it; it returns it and it is passed as argument to echo that displays it.
printf() returns the length of the outputted string.
See PHP docs:
Return Values: Returns the length of the outputted string.
Just remove echo fom that line.
quick question really.
Consider the following code:
//__/var/test/cli_test.php__
$x = 0;
while ($x < 9){
print "loop " . str_pad($x, 3, "0", STR_PAD_LEFT) . "\n";
sleep(1);
$x++;
}
if I type php /var/test/cli_test.php in the command line I get 9 interspaced-by-time lines.. i.e. 9 positive outputs, one per second. EG: these arrive one at a time, blip blip blip...
loop 000
loop 001
loop 002
loop 003
loop 004
loop 005
loop 006
loop 007
loop 008
now consider a different proposition
//__/var/test/cli_test_shell.php
print shell_exec("php /var/test/cli_test.php");
if I type php /var/test/cli_test_shell.php in the command line I get nothing for 9 seconds then everything arrives.. i.e. 1 BIG output 1 BIG wait. after 9 seconds of nothing EG: wait, wait wait.. nothing THEN DUMP:
loop 000
loop 001
loop 002
loop 003
loop 004
loop 005
loop 006
loop 007
loop 008
how can I alter /var/test/cli_test_shell.php so that the output returns each line on per second
try this:
$handle = popen('php /var/test/cli_test_shell.php 2>&1', 'r');
while (!feof($handle)) {
echo fread($handle, 8192);
}
fclose($handle);
The desired behaviour is not possible using shell_exec(). This is because the function collects the output of the command and returns it as a string - after the command's termination. Use passthru() instead and keep cli_test.php as it is.
I use append code to write new lines in .txt file:
$fh = fopen('ids.txt', 'a');
fwrite($fh, "Some ID\n");
fclose($fh);
I want this file to have only 20 lines and delete the first (old) ones.
Read all the lines in, add your lines at the bottom, then rewrite the file with only the last 20 lines.
I am not great at php, but if you only want 20 lines surely you would do something like this pseudocode.
lines <- number of lines you want to write
if lines > 20
yourfile <- new file
yourfile.append (last 20 lines of your text)
else if lines = 20
your file <- new file
yourfile.append (your text)
else
remainingtext <- the last [20-lines] of yourfile
yourfile.append (remaining text + your text)
EDIT: an easier way of doing it, but perhaps less efficient [I think this is equivalent to NovaDenizen's solution]
yourfile <- your file
yourfile.append(yourtext)
newfilearray <- yourfile.tokenize(newline)(http://php.net/manual/en/function.explode.php)
yourfile <- newfile
for loop from i=newfilearray.size-21 < newfilearray.size
yourfile.append (newfilearray[i])
$content=file($filename);
$content[]='new line of content';
$content[]='another new line of content';
$file_content=array_slice($content,-20,20);
$file_content=implode("\n",$file_content);
file_put_contents($filename,$file_content);
You can us file() function to load file as an array. Then add new content to loaded array, slice it to 20 elements, make 'entered' text from this array and save it to a file.
You could make use of the function file:
http://php.net/manual/en/function.file.php
Reads an entire file into an array.
This said, you Need to do the following:
1.) Read the existing file into an Array:
$myArray= file("PathToMyFile.txt");
2.) Reverse the Array, so the oldest Entry is topmost:
$myArray= array_reverse($myArray);
3.) Add your NEW Entry to the end of that Array.
$myArray[] = $newEntry + "\n";
4.) Reverse it again:
$myArray= array_reverse($myArray);
5.) Write the first 20 Lines back to your file (this is your "new" + 19 old lines):
$i = 1;
$handle = fopen("PathToMyFile.txt", "w"); //w = create or start from bit 0
foreach ($myArray AS $line){
fwrite($handle, $line); //line end is NOT removed by file();
if ($i++ == 20){
break;
}
}
fclose($handle);
Why dont you just use file_put_contents("yourfile.txt", ""); to set the file contents to nothing and then just file_put_contents("yourfile.txt",$newContent)?
Are you trying to do something else or am I missing something?
I'm using an API in order to retrieve some temperature and location values in JSON format.
I'm writing the output in a plain text cachefile.
However a temperature station may fail reporting the temperature value, and in that case my output will be an empty line (\n). I want to handle such case by displaying "N/A" for a non-reporting station.
Here's a typical cachefile with the first station reporting temperature and location, and the second station shut down (reporting two empty lines):
27.6
Napoli-Posillipo
(an empty line)
(an empty line)
I tried with:
$display = file($cachename);
$temperature[0] = $display[0];
$location[0] = $display[1];
$temperature[1] = $display[2];
$location[1] = $display[3];
$temp_avg = (($temperature[0]+$temperature[1])/2); //average temperature
if($temperature[0] = "\n"){ //if weather station is not reporting data
$temperature[0] = "N/A";
$temp_avg = "N/A";
}
if($temperature[1] = "\n"){
$temperature[1] = "N/A";
$temp_avg = "N/A";
}
echo "<div id='temperature'><b>".$temperature[0]."</b>°C (".$location[0].") | ";
echo "<b>".$temperature[1]."</b>°C (".$location[1].") | ";
echo "<b>".$temp_avg."</b>°C (avg) | ".$minutes."m".$secondsleft."s ago</div>";
However I keep getting "N/A" for both stations, even if the first station correctly reports its temperature value.
N/A°C (Napoli-Posillipo ) | N/A°C () | N/A°C (avg) | 12m21s ago
I tried with fgets() instead of file(), but I got an error:
fgets() expects parameter 1 to be resource, string given in [...] on
line 54
I also tried using if(empty($temperature[foo])) but it didn't work, because of course \n != empty.
Any hints?
Thanks in advance
You also can use:
if (trim($temperature[1]) == '') {
// Empty line.
}
Your comparisons should look like this (note the use of two equal signs):
if($temperature[0] == "\n"){
Your current code is assigning "\n" to $temperature[1], which evaluates true, which is why the if condition is executing.
If you would like to use empty(), which I suggest you do, change your call to file() to:
$display = file($cachename, FILE_IGNORE_NEW_LINES);
Adding the FILE_IGNORE_NEW_LINES flag will tell the function not to add newlines ("\n") to the end of the array elements.