Logic in if statement with numbers PHP - php

Can someone explain what's happening here:
if(2 && 5 < 4)
If i've got for example
$x = 2 && 3;
and var_dump($x) it gives boolean(true) no matter what numbers are.
But here it looks like numbers are comparing to 4 one by one.

Look at the PHP comparison table for PHP http://php.net/manual/en/types.comparisons.php
For integers a number other than 0 returns true in comparison.
if (2 && 5 < 4) => if (true && false) => false
$x = 2 && 3 = 1 && 1 = 1
because if a variable has an integer value, true becomes 1 because of type conversion.

Related

PHP multiple OR logical operators in one IF statement

I have a question about IF statements with multiple logical OR operators.
If we let:
$x=1;
A. I typical would write a IF statement comparing two items like this:
if($x == 1 || $x == 2) echo 'good';
else echo 'bad';
B. But, is this a valid IF statement? If not, why? (because it seems to work)
if($x == (1 || 2)) echo 'good';
else echo 'bad';
C. I typical would write a third comparison like this:
if($x == 1 || $x == 2 || $x == 3) echo 'good';
else echo 'bad';
D. What about this, following suit with B, above? (it does not seem to work)
if($x == (1 || 2 || 3)) echo 'good';
else echo 'bad';
The example in B, above works, but not the example in D. Why?
I cannot find any PHP documentation as to why.
Here is what happens for every version:
A. $x == 1 || $x == 2
PHP will compare $x with the value 1, this is true so it can short-circuit the if and echo 'good'.
B. $x == (1 || 2)
PHP will evaluate 1 || 2 because parentheses indicate the priority, as the result should be a boolean expression it will cast 1 to a boolean which evaluates to true so the expression becomes $x == true.
Now PHP will evaluate this expression. First it will cast both types to the same, according to the documentation, it will "Convert both sides to bool". So, same as above, as $x is 1 it will be cast to true and then the expression becomes true == true which is true.
C. $x == 1 || $x == 2 || $x == 3
It is the same as A.
D. $x == (1 || 2 || 3)
It is quite the same as B.
And, for the record 1 == (1 || 2 || 3) evaluates to true.

check if a number is a multiple of another inside for [duplicate]

