PHP is still new to me so excuse me if I am missing something basic here.
I have some very simple code:
echo $_GET['initState'];
if ($_GET['initState']) {
$num = 10;
}
else {
$num = PHP_INT_MAX;
}
echo $num;
And when I check my logs, I see the following: false10
So initState is false, and yet num is assigned to 10
But when I change the code to the following:
echo $_GET['initState'];
if ($_GET['initState'] == 1) {
$num = 10;
}
else {
$num = PHP_INT_MAX;
}
echo $num;
My output is now working correctly: false9223372036854775807
What am I missing here?
Here is the #GET code:
#GET("getreleases.php")
Call<ReleaseModelResponse> getReleases(#Query("initState") boolean initState);
Appreciate any insight that can be provided here.
EDIT Actually, maybe my code is not working correctly in either case, which is why I have been looking closely at this problem for a while now. I noticed my activity was always loading more than 10 items so this must mean neither versions of the code work correctly for me.
Just to be sure, I checked my logs again when performing an action that results in initState being true, and this is what I see: true9223372036854775807
In the first version of your code, the if statement is checking if the value of $_GET['initState'] is "truthy". In PHP, any non-empty string, non-zero number, or non-null value is considered "truthy". So even though the value of $_GET['initState'] is "false", it is still considered "truthy" in the if statement; therefore $num is assigned the value of 10.
In the second version of your code, you are explicitly checking if the value of $_GET['initState'] is equal to 1. Since it is not equal to 1, the else block is executed and $num is assigned the value of PHP_INT_MAX.
It seems that you are using this code in a REST API and sending a boolean value in the query parameter, but in PHP, booleans are not directly passed in query parameters, instead they are passed as strings "true" or "false", so in the first version of your code, the value of $_GET['initState'] is "false" string and its considered truthy, but in the second version, the value of $_GET['initState'] is "false" string and you are comparing it with 1, which is not equal and it's not truthy.
You could try to change the if($_GET['initState'] == 1) to if($_GET['initState'] === "true") or if($_GET['initState'] == true), this will check for the boolean value and not the string.
Related
I can't understand why the last debugbar message is showing. Strangely enough $nest = 1, not true.
$nest = true;
$showcosts = false;
Debugbar::info($nest);
Debugbar::info($showcosts);
Debugbar::info("x" . $nest . "x");
Debugbar::info("x" . $showcosts . "x");
Debugbar::info($nest == true);
Debugbar::info($showcosts);
if ($showcosts && $nest) {
Debugbar::info("this should never show");
}
returns this:
true
false
x1x
xfalsex
true
false
this should never show
I'd like the last debugbar message not to show as only one of the conditions in the if statement is true.
I'm using Laravel 5.4 with PHP 7.
As mentioned in the comment above:
The string value of a boolean true is 1 which is why you get x1x when you concatenate strings. However the string value of a false should be the empty string and not the string false which means you should also see a xx outputed (not xfalsex) .
Make 100% sure that $showcosts is a boolean and not a string that contains the word false because that behaviour is consistent with checking a false string.
In addition as #NinoŠkopac pointed out, the simple if ($variable) check will be true for any value of $variable which is considered "truthy". This includes non-null objects, non-empty arrays, non-zero numbers and non-empty strings as well as the boolean true. In this case the string "false" is a non-empty string and is therefore a "truthy" value.
If you're getting values from a request query string or post (e.g. via $_POST or $_GET) you must keep in mind that all values are strings.
For this purpose PHP has a set of filtering functions that aim to help with this. There's filter_var and filter_input (and others, check the manual for more details).
You can use filter_var on any variable, for example in your case you could do:
$nest = filter_var($nest,FILTER_VALIDATE_BOOLEAN);
$showcosts = filter_var($showcosts ,FILTER_VALIDATE_BOOLEAN);
The FILTER_VALIDATE_BOOLEAN filter:
Returns TRUE for "1", "true", "on" and "yes". Returns FALSE otherwise.
You can also use filter_input to filter input directly.
For example if you have an input entry $_POST["nest"] then you can do:
filter_input(INPUT_POST,"nest",FILTER_VALIDATE_BOOLEAN);
This will also save you from an isset check.
I have very basic question regarding return value of a function, and checking the variable value.
function test($var1, $var2){
if ($var1 == $var2){
$var3 = "abc";
return $var3;
}
return false
}
$value = test($var1, $var2);
if ($value){
echo "Value is".$value; //should output abc.
} else {
echo "Not equal";
}
Is it ok to either return a value or return false? For example I am not returning TRUE, it is ok?
When i call the function, i store the return value in a variable $value. How can i check the function did return the $var3? Which of the if condition should be used?
if (!empty($value)) or if (isset($value)) or if ($value) or if (value != false)
Yes, it is common practice in PHP to return FALSE as an indicator of an error condition. (What constitutes an error is your own decision and depends on what the function is supposed to do.)
However, since PHP automatically casts values to Boolean that are of another type (like the empty string or 0, which evaluate to FALSE as well), you should do an explicit check for FALSE like this:
if ($value !== FALSE) ...
As Felix Kling notes in the comments, this is called "strict comparison" (or "identity comparison"). It checks if a value is identical to FALSE, where as != FALSE, == FALSE and if ($value) only check if a value could be interpreted as FALSE.
I'm not a PHP developer, but I don't think your first approach works.
There are other things than the boolean value false interpreted as false:
When converting to boolean, the following values are considered FALSE:
* the boolean FALSE itself
* the integer 0 (zero)
* the float 0.0 (zero)
* the empty string, and the string "0"
* an array with zero elements
* an object with zero member variables (PHP 4 only)
* the special type NULL (including unset variables)
* SimpleXML objects created from empty tags
http://php.net/manual/en/language.types.boolean.php
It's perfectly OK to return different data types.
If you want to check against false, use: if ($value !== false). If you get lost which condition to use, this will clarify it: http://www.php.net/manual/en/types.comparisons.php
Your function returns false, so I would go with that check: if ($value != false)
$var3 = "abc";
return $var3;
That's pointless. You're returning a value, not a variable. return "abc"; is perfectly fine.
Is it ok to either return a value or return false?
Yes, that's perfectly fine for a simple case such as this.
How can i check the function did return the $var3?
As said above, the function returns the value "abc", not $var3. You're saving it in a new variable $value. This variable is definitely set (you just created it right there), so there's no need for isset or empty. Just test whether its value is true or false (or whatever else you want to test for). So the way you're doing it in fine.
Yes, you can return pretty much anything from the function, or you can just "return" without returning anything. In your example, you'll get a string or "false" in return.
To check for false you either do if (!$variable) or if ($variable===false). Zero will return true if you do "if ($variable==false)" due to auto casting of zero to false (and any other positive number to true). Three "===" makes sure it really is false and nothing else. The isset($var) checks for existance, not value - and is not applicable to your example since your function will return a value or "false" and thus always exists.
The only right answer here is: it depends.
I always ask myself this question when creating a function like this. To answer it, I analyze what the function does, instead of what it returns.
For instance, if I have a getter, I expect to get a value, or nothing. In this case I often return null when nothing is found/something went wrong.
A test function like yours should return a boolean at all times, in my opinion. Returning a variable when you're checking for something to be true or false is semantically incorrect, I think.
Aside from the semantics: returning 0, false or null does not really matter when you're checking it with if (test($var1, $var2)), since it will all work the same. However, if you want some finer details, you want to do an identity check (===) rather than a equality check. In PHP this is sometimes the case, for instance strpos can return 0 or false, 0 being a match is found, and false is not. Therefore the following would fail:
// returns 0, which is casted to false, so the 'else' part is executed
if (strpos('a', 'abc')) {
// 'abc' contains 'a'
} else {
// 'abc' does not contain 'a'
}
So, long story short: it depends...
I have a question regarding bools in php. I have a stored mysql proc that is returning a boolean. When this value is grabbed on the php side it displays the value as being a 0 or 1. This all seems fine to me and I have read in the php manual that php will interpret a 0 or 1 as false or true at compile time but this does not seem to be the case to me. I have gone a step further and casted my returned value with (bool) but this still does not seem to work.
My if statements are not properly firing because of this. Does anyone know what is going on? Thanks for the help.
MySQL does not have a proper BOOL or BOOLEAN data types. They are declared as synonyms for TINYINT(1). Your procedure will return 0 or 1, which being on non-PHP ground will get transformed into a string in PHP land, so in PHP you have the strings '0' and '1'.
It is weird however that boolean casting does not convert them to the appropriate booleans. You may have some other bugs in your code.
Are you trying to cast the direct result from the query? Because that one is probably an array and:
var_dump((bool) array('0')); // true
Maybe this is your problem. Inspect the returned result.
It sounds like the boolean value is being returned as a string.
Try something like this:
$your_bool = $field_value === "0" ? false : true;
Using the script below. (You'll have to add HTML line break tags before the word "Boolean" inside the left quote to make the output look like my sample; when I do, Firefox interprets them, making the format look strange).
You'll see that the second line produces a null value which MySQL sees as something different from 0 or 1; for TINYINT it stores the PHP true value correctly but nothing for the PHP false, since a null value has no meaning for TINYINT.
Line four shows type casting with (int) is a way to insure that both PHP true and false are stored to MySQL TINYINT Boolean fields. Retrieving the resultant integers from MySQL into PHP variables works since integers are implicitly cast when assigned to PHP Boolean variables.
echo "Boolean true=".true;
echo "Boolean false=".false;
echo "Boolean (int)true=".(int)true;
echo "Boolean (int)false=".(int)false;
Here's the output from PHP 5.3.1 for MySQL 5.1.41:
Boolean true=1
Boolean false=
Boolean (int)true=1
Boolean (int)false=0
Oh! And PHP Boolean literals may be all lowercase or uppercase with the same result... try it yourself.
I use a helpful function "to_bool" for anything I'm not sure of the type of:
function to_bool($value, $default = false)
{
if (is_bool($value)) {
return $value;
}
if (!is_scalar($value)) {
return $default;
}
$value = strtolower($value);
if (strpos(";1;t;y;yes;on;enabled;true;", ";$value;") !== false) {
return true;
}
if (strpos(";0;f;n;no;off;disabled;false;null;;", ";$value;") !== false) {
return false;
}
return $default;
}
Then:
if (to_bool($row['result'])) { ... }
EDIT: I believe my confusion is probably created by this code at the top of the page in which I'm testing for the value of the option... This creates a shortcut method to refer to the option without using the get_option('option') method...
global $options;
foreach ($options as $value) {
if (get_settings( $value['id'] ) === FALSE) {
$$value['id'] = $value['std'];
} else {
$$value['id'] = get_settings( $value['id'] );
}
}
And so when I set the value of a variable, $myvar, via a checkbox checked in my theme's options panel and click save, then view my options.php in worpdress, the value of the variable is
true
And when I do a lookup on this variable using
if($myvar == "true")
It passes.
However, when I set the value directly via the update_options() method, like so...
$mvar = true;
update_option('myvar', $myvar);
The value changes from true to 1
And when I do the same comparison as before, if($myvar == "true"), it now fails. It is no longer "true".
What am I missing? (1) why is "true" and 1, not evaluating the same and (2) What is the update_option method doing to the value of myvar to change the value from true to 1?
Try
if($myvar == true)
and
$myvar = true;
TRUE and FALSE are PHP's built in boolean variables which are much more universal than a true string.
About the update_option. It might not be that the option is changing it to 1. Instead it might be that the when it is inserting it into the database, it inserts it as the string "true". Then, when it comes back it is converted to the boolean value true, which when printed is 1
Try
if ($myvar)
Don't test whether things "equal" true, they are either true or they aren't.
You should change your first test to if($myvar == true) or simply if ($myvar). PHP has some strange rules for what is "true"; Generally, strings evaulate to true, except the special cases of "0" and an empty string "", which type-cast to false.
In your specific example, if ($myvar == "true"):
If $myvar contains a boolean, the expression will evaluate as (bool) == (bool)"true", or (bool) == true
If $myvar contains an integer, it's cast to a string and compared against the string "true"; so your test is failing, because "1" != "true".
If $myvar is a string, string comparison takes place and suddenly only the literal string "true" will successfully compare.
I would guess 2nd and 3rd cases are in effect: Wordpress is likely setting $myval to the string "true" when the from is posted back, so your test passes. When you manually specify boolean true, Wordpress must be converting it to an integer, and then integer comparison takes place and fails, because the integer 1 will be cast to string "1" when compared against "true".
You are doing a loose comparison between the integer 1 and the string 'true'. For this PHP will translate the string to a number. 'test' as a number is 0:
var_dump((int) 'true'); // int(0)
And since 0 is not equal to 1, the comparison will return false.
Like some other answers already correctly pointed out, you should test against the boolean literal TRUE or true. If one operator in a equality check is a boolean, PHP will convert the other operator to a boolean too, which, for the number 1, will give
var_dump((bool) 1); // boolean(true)
And then your test will pass, because true is equal to true.
Check out the Type Comparison Table to understand how PHP juggles types when testing for equality.
As for what check_update does to your boolean, check out the function description:
(mixed) (required) The NEW value for this option name. This value can be a string, an array, an object or a serialized value.
So, no boolean allowed. I've tried briefly to find out from the sourcecode where the conversion takes place, but since WP is a mess to me, couldn't find it. Like someone else suggested, it probably happens when storing it to the database and then getting it back.
"true" is a string, and all strings evaulates to the boolean 1 (try casting (bool) $string. true on the other hand, without quotes, is a boolean and will evaluate to 1.
I'm attempting to troubleshoot a problem, and need to understand what this if statement is saying:
if ($confirmation = $payment_modules->confirmation()) {
All the resources I can find only show if statements with double equal signs, not single. Is this one of the shorthand forms of a php if? What is it doing?
(If it's actually wrong syntax, changing it to a double equal sign doesn't resolve the problem. As-is, in some scenarios it does return true. In the scenario I'm troubleshooting, it doesn't return true until after I refresh the browser.)
Any help is greatly appreciated!!!
It's a form of shorthand, which is exactly equivalent to this:
$confirmation = $payment_modules->confirmation();
if ($confirmation) {
}
This will first assign the value of $payment_modules->confirmation() to $confirmation. The = operator will evaluate to the new value of $confirmation.
This has the same effect as writing:
$confirmation = $payment_modules->confirmation();
if ($confirmation) {
// this will get executed if $confirmation is not false, null, or zero
}
The code works because an assignment returns the value assigned, so if $payment_modules->confirmation() is true, $confirmation will be set to true, and then the assignment will return true. Same thing for false.
That's why you can use a command to assign to many variables, as in a = b = 0. Assigns zero to b and returns that zero. Therefore, it becomes a = 0. And a receives zero and it will return that zero, which can or can not be used.
Sometimes people like to do an assignment and then check if the assignment went through okay. Pair this up with functions that return false (or equivalent) on failure, and you can do an assignment and a check at the same time.
In order to understand this, remember that assignments are a kind of expression, and so (like all expressions) have a return value. That return value is equal to whatever got put into the variable. That is why you can do something like
a = b = c = 0;
to assign all of those variables at the same time.
= means assignment ( $a = 1 ), == is for comparison ( true == false is false ). I think in your example it should use = because it assigns it to the return value of confirmation, which should be something that evaluates to true.
Try doing a var_dump:
var_dump( $payment_modules->confirmation() );
See what boolean it evaluates to, and from there you can troubleshoot. Post more code if you want more help.
class test() {
public function confirmation() { return true; }
}
$boolean = test::confirmation();
var_dump( $boolean );
Will equate to true