Simple PHP hit counter / if else statement - php

I am trying to create a hit counter that once it reaches a certain number (in this case, 5), it will no longer display the amount of hits. This is my code:
<?php
$count = ("hits.txt");
$hits = file($count);
$hits[0] ++;
$fp = fopen($count , "w");
fputs($fp , "$hits[0]");
fclose($fp);
if ($hits > 5) {
echo "More than 5 hits";
}
else {
echo $hits[0];
}
?>
What am I doing wrong?

You are overcomplicating things. It would be much easier to do it like this:
$hits = file_get_contents('hits.txt');
++$hits;
file_put_contents('hits.txt', $hits);
if($hits > 5) {
echo 'Over 5!';
}
// else etc
As for your current code, the problem is that you don't test the number of hits with the correct syntax $hits[0] -- which you already use in fputs -- but with the wrong $hits instead. Remember that due to the way file works, $hits itself is an array. PHP will happily let you compare an array to an integer, and there are rules that define how the comparison works, but don't go there.

You need $hits[0] > 5:
if ($hits[0] > 5) {
echo "More than 5 hits";
}
The array value $hits when compared against a number 5 is compared as the string Array rather than the value of the array's first item. The string Array is always greater than 5.

More or less everything. In addition to other answers this
fputs($fp , "$hits[0]");
won't work as expected, you want either "{$hits[0]}" or $hits[0] (no quotes).
That is, if you don't care about concurrent access.

Related

I'm getting wrong result in php code where I have to return the total sum of all the numbers from a file

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?

"If" doesn´t work - weird string formatting