Within a for loop, i need to add some HTML that outputs only when the loop is on a [(multiple of 3) minus 1].
For example, what i could do is:
for($i=0; $i<count($imagearray); $i++)
{
if($i=="0" || $i=="2" || $i=="5" || $i=="8" || $i=="11")
{
echo 'string';
}
}
but this isnt very elegant and extremely useless for big for loops, is there a proper way to do this?
if ( $i==0 || ($i+1)%3 == 0 )
{
//do stuff
}
What this will do, is go to the next index, divide it by 3, and see if there is a remainder. If there is none, then that means that the current index is one less than a number that is divisible by 3
Use the modulus operator.
if (! (($i+1) % 3) ) {
If $i+1 divides into 3 with no remainder, the result will be zero. Then you just need a boolean not.
If you want to match 0 as well (since you use it in your example, but it doesn't match your description) then you will have to special case it with an ||.
You want to use the modulo for that:
(1 % 3) == 1
(2 % 3) == 2
(3 % 3) == 0
(4 % 3) == 1
Good luck
Modulo is the same thing as saying, give me the remainder of a division. So 1 / 3 equals 0 remainder 1, and so on.
if(($i+1)%3 == 0){
//do something
}
The % operator is known as the modulus operator and returns the remainder of a division.
the most elegent method is thus
if ($i % 3 === 2) {
//do stuff
}
as it doesn't add things to the $i value, but all answers are essentially correct!

PHP: Logical Operator: Why does (5 || 3) return 1?

While building a small Feedback-Solution where people can give a number of stars (between 0 and 5), I noticed that all user submitted ratings are stored with just 1 star.
I tried it myself by submitting 5 stars and the backend still shows 1 star.
So I looked into the code and this is the piece that causes the trouble:
$feedback->rating = ($wire->input->post->rating || 1);
Actually the || operator isn't doing what I suspected it to do.
In fact it just returns 1 every time (unless both hand sides are $false).
Check my example code below:
$example1 = ($true || 5);
$example2 = ($false || 5);
$example3 = ($false || $false);
$example4 = (5 || 0);
echo $example1."\n";
echo $example2."\n";
echo $example3."\n";
echo $example4."\n";
Also I made a paste here: https://eval.in/514978.
What I'm assuming is, PHP tries to convert the statements to an integer (either 0 or 1) depending on the given elements, is that true?
I'm used to use the || operator in JavaScript a lot where I can just type
var i = myFunction() || "default";
This will check if myFunction() returns a bool-ish value and if not just uses the right hand side value (rather than turning everything into an int).
|| is the or operator in PHP and it evaluates to either true or false. If you want the binary or operator you should use | instead.
Since everything not equall zero is treated like true it makes sense that all of the evalations give true, which as integer becomes 1.
You can see more info here: http://php.net/manual/en/language.operators.logical.php
Example ----- Name -----Result
$a || $b ------- Or ---------TRUE if either $a or $b is TRUE.
There is a difference to PHP || handling as opposed to other languages.
In PHP 5 || 7 will always return true; the || operator will always return a boolean.
5 || 7 = true;
In other languages like javascript. 5 || 7 will return 5 and 7 || 1 will return 7; the || operator will return the parameter that was evaluated true (or the last parameter);
5 || 7 = 5;
7 || 1 = 7;
0 || 7 || 1 = 7;
0 || 0 = 0;
In PHP you can achieve the same by using a ternary operator:
$result = $int ? $int : 1;
if the $int is implicitly true, $result will be $int, otherwise $result will be 1;
Or since PHP 5.3:
$result = $int ?: 1;
$feedback->rating = ($wire->input->post->rating || 1);
Come on, It is returning TRUE which you see as 1
Try this
echo TRUE; //1
What you are looking for is a ternary operator.
$feedback->rating = $wire->input->post->rating ?: 1;
^^
This gives you that value if it is set, otherwise gives you an actual 1.

php comparing 2 co-ords

I don't know why, but this doesn't seem to work.
Basically I want this to be true if the player1 ($playerX, $playerY) is within one square from player2 ($rs[x], $rs[y])
if (($rs[x] > $playerX-2 or $rs[x] < $playerX+2) && ($rs[y] > $playerY-2 or $rs[y] < $playerY+2)) {
// code
Any idea what I'm doing wrong?
If you replace with some test values, you might get:
if( (3 > 5 or 3 < 9) && (13 > 15 or 13 < 19))
Clearly, this is always true.
You should use && instead of or in this case.
It's just a case of replacing or with and. Here's a neater way of writing your if statement for bonus points:
if(abs($playerX - $rs[x]) < 2 && abs($playerY - $rs[y]) < 2) {
// code
Your conditions end up on true due to the OR operator
if (($rs[x] > $playerX-2 && $rs[x] < $playerX+2) && ($rs[y] > $playerY-2 && $rs[y] < $playerY+2)) {
//your code
}

Best way to check for positive integer (PHP)?

I need to check for a form input value to be a positive integer (not just an integer), and I noticed another snippet using the code below:
$i = $user_input_value;
if (!is_numeric($i) || $i < 1 || $i != round($i)) {
return TRUE;
}
I was wondering if there's any advantage to using the three checks above, instead of just doing something like so:
$i = $user_input_value;
if (!is_int($i) && $i < 1) {
return TRUE;
}
Not sure why there's no suggestion to use filter_var on this. I know it's an old thread, but maybe it will help someone out (after all, I ended up here, right?).
$filter_options = array(
'options' => array( 'min_range' => 0)
);
if( filter_var( $i, FILTER_VALIDATE_INT, $filter_options ) !== FALSE) {
...
}
You could also add a maximum value as well.
$filter_options = array(
'options' => array( 'min_range' => 0,
'max_range' => 100 )
);
Learn more about filters.
the difference between your two code snippets is that is_numeric($i) also returns true if $i is a numeric string, but is_int($i) only returns true if $i is an integer and not if $i is an integer string. That is why you should use the first code snippet if you also want to return true if $i is an integer string (e.g. if $i == "19" and not $i == 19).
See these references for more information:
php is_numeric function
php is_int function
The best way for checking for positive integers when the variable can be INTEGER or STRING representing the integer:
if ((is_int($value) || ctype_digit($value)) && (int)$value > 0 ) { // int }
is_int() will return true if the value type is integer. ctype_digit() will return true if the type is string but the value of the string is an integer.
The difference between this check and is_numeric() is that is_numeric() will return true even for the values that represent numbers that are not integers (e.g. "+0.123").
It's definitely heading towards the land of micro-optimisation, but hey: the code I'm working on chews through millions of items every day and it's Friday. So I did a little bit of experimenting...
for ($i = 0; $i < 1000000; $i++) {
// Option 1: simple casting/equivalence testing
if ((int) $value == $value && $value > 0) { ... }
// Option 2: using is_int() and ctype_digit(). Note that ctype_digit implicitly rejects negative values!
if ((is_int($value) && $value > 0) || ctype_digit($value)) { ... }
// Option 3: regular expressions
if (preg_match('/^\d+$/', $value)) { ... }
}
I then ran the above tests for both integer and string values
Option 1: simple casting/equivalence testing
Integer: 0.3s
String: 0.4s
Option 2: using is_int() and ctype_digit()
Integer: 0.9s
String: 1.45s
Option 3: regular expressions
Integer: 1.83s
String: 1.60s
Perhaps unsurprisingly, option 1 is by far the quickest, since there's no function calls, just casting. It's also worth noting that unlike the other methods, option 1 treats the string-float-integer value "5.0" as an integer:
$valList = array(5, '5', '5.0', -5, '-5', 'fred');
foreach ($valList as $value) {
if ((int) $value == $value && $value > 0) {
print "Yes: " . var_export($value, true) . " is a positive integer\n";
} else {
print "No: " . var_export($value, true) . " is not a positive integer\n";
}
}
Yes: 5 is a positive integer
Yes: '5' is a positive integer
Yes: '5.0' is a positive integer
No: -5 is not a positive integer
No: '-5' is not a positive integer
No: 'fred' is not a positive integer
Whether or not that's a good thing for your particular use-case is left as an exercise for the reader...
The other best way to check a Integer number is using regular expression. You can use the following code to check Integer value. It will false for float values.
if(preg_match('/^\d+$/',$i)) {
// valid input.
} else {
// invalid input.
}
It's better if you can check whether $i > 0 too.
preg_match('{^[0-9]*$}',$string))
and if you want to limit the length:
preg_match('{^[0-9]{1,3}$}',$string)) //minimum of 1 max of 3
So pisitive int with a max length of 6:
if(preg_match('{^[0-9]{1,6}$}',$string)) && $string >= 0)
You don't really need to use all three check and if you want a positive integer you might want to do the opposite of what is in your code:
if(is_numeric($i) && $i >= 0) { return true; }
Check Sören's answer for more information concerning the difference between is_int() and is_numeric()
if(preg_match('/^[1-9]\d*$/',$i)) {
//Positive and > 0
}
Rather than checking for int OR string with multiple conditions like:
if ( ctype_digit($i) || ( is_int($i) && $i > 0 ) )
{
return TRUE;
}
you can simplify this by just casting the input to (string) so that the one ctype_digit call will check both string and int inputs:
if( ctype_digit( (string)$i ) )
{
return TRUE;
}
In addition to all the other answers: You are probably looking for ctype_digit. It looks for a string containing only digits.
Definition:
!A = !is_numeric($i)
B = $i < 1
!C = $i != round($i)
Then...
!is_numeric($i) || $i < 1 || $i != round($i) is equal to
!A || B || !C
So:
!A || B || !C = !A || !C || B
Now, using the deMorgan theorem, i.e. (!A || !C) = (A && C), then:
!A || !C || B = (A && C) || B
Now, note that A && C = is_numeric($i) && $i == round($i), but if $i == round($i) is TRUE, then is_numeric($i) is TRUE as well, so we can simplify A && C = C so,
(A && C) || B = C || B =
$i == round($i) || $i < 1
So you just need to use:
$i = $user_input_value;
if ($i == round($i) || $i < 1) {
return TRUE;
}
Laravel 4.2 Validation rule for positive number
It takes only positive numbers including float values.
public static $rules = array(
'field_name' => 'required|regex:/^\d*\.?\d*$/'
);
e.g:20,2.6,06
The first example is using round to verify that the input is an integer, and not a different numeric value (ie: a decimal).
is_int will return false if passed a string. See the PHP manual examples for is_int
To check for positive integer use:
$i = $user_input_value;
if (is_int($i) && $i > 0) {
return true; //or any other instructions
}
OR
$i = $user_input_value;
if (!is_int($i) || $i < 1) {
return false; //or any other instructions
}
Use the one that fits your purpose as they are the same. The following examples demonstrate the difference between is_numeric() and is_int():
is_numeric(0); // returns true
is_numeric(7); // returns true
is_numeric(-7); // returns true
is_numeric(7.2); // returns true
is_numeric("7"); // returns true
is_numeric("-7"); // returns true
is_numeric("7.2"); // returns true
is_numeric("abc"); // returns false
is_int(0); // returns true
is_int(7); // returns true
is_int(-7); // returns true
is_int(7.2); // returns false
is_int("7"); // returns false
is_int("-7"); // returns false
is_int("7.2"); // returns false
is_int("abc"); // returns false
All these answers overlook the fact that the requestor may checking form input.
The is_int() will fail because the form input is a string.
is_numeric() will be true also for float numbers.
That is why the $i == round($i) comes in as it checks for the input being a whole number.
Ok, I know this thread is really old but I share #Jeffrey Vdovjak's opinion: since I was able to find it, it might still help someone else out there.
php's gmp_sign() might be another easy way to check. It works for integer and numeric strings, and returns 1 if a is positive, -1 if a is negative, and 0 if a is zero.
So:
// positive
echo gmp_sign("500") . "\n";
// negative
echo gmp_sign("-500") . "\n";
// zero
echo gmp_sign("0") . "\n";
will output:
1
-1
0
See function manual at http://php.net/manual/en/function.gmp-sign.php
P.S. You'll need to have php_gmp.dll enabled in your .ini file.
This's my solution, hope helpful :
if (is_numeric($i) && (intval($i) == floatval($i)) && intval($i) > 0)
echo "positive integer";
i check if string is numeric, second check to sure it's integer and third to sure it positive
If you use "is_int" the variable must be integer, so it can't be a float value. (no round needed).
if(isset($i) && is_int($i) && $i >= 0){ //0 is technically a postive integer I suppose
return TRUE; //or FALSE I think in your case.
}
I would do something like this:
if ((int) $i > 0) {
// this number is positive
}
The number gets typecast to a positive or negative number depending on the minus sign being at the front. Then compares the typecast number to being greater than 0 to determine if the number is positive.

Categories