Wrong calculation - php

I got a weird problem.
I want a simple system which shows an error if there are more than 1 request in one second.
What i did:
if(!isset($_SESSION['protect']['mass_request_time']) || $_SESSION['protect']['mass_request_time'] = null) {
$_SESSION['protect']['mass_request_time'] = microtime(true);
$_SESSION['protect']['mass_request_request'] = 1;
} else {
$_SESSION['protect']['mass_request_request'] += 1;
if($_SESSION['protect']['mass_request_request'] >= 2 && microtime(true) - $_SESSION['protect']['mass_request_time'] < 1) {
die('Too many requests!');
} elseif(microtime(true) - $_SESSION['protect']['mass_request_time'] > 1) {
# Reset the counter since more than a second is over
$_SESSION['protect']['mass_request_time'] = null;
}
I have no clue what i did wrong, i guess the solution is pretty easy (maybe just a calculation error.. it's already 3 AM here).

Your first if statement isn't valid.
$time = $_SESSION['protect']['mass_request_time'];
if (!isset($time) || $time = null)
Your code just just sets the time to null. Use == instead.

Related

PHP Warning: count(): Parameter must be an array or an object that implements Countable?

On my website I allow people to upload image galleries. When they click an image there is a next and previous button at the bottom so they can easily scroll back and forth through the images.
I am getting the below error in my log located at /opt/cpanel/ea-php72/root/usr/var/log/php-fpm/
NOTICE: PHP message: PHP Warning: count(): Parameter must be an array or an object that implements Countable in . . . on line 12
It is talking about the line below in my code:
$max = count($photos);
Below is the other code that comes with that line:
$photos = get_field('gallery');
$max = count($photos); <------- error line here -------->
$current = (isset($_GET['image'])) ? intval($_GET['image']) : false;
if ($current !== false) {
if ($current > $max) $current = $max;
if ($current < 1) $current = 1;
}
$next = (($current + 1) < $max) ? ($current + 1) : $max;
$prev = (($current - 1) > 1) ? ($current - 1) : 1;
?>
Basically this code uses get_field('gallery') to get the total amount of photos in the gallery and the number is assigned to variable max.
The rest of the code is how the next and previous buttons work.
I do not know what is wrong. Can somebody help with this?
In the general, solution is simple:
First debbug with var_dump() what $photos return. Than you will know what's the issue.
count() accept array and if you have false, null or anything else you will have error.
Just do something like this:
$photos = get_field('gallery');
if(!is_array($photos) || empty($photos)) $photos = array(); // FIX ERROR!!!
$max = count($photos); <------- error line here -------->
$current = (isset($_GET['image']) && !empty($_GET['image']) && is_numeric($_GET['image'])) ? intval($_GET['image']) : 0;
if ($current > 0) {
if ($current > $max) $current = $max;
if ($current < 1) $current = 1;
}
$next = (($current + 1) < $max) ? ($current + 1) : $max;
$prev = (($current - 1) > 1) ? ($current - 1) : 1;
?>
With if(!is_array($photos) || empty($photos)) $photos = array(); before $max = count($photos); you fixing your issue and anything what is not array or empty (0, NULL, FALSE, '') will be fixed and you will have in the count $max result 0 because array is empty.
IMPORTANT!!!
You should not work like this. You need to know what information you receive and expect in variables. The code must remain clean and correcting such errors is a bad practice. If you receive an array, then the array is expected and you must have checks before any calculating.
UPDATE:
Also you have error in
$current = (isset($_GET['image'])) ? intval($_GET['image']) : false;
if ($current !== false)
I fix it to work like this:
$current = (isset($_GET['image']) && !empty($_GET['image']) && is_numeric($_GET['image'])) ? intval($_GET['image']) : 0;
if ($current > 0)
Reason for that is that you have calculations below and you not expect (false + 1) to be something good. false can be translated to 0 but in your case you can also get error. For that case I replace false with 0, add empty() and is_numeric() check and you have no errors there.

PHP if and else statement not working properly

im trying to create a script that generates a number and depending on the number generated it prints something specific but it's not working properly, Heres the code:
<?php
for($zz = 1; $zz <= 20; $zz++) {
$rangen = rand(1,100);
$a = (1 <= 0) && (0 <= 7);
$b = (8 <= 0) && (0 <= 17);
echo ("<br>".$rangen . "<br>");
if($a) {
echo "a";
} elseif ($b) {
echo "b";
} else {
echo "c";
}
}
?>
The error is that it keeps printing "c" no matter what the number is.
If anyone could help that would be great, thanks.
Your conditions are all wrong. Your comparing the same numbers and never using $rangen, this is why you obtain the same result each time.
1 <= 0 and 8 <= 0 will always return false which is why you always go to the else statement.

Php age check form

I'm giving my first steps on php and I got this project where, although I understand what is being done, for some reason it does not work.
$app->post('/age/', function($lang) use($app) {
$action = $app->request()->post('action');
$remember = $app->request->post('remember') === 'on';
if ($action === 'Yes') {
setcookie('AgeCheck', 'true', time()+60*60*24*30, '/'); //Expire in 1 month
$_SESSION['age'] = 'true';
$app->redirect(urldecode($app->request()->get('return')) ?: "/$lang");
}
else if ($action === 'Enter') {
$limit = (60 * 60 * 24 * 365) * 18;
$dob = $app->request->post('dob');
if ($lang === 'us') {
$dob = \DateTime::createFormFormat('mdy', $dob);
$limit = (60 * 60 * 24 * 365) * 21;
}
else
{
$dob = \DateTime::createFromFormat('dmy', $dob);
}
if ((time() - $dob->getTimestamp()) >= $limit)
{
setcookie('AgeCheck', 1, (60*60*24*365)/12); //Expire in 1 month
$_SESSION['age'] = 1;
$app->redirect(urldecode($app->request()->get('return')) ?: "/$lang");
}
}
$app->redirect("/$lang/underage");
This should, in theory,redirect the user to the proper page if he passes the age restriction, but it always redirects him to the underage page.
The issue is, most definitely, in here: if ((time() - $dob->getTimestamp()) >= $limit)
What am I doing wrong?
Always check every line of your code.
Your key condition is:
if ((time() - $dob->getTimestamp()) >= $limit)
{
setcookie('DrambuieAgeCheck', 1, (60*60*24*365)/12); //Expire in 1 month
$_SESSION['age'] = 1;
$app->redirect(urldecode($app->request()->get('return')) ?: "/$lang");
}
So before that, just echo/var_dump $dob->getTimestamp(), and $limit. Everything will be clear for you.
If something wrong with $dob, check what is returned by $_POST['dob'].
Example:
var_dump($dob->getTimestamp());
var_dump($app->request->post('dob'));
var_dump($dob->getTimestamp());
var_dump(time());
echo 'condition result:';
var_dump(((time() - $dob->getTimestamp()));
if ((time() - $dob->getTimestamp()) >= $limit)
You will see most important variables in condition, and condition it self
Figured the issue. Everything was correct, but it wasn't even entering the if, since the $action was not enter, but submit. I'l still keep #Daimos answer as correct.
The more interesting part here is that ((time() - $dob->getTimestamp()) >= $limit) is actually true(in this context). So maybe the $action is not Enter? – Andrew
This was the key to solve it, after I've tried everything and checked that it was all correct.

Making many If statments into One statement. Php

function rawtransform{
if ($raw>=500 && $raw<=550){
$score= 1;
}
if ($raw>=550 && $raw<=600){
$score= 2;
}
if ($raw>=600 && $raw<=650){
$score= 3;
}
if ($raw>=700 && $raw<=750){
$score= 4;
}
if ($raw>=750 && $raw<=800){
$score= 5;
}
if ($raw>=800 && $raw<=850){
$score= 6;
}
if ($raw>=850 && $raw<=900){
$score= 7;
}
if ($raw>=900 && $raw<=950){
$score= 8;
}
if ($raw>=950 && $raw<=1000){
$score= 9;
}
}
This seems very basic and not very well coded. (I am only learning php )
Can anyone offer a better way of doing this? maybe a single if statement. I think there is a way just cant get my head round it.
Thanks
How about just using math?
function rawtransform($raw) {
$score = (int)($raw/50)-9;
}
You may want to add a range check for the input, though.
You can create a list of conditions, and loop through the and apply the if.
$conditions = array(
array(500, 550, 1), // greater than value, lesser than value, assignment value
array(550, 600, 2),
array(650, 700, 3) // add the rest of the conditions
);
foreach($conditions as $condition) {
if($raw >= $condition[0] && $raw <= $condition[1]) {
$score = $condition[2];
}
}
if ($raw >= 500 && $raw<= 1000){
$score = ceil(($raw-500)/50);
}
You can use if...else constructs.
if ($raw>=500 && $raw<=550){
$score= 1;
}
elseif ($raw>=550 && $raw<=600){
$score= 2;
}
elseif ($raw>=600 && $raw<=650){
$score= 3;
}
That way, if the script encounters a size of, say, 575 it won't even bother to go through the following conditions.
In your given example, the script can be simplified by:
function rawtransform($raw) { $score = floor(($raw - 450)/50); return $score; }
Your logic seems to be that you are subtracting 450 from raw, then dividing it by 50 and rounding down to the nearest whole number. (There are problems in your implementation however, as if raw is a factor of 50, it will meet the requirements for two of the if statements and there is a condition missing for when it falls between 650 and 700.)
You could do this as follows:
floor(($raw-450)/50)

php, how to simplify a php script?

im not sure this is a good question to post but here is my issue. I have an if statement that is getting way too long and i was wondering if there is some other kind of syntax to shorten it out:
if (($time1 <= $one_day)&&
($time2 <= $one_day)&&
($time3 <= $one_day)&&
($time4 <= $one_day)&&
($time5 <= $one_day)&&
($time1 != NULL)&&
($time2 != NULL)&&
($time3 != NULL)&&
($time4 != NULL)&&
($time5 != NULL)){
//do sometihng
}
this is one example but i have a similar one that goes up to ..&&($time15 <= $one_day).
the statement is pretty self explanatory, $time1, $time2, etc can come back empty so i have to check if they are NULL or not
any ideas?
thanks
You can put the common stuff in a function:
function validate_time($time, $one_day) {
return $time <= $one_day && $time != NULL;
}
if (validate_time($time1, $one_day) &&
validate_time($time2, $one_day) &&
validate_time($time3, $one_day) &&
validate_time($time4, $one_day) &&
validate_time($time5, $one_day)) {
// do something
}
You may want to refactor code and eliminate the need for copying & pasting those checks. Another way to get the job done:
while (true) {
foreach (array($time1, $time2, $time3, $time4, $time5) as $time) {
if ($time > $one_day || $time == NULL) {
break 2;
}
}
// do something
break;
}
The above could be put in a function as well which would make the while-loop and break keyword redundant. Replace break 2 by return then.
Using an array for you variables would help. The you can iterate over them and check.
Put the times in an array and have a for loop to do the checking.
Instead of using 15 similar but different variables, consider using an array.
If you must (or want to) keep the original variable names and not use an array here is the good solution (for $time1 to $time5):
$ok = true;
for ($i = 1; $i <= 5; $i++)
{
$var =& ${'time'.$i};
if ( ! ($var <= $one_day && $var != NULL))
{
$ok = false;
}
}
if ($ok)
{
//do something
}
You can set all the values into an Array and compare it using an For Loop.
A functionised version which should help with your reuse. This is similar to Lekensteyns code.
$times = array(
'time',
'time',
'time',
'time',
'time',
);
function validateTime($checks, $limit)
{
foreach($checks as $check) {
if($check == null || $check > $limit) {
return false;
}
}
return true;
}
if(validateTime($times,$one_day) == true) {
//codey code.
}

Categories