Consider this PHP code:
<?php
$xmlString =
'<'.'?xml version="1.0" encoding="UTF-8"?'.'>' .
'<rootEl>' .
'<a attrA="valA">xxx</a>' .
'<b attrB="valB"/>' .
'<c>oink</c>' .
'<d/>'.
'<e>' .
'<f>zzz</f>' .
'</e>' .
'</rootEl>';
$xml = simplexml_load_string( $xmlString );
foreach ( $xml->children() as $child ) {
echo "\$CHILD [" . $child->getName() . "]: " . $child->asXML();
echo "\n";
$insideIf1 = false;
if ($child) { $insideIf1 = true; }
$insideIf2 = false;
if (true == $child) { $insideIf2 = true; }
$insideIf3 = false;
if ((boolean)$child) { $insideIf3 = true; }
echo " - if(\$CHILD) return \"true\"; else return \"false\"; : " . (($insideIf1)?"true":"false")."\n";
echo " - if(true == \$CHILD) return \"true\"; else return \"false\"; : " . (($insideIf2)?"true":"false")."\n";
echo " - if((boolean)\$CHILD) return \"true\"; else return \"false\"; : " . (($insideIf3)?"true":"false")."\n";
echo " - ((\$CHILD)?\"true\":\"false\"): " . (($child)?"true":"false")."\n";
echo " - ((true == \$CHILD)?\"true\":\"false\"): " . ((true == $child)?"true":"false")."\n";
echo " - (((boolean)\$CHILD)?\"true\":\"false\"): " . (((boolean)$child)?"true":"false")."\n";
echo "\n";
}
As per PHP documentation (online, see http://php.net/manual/en/control-structures.if.php):
As described in the section about expressions, expression is evaluated
to its Boolean value. If expression evaluates to TRUE, PHP will
execute statement, and if it evaluates to FALSE - it'll ignore it.
More information about what values evaluate to FALSE can be found in
the 'Converting to boolean' section.
The "converting to boolean" section of this explanation states:
Converting to boolean
When converting to boolean, the following values are considered FALSE:
...omissis...
SimpleXML objects created from empty tags
If you execute the code above, these are the results on my PHP 5.5.9-1ubuntu4.5 (cli):
$CHILD [a]: <a attrA="valA">xxx</a>
- if($CHILD) return "true"; else return "false"; : true
- if(true == $CHILD) return "true"; else return "false"; : true
- if((boolean)$CHILD) return "true"; else return "false"; : true
- (($CHILD)?"true":"false"): true
- ((true == $CHILD)?"true":"false"): true
- (((boolean)$CHILD)?"true":"false"): true
$CHILD [b]: <b attrB="valB"/>
- if($CHILD) return "true"; else return "false"; : true
- if(true == $CHILD) return "true"; else return "false"; : false
- if((boolean)$CHILD) return "true"; else return "false"; : true
- (($CHILD)?"true":"false"): true
- ((true == $CHILD)?"true":"false"): false
- (((boolean)$CHILD)?"true":"false"): true
$CHILD [c]: <c>oink</c>
- if($CHILD) return "true"; else return "false"; : false
- if(true == $CHILD) return "true"; else return "false"; : true
- if((boolean)$CHILD) return "true"; else return "false"; : false
- (($CHILD)?"true":"false"): false
- ((true == $CHILD)?"true":"false"): true
- (((boolean)$CHILD)?"true":"false"): false
$CHILD [d]: <d/>
- if($CHILD) return "true"; else return "false"; : false
- if(true == $CHILD) return "true"; else return "false"; : false
- if((boolean)$CHILD) return "true"; else return "false"; : false
- (($CHILD)?"true":"false"): false
- ((true == $CHILD)?"true":"false"): false
- (((boolean)$CHILD)?"true":"false"): false
$CHILD [e]: <e><f>zzz</f></e>
- if($CHILD) return "true"; else return "false"; : true
- if(true == $CHILD) return "true"; else return "false"; : false
- if((boolean)$CHILD) return "true"; else return "false"; : true
- (($CHILD)?"true":"false"): true
- ((true == $CHILD)?"true":"false"): false
- (((boolean)$CHILD)?"true":"false"): true
Children elements "b" and "d" ARE empty, therefore I was expecting "false", and "a", "c", "e" ARE NOT empty, so I was expecting "true".
As is comes out, that statement in PHP documentation is absolutely NOT true, and the behaviour doesn't even seem consistent: implicit or explicit casts to boolean don't behave the same way (see case of element "c"), and if the bare SimpleXML object is used as "if" conditional expression (both "if" and ternary operator), somehow that expression evaluates differently from a cast to boolean.
Does anyone have an idea of what's going on here?
First of all, let's discard some of your code.
foreach ( $xml->children() as $child ) {
echo "\$CHILD [" . htmlspecialchars($child->getName()) . "]: " . htmlspecialchars($child->asXML());
echo "\n";
$insideIf1 = false;
if ($child) { $insideIf1 = true; }
$insideIf2 = false;
if (true == $child) { $insideIf2 = true; }
$insideIf3 = false;
if ((boolean)$child) { $insideIf3 = true; }
var_dump($child);
// echo intval($child)."\n";
echo 'VALUE EVALUATES TO: '. $child."\n";
echo " - if(\$CHILD) return \"true\"; else return \"false\"; : " . (($insideIf1)?"true":"false")."\n";
echo " - if(true == \$CHILD) return \"true\"; else return \"false\"; : " . (($insideIf2)?"true":"false")."\n";
echo " - if((boolean)\$CHILD) return \"true\"; else return \"false\"; : " . (($insideIf3)?"true":"false")."\n";
// This part evaluated exactly same as above. So no need to make confusion
echo "\n";
}
Next:
First and third test
Those are basically same. Object is considered true, if it has properties. So basically xml tag without attributes has no properties (just var_dump them).
Objects without properties (does not have attributes BUT NOTE THEY CAN have value - which is returned by iterator) considered false: c, d
Second test
This test on the other hand does not test object itself. But all values returned by it from casting to: int, bool and string.
One of those tests calls for __toString magic method. Which returns value. Then it evaluates to true (Elements a and c)
So its not random, but has special rules while considering it true or false.
Forgot to add
Note: SimpleXML has made a rule of adding iterative properties to most methods. They cannot be viewed using var_dump() or anything else which can examine objects.
This "strange" behaviour is result of it implementing inerators.
Edit:
As you stated in comment what made you analyze this behaviour. I think that you should never chose to check SimpleXML objects on if($obj) basis.
Instead, use SimpleXML::attributes() or strval to do all checks. Then you're sure what you're checking.
Edit2:
$xmlObject is considered true (is not empty) if it has Properties OR Chilren (subnodes) (that works fine)
To check if object has value you cast it to string.
In this case, empty does not mean if it has value, only if it has children or properties.
Related
I have array look like this.
$setLogic = array(array("Conj"=>null,"Topic"=>True),array("Conj"=>"Or","Topic"=>True),array("Conj"=>"Or","Topic"=>false),
I try to build a IF statement with the dynamicly with this way.
foreach($setLogic as $value){
echo $value['Conj'].(int)$value['Topic'];
if($value['Conj'].(int)$value['Topic'] == true){
$getBoolean[] = true;
}
else{
$getBoolean[] = false;
}
I just need something like this.
(true or true or false) and return true or false
I found my answer with my self.
It's look like this.
$abc= '';
foreach($setLogic2 as $key => $value){
$abc.= $value['Conj'].' '.(int)$value['Topic'].' ';
}
//$abc = "0 And 1 And 1";
if(eval("return $abc;") == true) {
echo 'true boolean';
}
else if(eval("return $abc;") == false){
echo 'false boolean';
}
else{
echo 'none';
}
Ok i will re formulate my answer....
You want to dynamically evaluate an array which contains for each subarray
* a verb : "and" or "or"
* a value "true or "false"
Quicker and most dirty way is to use eval().
* build your conditions as a string (replace "and" by "&&" and "or" by "||"
'true || true && false'
then put the result in a variable and evaluate
eval('$result = (true || true && false);');
var_dump($result);
This works for sure...
I have a response from aws like this with boolean value :
$string=/vasff/fdsfsdf:boolean true
and $string=/sadasff/fdsfsdf:boolean false
in their documentation, they had written a response in boolean.// Success? (Boolean, not a CFResponse object).
Their documentaion is https://docs.aws.amazon.com/aws-sdk-php/v2/api/class-Aws.S3.S3Client.html#_doesObjectExist
how to match value is true or false? I tried this code but it always returns true.
if(stripos($string, true) !== false){
echo "true";
}
else{
echo "false";
}
EDIT
Just wanted to thank everyone for their good answers on this.
This code is working fine for aws s3 bucket response.
if($response == FALSE){
return false; }else{
return true;
}
if you mean by this :
$string=/vasff/fdsfsdf:boolean true
this :
$string='/vasff/fdsfsdf:boolean true';
you can use this code : use true with double quote
$string='/vasff/fdsfsdf:boolean true';
if(stripos($string, "true") !== false){
echo "true";
}
else{
echo "false";
}
Edit :
use your function paramaters intead of ....
if(doesObjectExist(....)){
echo "true";
}else{
echo "false";
}
You can try this:
preg_match_all("/:boolean (.+)/", $string, $mc);
if(isset($mc[1]) && isset($mc[1][0])){
if($mc[1][0] == "false"){
echo $mc[1][0] . " == false";
}
else{
echo $mc[1][0] . " == true";
}
}
$a = 101;
if (isset($a) && is_int($a) && in_array($a, range(1, 100))) {
echo "TRUE";
} else echo "FALSE";
Why this condition returns FALSE as it should be while this IF:
if (isset($argv[1]) && is_int($argv[1]) && in_array($argv[1], range(1, 100))) {
echo "TRUE";
} else echo "FALSE";
returns also FALSE where value passed as first parameter is 50 which is in range??? PHP-CLI is 7.0.9-TS-VC14-x64
Thanks in advance
argv[1] is, by default, an string.
Use is_numeric() instead of is_int(), and convert (or cast) it to integer value before checking if in the range.
// var_dump($argv); // ...if you want to check $argv types and values.
if (isset($argv[1]) && is_numeric($argv[1]) && in_array(intval($argv[1]), range(1, 100))) {
echo "TRUE";
}
else {
echo "FALSE";
}
CAUTION: is_numeric() also returns TRUE in case of a float value!
I wrote this REALLY simple code:
$foo=false;
echo $foo;//It outputs nothing
Why? Shouldn't it output false? What can I do to make that work?
false evaluates to an empty string when printing to the page.
Use
echo $foo ? "true" : "false";
The string "false" is not equal to false. When you convert false to a string, you get an empty string.
What you have is implicitly doing this: echo (string) $foo;
If you want to see a "true" or "false" string when you echo for tests etc you could always use a simple function like this:
// Boolean to string function
function booleanToString($bool){
if (is_bool($bool) === true) {
if($bool == true){
return "true";
} else {
return "false";
}
} else {
return NULL;
}
}
Then to use it:
// Setup some boolean variables
$Var_Bool_01 = true;
$Var_Bool_02 = false;
// Echo the results using the function
echo "Boolean 01 = " . booleanToString($Var_Bool_01) . "<br />"; // true
echo "Boolean 02 = " . booleanToString($Var_Bool_02) . "<br />"; // false
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What is the PHP ? : operator called and what does it do?
i was interviewed with a very basic question of PHP which was like:
echo ('True' ? (true ? 't' : 'f') : 'False');
Can Someone explain the details of the output it will yield?
Thanks
This will echo t.
Because of first it will check the first condition that will give true.
and after that in next condition it again give true and execute the first condition that is t.
In if and else condition it will be write as follow:
if('True') { //condition true and go to in this block
if(true){ //condition true and go to in this block
echo 't'; // echo t
} else {
echo 'f';
}
} else {
echo 'False';
}
Looking at this version should make it clear:
if('True'){ // evaluates true
if(true){ // evaluates tre
echo 't'; // is echo'd
}else{
echo 'f';
}
}else {
echo 'False';
}
A non-empty string is considered a truthy value except the string "0". PHP evaluates
'True' ? (true ? 't' : 'f') : 'False'
from left to right as follows:
The expression 'True' is evaluated as a boolean true
Next, the expression following the ? is evaluated
The expression true is... true!
The expression following the ? is returned, which is t
Surprisingly, you'll still get t if the expression was:
echo 'False' ? (true ? 't' : 'f') : 'False'
As 'True' is Evaluated as true
if('True'){
if(true){
echo 't';
}else{
echo 'f';
}
}else{
echo 'False';
}
The inner bracket will be executed first true?'t':'f' it will return 't' that is a string
Now outer condition will check for echo ('True' ? 't' : 'False'). Here 'True' is a "non empty string"(implicitly casted to TRUE), so it evaluate to true, and will return 't'.
Final code will be echo ('t') which will simply echo t
echo ( // will echo the output
'True'? // first ternary operation 'True' is considered true
(true? 't':'f') // will go here for the second ternary operation
// true is also evaluated as true so it will echo 't'
: 'False'); // never goes here
This:
'True'?(true?'t':'f'):'False'
May be written as
// Will always be true if String is not an Empty string.
if('True'){
// if (true) will always enter
if(true){
// t will be the output
echo 't';
}else{
echo 'f';
}
else {
echo 'False';
}