I have weird problem with data handling. I need to pick data from the user form, and handle it (generate xml).
The data is for example this:
2000;AC;1;60;5;5;Do your setup - meaning voltage, voltage type, test current, test time, ramp-up time, rampdown time, and user prompt.
I want to decide how to assemble my xml file based on the last value. If it is zero, there will be shorter xml assembly, while when there is text, there will be user prompt assembly of xml taggery.
So I explode the input into array, and check the value by:
If (empty($xplodline[6]) == true) {do this;}
else {do that;}
The problem is, that it always only does "that", and never "this", even when there is 0 in the $xplodline[6] as intended.
So I put echo $xplodline[6]; into {do that;} to see what´s happening.
The zero is echoed, (and while this action is in the cycle, I get other $xplodline[6]s from the cycle), and I see there is a space between the zero in the $xplodline[6] and next $xplodline[6] iteration. When I look into user form or temporary cleaned file with these values, there is no space between. Where could it come from?
When I put another array divider into the user form to make it ;0; there is no space, and If statement works well.
Here is the original data from the temporary cleaned file:
2000;AC;1;60;5;5;0
2000;AC;1;60;5;5;Set your cables for X10
2000;AC;1;60;5;5;Set your cables for X10
Any idea?
Ok, here is the code:
$stringer = fopen($tempfile, "r");
while(!feof($stringer)){
$oneline = fgets($stringer) ;
$xplodline = explode(";",$oneline) ;
$range01 = "gross" ;
$rampup = "100" ;
$rampdown = "100" ;
$rampupfunction = "false" ;
$rampdownfunction = "false" ;
$currentrange = "_1mA" ;
$assy01 = "1" ;
if ($xplodline[0] >= 3000) {$range01 = "gross" ;}
else {$range01 = "klein" ;}
if (empty($xplodline[4]) == false) {$rampupfunction = "true" ; $rampup = round($xplodline[0] / $xplodline[4]) ;}
if (empty($xplodline[5]) == false) {$rampdownfunction = "true" ;$rampdown = round($xplodline[0] / $xplodline[5]) ;}
if ($xplodline[2] < 1) {$currentrange = "_1mA";}
if ($xplodline[2] >= 1 && $xplodline[2] < 10) {$currentrange = "_10mA";}
if ($xplodline[2] >= 10 && $xplodline[2] < 100) {$currentrange = "_100mA";}
if (empty($xplodline[6]) == true) {$assy01 = $xmltestbegin.$xplodline[0]."V ".$xplodline[1].$xmltype.$xplodline[1].$xmlrange.$range01.$xmlrampup.$rampupfunction.$xmlrampdown.$rampdownfunction.$xmlcurrentrange.$currentrange.$xmlvoltage.$xplodline[0].$xmlrampupspeed.$rampup.$xmlrampdownspeed.$rampdown.$xmltesttime.$xplodline[3].$xmlcurrent.$xplodline[2].$xmlballast ;}
else {$assy01 = $xmlpromptbegin.$xplodline[6].$xmlpromptend.$xmltestbegin.$xplodline[0]."V ".$xplodline[1].$xmltype.$xplodline[1].$xmlrange.$range01.$xmlrampup.$rampupfunction.$xmlrampdown.$rampdownfunction.$xmlcurrentrange.$currentrange.$xmlvoltage.$xplodline[0].$xmlrampupspeed.$rampup.$xmlrampdownspeed.$rampdown.$xmltesttime.$xplodline[3].$xmlcurrent.$xplodline[2].$xmlballast ;}
file_put_contents ( $filename, $assy01, FILE_APPEND );
}
fclose($stringer);
My function works ok, every If except the last one, works...
From http://php.net/manual/en/function.fgets.php
Reading ends when length - 1 bytes have been read, or a newline (which is included in the return value), or an EOF (whichever comes first). If no length is specified, it will keep reading from the stream until it reaches the end of the line.
In short, there's always going to be a newline character in your last array entry. Clean it up by doing
$oneline = rtrim(fgets($stringer));
You can also consider:
$stringer = fopen($tempfile, "r");
while(!feof($stringer)){
$xplodline = fgetcsv($stringer,0,";");
//Rest of code as normal
which would let PHP handle the file as a CSV style file.

SPOJ prime generator in PHP

I am getting time limit exceeded error while I submitted my solution.
<?php
$stdin = fopen('php://stdin', 'r');
$testcase = fgets($stdin);
$n=1;
while($n<=$testcase){
$start = fgets($stdin);
$end=fgets($stdin);
if($start==1) {
$start=2;
}
for($i=$start;$i<$end;$i++){
$flag=0;
for($j=2;$j<$i;$j++){
if($i%$j==0){
$flag=1;
break;
}
}
if($flag==0){
echo $i."\n";
}
}
$n++;
}
fclose($stdin);
?>
Please help me out, I'm stuck with time limit exceeded error and please explain why I'm getting this error. In my local version it shows the correct answer.
Your solution is too slow. Try a slightly modified Sieve of Eratosthenes. The modification should allow your sieve to work only in the [start, end] interval.
In the first for loop, instead for looping all the numbers, you can loop only the odd numbers since other than 2 all the even numbers can never be prime.
you can use $i+=2 in first for loop. this could help you reduce some unnecessary looping.
Update 1:
Also inside second for loop, instead of finding modulo will all the numbers, you could just store the calculated prime numbers in an array and check whether the $i % calculated prime numbers == 0 instead of $i%$j

PHP Counter overwraps/overflows only 1 byte of data, counter resets (race condition)

I know this is a simple question but I downloaded a PHP Counter script from http://www.stevedawson.com/scripts/text-counter.php
which is the first result on google for PHP counter scripts and it worked great as expected.
I tried to see if it messes up by holding refresh in my browser after 255 requests it overflowed back to 0. How would I fix this script? I think the culprit is the filesize() which probably gets only 1 byte of data but it doesn't make sense since 255 is actually 3 bytes of data right? since it saves in plain-text format?
Why would it overflow? it's even PHP it shouldn't overflow just automatically mutate into a bigger datatype.
<?php
$orderCountFile = "order_num_count.txt";
if (file_exists($orderCountFile)) {
$fil = fopen($orderCountFile, r);
$dat = fread($fil, filesize($orderCountFile));
echo $dat+1;
fclose($fil);
$fil = fopen($orderCountFile, w);
fwrite($fil, $dat+1);
} else {
$fil = fopen($orderCountFile, w);
fwrite($fil, 1);
echo '1';
fclose($fil);
}
?>
Yeah I started to remake the script into another purpose I want to use it to keep track of order numbers for my website.
For a fix I think I have to recast $dat into a bigger integer type but can you even cast in PHP?
Also those r and w are suppose to be strings i think but they are used as constants but it doesn't seem to cause any troubles afaik.
Use file_get_contents and file_put_contents instead. You still have to consider, that there is a hard limit for that counter as well (see PHP_INT_MAX), but it's significantly higher.
<?php
$file = "counter.txt";
$counter = 0;
if (file_exists($file)) {
$counter = file_get_contents($file);
}
$counter = $counter + 1;
file_put_contents($file, $counter);
echo $counter;

How can I search for exact number through a file containing thousands of numbers?

If we say that we have a text file containing order numbers or references (1 Number per 1 Line only) what is the best way to find/validate an input (number entered in form for example) against those numbers in a file?
Is there a simple idea to do it? Assume we have thousands of numbers to search through.
Thank you very much.
If memory is not an issue (Demo):
if (in_array($number, file('numbers.txt', FILE_IGNORE_NEW_LINES))) {
// number exists - do something
}
Since file returns an array where each line is one element in the array, you can also use array_search to find the line where it was found or array_keys to find all the lines where it was found.
If memory is an issue (Demo):
foreach(new SplFileObject('numbers.txt') as $line) {
if ($number == $line) {
// number exists - do something
break;
}
}
When in doubt which to use, benchmark.
Marking CW because there is already several questions asking how to read a file line by line or efficiently.
$file = file_get_contents("filename.txt");
if (strpos($file, "search string") === false) {
echo "String not found!";
}
if the numbers are ordered: don't load the whole file into memory. seek to the middle of the file and read the number. if your number is < than the middle, seek the middle of the first half. otherwise seek the middle of the second half...
Binary Search
If you want to return the line number of the location of the matching number in the file, you can use file() to return the reference file as an array of file lines.
$search_string = '42';
$file_name = 'test_file.txt';
$file = file($file_name);
foreach($file as $line_number=>$number){
if(intval($search_string) == $number){
$found_on_lines[] = $line_number;
}
}
echo "String ".$search_string;
if(count($found_on_lines)>0){
echo " found on line(s):</br> ";
foreach($found_on_lines as $line){
echo $line."</br>";
}
}
else{
echo "not found in file ".$file_name.".";
}
This will output
String 42 found on line(s):
9
256
if your reference file contains the number '42' on lines 9 and 256.

Categories