Bitwise operations on boolean values - php

From my knowledge, bitwise operators perform a check on all corresponding bits, as in:
echo 64 | 32; //prints 96
echo 'a' & 'b'; //prints `
While conditional && and || operators perform operations on boolean values:
echo (int)(true && false); //prints: 0
echo (int)(true || false); //prints: 1
When I (in my head) want to predict the result of a bitwise operation, I first convert the values into their binary representation (which depends on the datatype). After this, I compare it bit-for-bit, and convert the result into the suitable output type (which I suppose is determined by the operands). Although at one point, I tried doing the same with boolean values, which (from my knowledge) only consists of one bit in memory, making true corresponding to 1₂, and making false corresponding to 0₂ (in binary). Performing bitwise operations on these values should therefore produce a similar result as with && and ||, right? To show you what I mean:
true & false => 1₂ & 0₂ => 0₂ => false
true | false => 1₂ | 0₂ => 1₂ => true
~true => ~1₂ => 0₂ => false
(Not including xor, as there's no corresponding conditional boolean operator.)
To me, it looks like the behaviour should be really equivalent to conditional operators:
true && false => false
true || false => true
!true => false
So therefore, I set this code up to test it:
echo "true AND false: " . ((true && false) ? "1" : "0") . "<br />\n";
echo "true OR false: " . ((true || false) ? "1" : "0") . "<br />\n";
echo "NOT true: " . ((!true) ? "1" : "0") . "<br />\n";
echo "<br />\n";
echo "true BITAND false: " . ((true & false) ? "1" : "0") . "<br />\n";
echo "true BITOR false: " . ((true | false) ? "1" : "0") . "<br />\n";
echo "BITNOT true: " . ((~true) ? "1" : "0") . "<br />\n";
It gave me the following output:
true AND false: 0
true OR false: 1
NOT true: 0
true BITAND false: 0
true BITOR false: 1
Fatal error: Unsupported operand types in C:\Abyss Web Server\htdocs\handler.php on line 21
So from this, I have two questions:
What's the point with && and ||, if we (as it seems) can use & and | on boolean values instead?
Why can't I do ~true (or with other words, why aren't boolean values supported)? To me, it sounds logical that ~true returns false.
I did come up with one thing, being that && and || will (sometimes) cast the values into bool and thereafter return the correct results, if we (by mistake) would happen to pass a value that's not of type bool. But to solve that, can't we just do a cast first? Such as:
if ((bool)$foo & (bool)$bar) { ...
It feels like I'm missing a major piece here that changes everything... But just in case I didn't, I included as much info as I could. Could someone make me understand this a bit better, by answering my two questions? I'm pretty confused at this point, and I've been thinking about this for quite some time.

Answer 1
Parts of a boolean expressions (||, &&, !, ...) are only evaluated if needed (from left to right):
if ($a | func()) { } // func is always called
if ($a || func()) { } // func is not called if $a is true,
// because expression is true whatever func will return
if ($a && func()) { } // func is not called if $a is false,
// because expression is false whatever func will return
func() || exit(); // exit() will be called if func() returns false
Take a look at the documentation: http://php.net/manual/en/language.operators.logical.php
Answer 2
~true seems not to be meaningful: true is 0x00...01 and ~true will be 0xff...fe and not false 0x000...0:
var_dump(~((int)true)); // prints: int(-2)
echo dechex(~((int)true)); // prints: fffffffffffffffe
Use !-operator instead:
var_dump(!true); // prints: bool(false)
Résumé
Use bitwise operators only if you need to change bits.

true and false boolean flags, albeit being stored in memory as 32-bit or 64-bit values, should be considered just as two-states boolean values. You'll end up using it only on brach guards so you should not make arithmetic over them. && and || evaluates as boolean flags, bitwise operators & and | evaluates as the same of the operands (e.g. int & int evaluates as int, int && int evaluates as boolean).
the story is:
use && and || when you have to take decisions over some conditions. Use & and | to perform boolean arithmetic over values.
that's C++
C doesn't have any built-in boolean values so any non zero value is a true, and zero is false.

Related

How is it better to test return value of preg_match in PHP? [duplicate]

What is the difference between == and ===?
How exactly does the loosely == comparison work?
How exactly does the strict === comparison work?
What would be some useful examples?
Difference between == and ===
The difference between the loosely == equal operator and the strict === identical operator is exactly explained in the manual:
Comparison Operators
Example
Name
Result
$a == $b
Equal
TRUE if $a is equal to $b after type juggling.
$a === $b
Identical
TRUE if $a is equal to $b, and they are of the same type.
Loosely == equal comparison
If you are using the == operator, or any other comparison operator which uses loosely comparison such as !=, <> or ==, you always have to look at the context to see what, where and why something gets converted to understand what is going on.
Converting rules
Converting to boolean
Converting to integer
Converting to float
Converting to string
Converting to array
Converting to object
Converting to resource
Converting to NULL
Type comparison table
As reference and example you can see the comparison table in the manual:
TRUE
FALSE
1
0
-1
"1"
"0"
"-1"
NULL
array()
"php"
""
TRUE
TRUE
FALSE
TRUE
FALSE
TRUE
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
TRUE
TRUE
FALSE
TRUE
1
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
0
FALSE
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
TRUE
FALSE
TRUE
TRUE
-1
TRUE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
"1"
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
"0"
FALSE
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
"-1"
TRUE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
NULL
FALSE
TRUE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
TRUE
TRUE
FALSE
TRUE
array()
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
TRUE
FALSE
FALSE
"php"
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
""
FALSE
TRUE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
TRUE
Strict === identical comparison
If you are using the === operator, or any other comparison operator which uses strict comparison such as !== or ===, then you can always be sure that the types won't magically change, because there will be no converting going on. So with strict comparison the type and value have to be the same, not only the value.
Type comparison table
As reference and example you can see the comparison table in the manual:
Strict comparisons with ===
TRUE
FALSE
1
0
-1
"1"
"0"
"-1"
NULL
array()
"php"
""
TRUE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
1
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
0
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
-1
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
"1"
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
"0"
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
"-1"
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
NULL
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
array()
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
"php"
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
""
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
Editor's note - This was properly quoted previously, but is more readable as a markdown table. This is not plagiarism
The operator == casts between two different types if they are different, while the === operator performs a 'typesafe comparison'. That means that it will only return true if both operands have the same type and the same value.
Examples:
1 === 1: true
1 == 1: true
1 === "1": false // 1 is an integer, "1" is a string
1 == "1": true // "1" gets casted to an integer, which is 1
"foo" === "foo": true // both operands are strings and have the same value
Warning: two instances of the same class with equivalent members do NOT match the === operator. Example:
$a = new stdClass();
$a->foo = "bar";
$b = clone $a;
var_dump($a === $b); // bool(false)
A picture is worth a thousand words:
PHP Double Equals == equality chart:
PHP Triple Equals === Equality chart:
Source code to create these images:
https://github.com/sentientmachine/php_equality_charts
Guru Meditation
Those who wish to keep their sanity, read no further because none of this will make any sense, except to say that this is how the insanity-fractal, of PHP was designed.
NAN != NAN but NAN == true.
== will convert left and right operands to numbers if left is a number. So 123 == "123foo", but "123" != "123foo"
A hex string in quotes is occasionally a float, and will be surprise cast to float against your will, causing a runtime error.
== is not transitive because "0"== 0, and 0 == "" but "0" != ""
PHP Variables that have not been declared yet are false, even though PHP has a way to represent undefined variables, that feature is disabled with ==.
"6" == " 6", "4.2" == "4.20", and "133" == "0133" but 133 != 0133. But "0x10" == "16" and "1e3" == "1000" exposing that surprise string conversion to octal will occur both without your instruction or consent, causing a runtime error.
False == 0, "", [] and "0".
If you add 1 to number and they are already holding their maximum value, they do not wrap around, instead they are cast to infinity.
A fresh class is == to 1.
False is the most dangerous value because False is == to most of the other variables, mostly defeating it's purpose.
Hope:
If you are using PHP, Thou shalt not use the double equals operator because if you use triple equals, the only edge cases to worry about are NAN and numbers so close to their datatype's maximum value, that they are cast to infinity. With double equals, anything can be surprise == to anything or, or can be surprise casted against your will and != to something of which it should obviously be equal.
Anywhere you use == in PHP is a bad code smell because of the 85 bugs in it exposed by implicit casting rules that seem designed by millions of programmers programming by brownian motion.
In regards to JavaScript:
The === operator works the same as the == operator, but it requires that its operands have not only the same value, but also the same data type.
For example, the sample below will display 'x and y are equal', but not 'x and y are identical'.
var x = 4;
var y = '4';
if (x == y) {
alert('x and y are equal');
}
if (x === y) {
alert('x and y are identical');
}
An addition to the other answers concerning object comparison:
== compares objects using the name of the object and their values. If two objects are of the same type and have the same member values, $a == $b yields true.
=== compares the internal object id of the objects. Even if the members are equal, $a !== $b if they are not exactly the same object.
class TestClassA {
public $a;
}
class TestClassB {
public $a;
}
$a1 = new TestClassA();
$a2 = new TestClassA();
$b = new TestClassB();
$a1->a = 10;
$a2->a = 10;
$b->a = 10;
$a1 == $a1;
$a1 == $a2; // Same members
$a1 != $b; // Different classes
$a1 === $a1;
$a1 !== $a2; // Not the same object
It's all about data types. Take a BOOL (true or false) for example:
true also equals 1 and
false also equals 0
The == does not care about the data types when comparing:
So if you had a variable that is 1 (which could also be true):
$var=1;
And then compare with the ==:
if ($var == true)
{
echo"var is true";
}
But $var does not actually equal true, does it? It has the int value of 1 instead, which in turn, is equal to true.
With ===, the data types are checked to make sure the two variables/objects/whatever are using the same type.
So if I did
if ($var === true)
{
echo "var is true";
}
that condition would not be true, as $var !== true it only == true (if you know what I mean).
Why would you need this?
Simple - let's take a look at one of PHP's functions: array_search():
The array_search() function simply searches for a value in an array, and returns the key of the element the value was found in. If the value could not be found in the array, it returns false. But, what if you did an array_search() on a value that was stored in the first element of the array (which would have the array key of 0)....the array_search() function would return 0...which is equal to false..
So if you did:
$arr = array("name");
if (array_search("name", $arr) == false)
{
// This would return 0 (the key of the element the val was found
// in), but because we're using ==, we'll think the function
// actually returned false...when it didn't.
}
So, do you see how this could be an issue now?
Most people don't use == false when checking if a function returns false. Instead, they use the !. But actually, this is exactly the same as using ==false, so if you did:
$arr = array("name");
if (!array_search("name", $arr)) // This is the same as doing (array_search("name", $arr) == false)
So for things like that, you would use the === instead, so that the data type is checked.
PHP Double Equals == :
In most programming languages, the comparison operator (==) checks, on the one hand, the data type and on the other hand the content of the variable for equality. The standard comparison operator (==) in PHP behaves differently. This tries to convert both variables into the same data type before the comparison and only then checks whether the content of these variables is the same. The following results are obtained:
<?php
var_dump( 1 == 1 ); // true
var_dump( 1 == '1' ); // true
var_dump( 1 == 2 ); // false
var_dump( 1 == '2' ); // false
var_dump( 1 == true ); // true
var_dump( 1 == false ); // false
?>
PHP Triple Equals === :
This operator also checks the datatype of the variable and returns (bool)true only if both variables have the same content and the same datatype. The following would therefore be correct:
<?php
var_dump( 1 === 1 ); // true
var_dump( 1 === '1' ); // false
var_dump( 1 === 2 ); // false
var_dump( 1 === '2' ); // false
var_dump( 1 === true ); // false
var_dump( 1 === false ); // false
?>
Read more in What is the difference between == and === in PHP
You would use === to test whether a function or variable is false rather than just equating to false (zero or an empty string).
$needle = 'a';
$haystack = 'abc';
$pos = strpos($haystack, $needle);
if ($pos === false) {
echo $needle . ' was not found in ' . $haystack;
} else {
echo $needle . ' was found in ' . $haystack . ' at location ' . $pos;
}
In this case strpos would return 0 which would equate to false in the test
if ($pos == false)
or
if (!$pos)
which is not what you want here.
Variables have a type and a value.
$var = "test" is a string that contain "test"
$var2 = 24 is an integer vhose value is 24.
When you use these variables (in PHP), sometimes you don't have the good type.
For example, if you do
if ($var == 1) {... do something ...}
PHP have to convert ("to cast") $var to integer. In this case, "$var == 1" is true because any non-empty string is casted to 1.
When using ===, you check that the value AND THE TYPE are equal, so "$var === 1" is false.
This is useful, for example, when you have a function that can return false (on error) and 0 (result) :
if(myFunction() == false) { ... error on myFunction ... }
This code is wrong as if myFunction() returns 0, it is casted to false and you seem to have an error. The correct code is :
if(myFunction() === false) { ... error on myFunction ... }
because the test is that the return value "is a boolean and is false" and not "can be casted to false".
<?php
/**
* Comparison of two PHP objects == ===
* Checks for
* 1. References yes yes
* 2. Instances with matching attributes and its values yes no
* 3. Instances with different attributes yes no
**/
// There is no need to worry about comparing visibility of property or
// method, because it will be the same whenever an object instance is
// created, however visibility of an object can be modified during run
// time using ReflectionClass()
// http://php.net/manual/en/reflectionproperty.setaccessible.php
//
class Foo
{
public $foobar = 1;
public function createNewProperty($name, $value)
{
$this->{$name} = $value;
}
}
class Bar
{
}
// 1. Object handles or references
// Is an object a reference to itself or a clone or totally a different object?
//
// == true Name of two objects are same, for example, Foo() and Foo()
// == false Name of two objects are different, for example, Foo() and Bar()
// === true ID of two objects are same, for example, 1 and 1
// === false ID of two objects are different, for example, 1 and 2
echo "1. Object handles or references (both == and ===) <br />";
$bar = new Foo(); // New object Foo() created
$bar2 = new Foo(); // New object Foo() created
$baz = clone $bar; // Object Foo() cloned
$qux = $bar; // Object Foo() referenced
$norf = new Bar(); // New object Bar() created
echo "bar";
var_dump($bar);
echo "baz";
var_dump($baz);
echo "qux";
var_dump($qux);
echo "bar2";
var_dump($bar2);
echo "norf";
var_dump($norf);
// Clone: == true and === false
echo '$bar == $bar2';
var_dump($bar == $bar2); // true
echo '$bar === $bar2';
var_dump($bar === $bar2); // false
echo '$bar == $baz';
var_dump($bar == $baz); // true
echo '$bar === $baz';
var_dump($bar === $baz); // false
// Object reference: == true and === true
echo '$bar == $qux';
var_dump($bar == $qux); // true
echo '$bar === $qux';
var_dump($bar === $qux); // true
// Two different objects: == false and === false
echo '$bar == $norf';
var_dump($bar == $norf); // false
echo '$bar === $norf';
var_dump($bar === $norf); // false
// 2. Instances with matching attributes and its values (only ==).
// What happens when objects (even in cloned object) have same
// attributes but varying values?
// $foobar value is different
echo "2. Instances with matching attributes and its values (only ==) <br />";
$baz->foobar = 2;
echo '$foobar' . " value is different <br />";
echo '$bar->foobar = ' . $bar->foobar . "<br />";
echo '$baz->foobar = ' . $baz->foobar . "<br />";
echo '$bar == $baz';
var_dump($bar == $baz); // false
// $foobar's value is the same again
$baz->foobar = 1;
echo '$foobar' . " value is the same again <br />";
echo '$bar->foobar is ' . $bar->foobar . "<br />";
echo '$baz->foobar is ' . $baz->foobar . "<br />";
echo '$bar == $baz';
var_dump($bar == $baz); // true
// Changing values of properties in $qux object will change the property
// value of $bar and evaluates true always, because $qux = &$bar.
$qux->foobar = 2;
echo '$foobar value of both $qux and $bar is 2, because $qux = &$bar' . "<br />";
echo '$qux->foobar is ' . $qux->foobar . "<br />";
echo '$bar->foobar is ' . $bar->foobar . "<br />";
echo '$bar == $qux';
var_dump($bar == $qux); // true
// 3. Instances with different attributes (only ==)
// What happens when objects have different attributes even though
// one of the attributes has same value?
echo "3. Instances with different attributes (only ==) <br />";
// Dynamically create a property with the name in $name and value
// in $value for baz object
$name = 'newproperty';
$value = null;
$baz->createNewProperty($name, $value);
echo '$baz->newproperty is ' . $baz->{$name};
var_dump($baz);
$baz->foobar = 2;
echo '$foobar' . " value is same again <br />";
echo '$bar->foobar is ' . $bar->foobar . "<br />";
echo '$baz->foobar is ' . $baz->foobar . "<br />";
echo '$bar == $baz';
var_dump($bar == $baz); // false
var_dump($bar);
var_dump($baz);
?>
All of the answers so far ignore a dangerous problem with ===. It has been noted in passing, but not stressed, that integer and double are different types, so the following code:
$n = 1000;
$d = $n + 0.0e0;
echo '<br/>'. ( ($n == $d)?'equal' :'not equal' );
echo '<br/>'. ( ($n === $d)?'equal' :'not equal' );
gives:
equal
not equal
Note that this is NOT a case of a "rounding error". The two numbers are exactly equal down to the last bit, but they have different types.
This is a nasty problem because a program using === can run happily for years if all of the numbers are small enough (where "small enough" depends on the hardware and OS you are running on). However, if by chance, an integer happens to be large enough to be converted to a double, its type is changed "forever" even though a subsequent operation, or many operations, might bring it back to a small integer in value. And, it gets worse. It can spread - double-ness infection can be passed along to anything it touches, one calculation at a time.
In the real world, this is likely to be a problem in programs that handle dates beyond the year 2038, for example. At this time, UNIX timestamps (number of seconds since 1970-01-01 00:00:00 UTC) will require more than 32-bits, so their representation will "magically" switch to double on some systems. Therefore, if you calculate the difference between two times you might end up with a couple of seconds, but as a double, rather than the integer result that occurs in the year 2017.
I think this is much worse than conversions between strings and numbers because it is subtle. I find it easy to keep track of what is a string and what is a number, but keeping track of the number of bits in a number is beyond me.
So, in the above answers there are some nice tables, but no distinction between 1 (as an integer) and 1 (subtle double) and 1.0 (obvious double). Also, advice that you should always use === and never == is not great because === will sometimes fail where == works properly. Also, JavaScript is not equivalent in this regard because it has only one number type (internally it may have different bit-wise representations, but it does not cause problems for ===).
My advice - use neither. You need to write your own comparison function to really fix this mess.
Difference between == (equal) and === (identical equal)
PHP provides two comparison operators to check equality of two values. The main difference between of these two is that '==' checks if the values of the two operands are equal or not. On the other hand, '===' checks the values as well as the type of operands are equal or not.
== (Equal)
=== (Identical equal)
Example =>
<?php
$val1 = 1234;
$val2 = "1234";
var_dump($val1 == $val2);// output => bool(true)
//It checks only operands value
?>
<?php
$val1 = 1234;
$val2 = "1234";
var_dump($val1 === $val2);// output => bool(false)
//First it checks type then operands value
?>
if we type cast $val2 to (int)$val2 or (string)$val1 then it returns true
<?php
$val1 = 1234;
$val2 = "1234";
var_dump($val1 === (int)$val2);// output => bool(true)
//First it checks type then operands value
?>
OR
<?php
$val1 = 1234;
$val2 = "1234";
var_dump($val1 === (int)$val2);// output => bool(true)
//First it checks type then operands value
?>
There are two differences between == and === in PHP arrays and objects that nobody mentioned: two arrays with different key sorts, and objects.
Two arrays with different key sorts
If you have two arrays with their keys sorted differently, but having equal key-value maps, they are strictly different (i.e. using ===). That might lead to problems, if you key-sort an array, and try to compare the sorted array with the original one.
For example:
$arrayUnsorted = [
"you" => "you",
"I" => "we",
];
$arraySorted = $arrayUnsorted;
ksort($arraySorted);
$arrayUnsorted == $arraySorted; // true
$arrayUnsorted === $arraySorted; // false
Objects
Keep in mind, the main rule is that two different objects are never strict-equal. Look at the following example:
$stdClass1 = new stdClass();
$stdClass2 = new stdClass();
$clonedStdClass1 = clone $stdClass1;
$stdClass1 == $stdClass2; // true
$stdClass1 === $stdClass2; // false
$stdClass1 == $clonedStdClass1; // true
$stdClass1 === $clonedStdClass1; // false
Note: Assigning an object to another variable does not create a copy - rather, it creates a reference to the same object. See here.
Note: As of PHP7, anonymous classes was introduced. There is no difference between a new class {} and a new stdClass() in the tests above.

How is it logical that a string equals TRUE in PHP

For the record, I know the solution is to use === instead of == .
I'm just wondering what the logic behind it is. How is it logical that 'hello' can equal TRUE?
$var = TRUE;
if($var == 'hello'){
echo 'match';
}
else{
echo 'no match';
}
The solution has been discussed, but I haven't seen any real explanation.
String value equals true
== compares just the values of the variables whereas === compares variable values and type. so for an example:
1 == 1: true
1 === "1": false // "1" is a string and 1 is an integer
when asking if a string == true, you are essientially asking if it is set. Similar functionality is behind the isset() method.
If you were to compare "hello" === true. This would be false as they are of different type and "hello" would HAVE to equal "hello"
When using == operator think in falsy and truthy terms.
So:
When converting to boolean, the following values are considered FALSE:
the boolean FALSE itself
the integers 0 and -0 (zero)
the floats 0.0 and -0.0 (zero)
the empty string, and the string "0"
an array with zero elements
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
-1 is considered TRUE, like any other non-zero (whether negative or positive) number!
Every other value is considered TRUE (including any resource and NAN).
#see: https://www.php.net/manual/en/language.types.boolean.php

Comparing BOOLEAN TRUE to INTEGER value in PHP

I have the following PHP (the server is running version 5.3.x) in a script which is giving me a result that I am having trouble understanding. The general idea of this code is that I have a "normal mode", and two maintenance modes. In the first maintenance mode, data is only evaluated and can be viewed by an admin but is not stored to the database. If I set $maintenance_mode_enabled = 2;, then the same "preview" output should be displayed but only SOME specific updates to the database should be processed. The reason I added the ==2 comparison is because I found the need for a third option after I had setup the true/false for the basic default maintenance mode. At any rate, I noticed 18 records on my last maintenance_mode_enabled = true; run that were partially updated during the process, just as though I had set maintenance_mode_enabled = 2;.
$maintenance_mode_enabled = true;
if ($maintenance_mode_enabled){
echo "Case 0\n";
}
if (!$maintenance_mode_enabled){
echo "Case 1\n";
}
if ($maintenance_mode_enabled == 2){
echo "Case 2\n";
}
The output I get is:
Case 0
Case 2
From what I understood, true (being boolean) is definitely not equal to 3. I am familiar with some oddities when comparing false, NULL and 0, but this problem with integers and TRUE is entirely new to me.
Any ideas as to why this isn't working? I realize that I can just as easily change $maintenance_mode_enabled to an integer instead of a bolean by default, and set it as either 0, 1 or 2 to get the desired results, but I really want to understand WHY this seems to defy logic.
The reason this happens is because you're comparing a boolean to an integer. As with many languages, at the core of the comparison function it's casting the second part of your comparison to a boolean. Any non-NULL, non-zero, non-empty or non-false value, in this case 2 is "true."
As the previous answer mentions I would change the code to use strict comparison. I would also change from three separate if-statements to one if-elseif statement:
if ($maintenance_mode_enabled === true) {
// catches only true not > 0
echo "Case 0\n";
} elseif ($maintenance_mode_enabled === false) {
// catches only true not = 0
echo "Case 1\n";
} elseif ((int)$maintenance_mode_enabled === 2) {
echo "Case 2\n";
}
I recommend this change because maintenance mode can only have one value.
EDIT
I didn't realize true and 2 could coexist. You could do:
if ($maintenance_mode_enabled) {
echo "Case 0\n";
if (2 === (int)$maintenance_mode_enabled) {
echo "Case 2\n";
}
} else {
echo "Case 1\n";
}
Use the === operator for true otherwise all non 0 / null / false will be true.
Use the === operator for false otherwise all equal to 0 / false / null will show as "false"
The following will output Case 0
<?php
$maintenance_mode_enabled = true;
if ($maintenance_mode_enabled === true){
// catches only true not just > 0
echo "Case 0\n";
}
elseif (!$maintenance_mode_enabled === false){
// catches only false not including = 0
echo "Case 1\n";
}
elseif ($maintenance_mode_enabled == 2){
echo "Case 2\n";
}
?>
Oh, NOW I get it. It seems the problem here is that when I do the loose (==) comparison of a boolean with an integer, the type casting is converting the integer into a boolean, thus resulting in 2 being equal to true - since both are being tested as booleans. The solution is to use strict (===) comparison, so that both must be of the same type... i.e.: 2 (integer), is not exactly the same as true, since true is is of a different type - boolean.

Why did i get this result in php?

if(NULL ==0){
echo "test". NULL;//output is test
echo "<br>";
echo "test". 0;//output is test0
}
If condition say both null and 0 are equal.But why did i get this result?
You have used Loose comparison == . If you use Strict comparison === then you will find the differences.
Read more :
type comparison table
NULL in PHP
Because it depends if you are looking at 0 as the number zero (as in nothing) or a string (as in the character '0').
NULL in PHP has the following properties:
NULL == NULL is true,
NULL == FALSE is true.
And in line with the relational model, NULL == TRUE fails
Over here you are comparing NULL to false whose output is true in PHP
As Nick already said: in this case, you are adding the value 0 to a string that makes it also a string. That's why you get the value test0.
Also, in your if, you are checking for zero value, not a strict true or false statement:
<?php
if( NULL == 0 ) {
echo "test" . NULL;
echo "<br>";
echo "test" . 0;
}
?>
Output:
test
test0
Now try it like this:
<?php
if( NULL === 0 ) {
echo "test" . NULL;
echo "<br>";
echo "test" . 0;
}
?>
You will see, that you get no output, because now the if statement is false.
NULL has no value, in your comparison it is evaluating to False, and 0 is also evaluated as False (so False == False, which is True), which is why the body of the loop executes.
NULL explicitly means "no value". See the documentation for what exactly NULL is.
because if you concat a string with NOTHING (null) the string will remain at it is, if you concat with the integer "0", it will be casted to string (auto-boxing) and concated to the original string...
normal behaviour?
and "null == 0" -> true, but "null === 0" -> false...
you have to check not only the VALUE (which will be "zero" for both itc), you have to check TYPE equality too with "==="
Because, a NULL string is nothing to be printed. Hence the first echo statement, concatenates:
"test" . NULL => "test" Then Nothing
While the 0 is a logical NULL, but in case of String it prints as 0.
In PHP, if you compare any value to a number, the value will be typecasted to Int or Float, and then the comparison will be done. In your case, the NULL is first typecasted to Int, which produces 0, and then compared, givng TRUE. Check PHP type comparison and type juggling.

How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ?

What is the difference between == and ===?
How exactly does the loosely == comparison work?
How exactly does the strict === comparison work?
What would be some useful examples?
Difference between == and ===
The difference between the loosely == equal operator and the strict === identical operator is exactly explained in the manual:
Comparison Operators
Example
Name
Result
$a == $b
Equal
TRUE if $a is equal to $b after type juggling.
$a === $b
Identical
TRUE if $a is equal to $b, and they are of the same type.
Loosely == equal comparison
If you are using the == operator, or any other comparison operator which uses loosely comparison such as !=, <> or ==, you always have to look at the context to see what, where and why something gets converted to understand what is going on.
Converting rules
Converting to boolean
Converting to integer
Converting to float
Converting to string
Converting to array
Converting to object
Converting to resource
Converting to NULL
Type comparison table
As reference and example you can see the comparison table in the manual:
TRUE
FALSE
1
0
-1
"1"
"0"
"-1"
NULL
array()
"php"
""
TRUE
TRUE
FALSE
TRUE
FALSE
TRUE
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
TRUE
TRUE
FALSE
TRUE
1
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
0
FALSE
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
TRUE
FALSE
TRUE
TRUE
-1
TRUE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
"1"
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
"0"
FALSE
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
"-1"
TRUE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
NULL
FALSE
TRUE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
TRUE
TRUE
FALSE
TRUE
array()
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
TRUE
FALSE
FALSE
"php"
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
""
FALSE
TRUE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
TRUE
Strict === identical comparison
If you are using the === operator, or any other comparison operator which uses strict comparison such as !== or ===, then you can always be sure that the types won't magically change, because there will be no converting going on. So with strict comparison the type and value have to be the same, not only the value.
Type comparison table
As reference and example you can see the comparison table in the manual:
Strict comparisons with ===
TRUE
FALSE
1
0
-1
"1"
"0"
"-1"
NULL
array()
"php"
""
TRUE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
1
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
0
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
-1
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
"1"
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
"0"
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
"-1"
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
NULL
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
array()
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
"php"
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
""
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
Editor's note - This was properly quoted previously, but is more readable as a markdown table. This is not plagiarism
The operator == casts between two different types if they are different, while the === operator performs a 'typesafe comparison'. That means that it will only return true if both operands have the same type and the same value.
Examples:
1 === 1: true
1 == 1: true
1 === "1": false // 1 is an integer, "1" is a string
1 == "1": true // "1" gets casted to an integer, which is 1
"foo" === "foo": true // both operands are strings and have the same value
Warning: two instances of the same class with equivalent members do NOT match the === operator. Example:
$a = new stdClass();
$a->foo = "bar";
$b = clone $a;
var_dump($a === $b); // bool(false)
A picture is worth a thousand words:
PHP Double Equals == equality chart:
PHP Triple Equals === Equality chart:
Source code to create these images:
https://github.com/sentientmachine/php_equality_charts
Guru Meditation
Those who wish to keep their sanity, read no further because none of this will make any sense, except to say that this is how the insanity-fractal, of PHP was designed.
NAN != NAN but NAN == true.
== will convert left and right operands to numbers if left is a number. So 123 == "123foo", but "123" != "123foo"
A hex string in quotes is occasionally a float, and will be surprise cast to float against your will, causing a runtime error.
== is not transitive because "0"== 0, and 0 == "" but "0" != ""
PHP Variables that have not been declared yet are false, even though PHP has a way to represent undefined variables, that feature is disabled with ==.
"6" == " 6", "4.2" == "4.20", and "133" == "0133" but 133 != 0133. But "0x10" == "16" and "1e3" == "1000" exposing that surprise string conversion to octal will occur both without your instruction or consent, causing a runtime error.
False == 0, "", [] and "0".
If you add 1 to number and they are already holding their maximum value, they do not wrap around, instead they are cast to infinity.
A fresh class is == to 1.
False is the most dangerous value because False is == to most of the other variables, mostly defeating it's purpose.
Hope:
If you are using PHP, Thou shalt not use the double equals operator because if you use triple equals, the only edge cases to worry about are NAN and numbers so close to their datatype's maximum value, that they are cast to infinity. With double equals, anything can be surprise == to anything or, or can be surprise casted against your will and != to something of which it should obviously be equal.
Anywhere you use == in PHP is a bad code smell because of the 85 bugs in it exposed by implicit casting rules that seem designed by millions of programmers programming by brownian motion.
In regards to JavaScript:
The === operator works the same as the == operator, but it requires that its operands have not only the same value, but also the same data type.
For example, the sample below will display 'x and y are equal', but not 'x and y are identical'.
var x = 4;
var y = '4';
if (x == y) {
alert('x and y are equal');
}
if (x === y) {
alert('x and y are identical');
}
An addition to the other answers concerning object comparison:
== compares objects using the name of the object and their values. If two objects are of the same type and have the same member values, $a == $b yields true.
=== compares the internal object id of the objects. Even if the members are equal, $a !== $b if they are not exactly the same object.
class TestClassA {
public $a;
}
class TestClassB {
public $a;
}
$a1 = new TestClassA();
$a2 = new TestClassA();
$b = new TestClassB();
$a1->a = 10;
$a2->a = 10;
$b->a = 10;
$a1 == $a1;
$a1 == $a2; // Same members
$a1 != $b; // Different classes
$a1 === $a1;
$a1 !== $a2; // Not the same object
It's all about data types. Take a BOOL (true or false) for example:
true also equals 1 and
false also equals 0
The == does not care about the data types when comparing:
So if you had a variable that is 1 (which could also be true):
$var=1;
And then compare with the ==:
if ($var == true)
{
echo"var is true";
}
But $var does not actually equal true, does it? It has the int value of 1 instead, which in turn, is equal to true.
With ===, the data types are checked to make sure the two variables/objects/whatever are using the same type.
So if I did
if ($var === true)
{
echo "var is true";
}
that condition would not be true, as $var !== true it only == true (if you know what I mean).
Why would you need this?
Simple - let's take a look at one of PHP's functions: array_search():
The array_search() function simply searches for a value in an array, and returns the key of the element the value was found in. If the value could not be found in the array, it returns false. But, what if you did an array_search() on a value that was stored in the first element of the array (which would have the array key of 0)....the array_search() function would return 0...which is equal to false..
So if you did:
$arr = array("name");
if (array_search("name", $arr) == false)
{
// This would return 0 (the key of the element the val was found
// in), but because we're using ==, we'll think the function
// actually returned false...when it didn't.
}
So, do you see how this could be an issue now?
Most people don't use == false when checking if a function returns false. Instead, they use the !. But actually, this is exactly the same as using ==false, so if you did:
$arr = array("name");
if (!array_search("name", $arr)) // This is the same as doing (array_search("name", $arr) == false)
So for things like that, you would use the === instead, so that the data type is checked.
PHP Double Equals == :
In most programming languages, the comparison operator (==) checks, on the one hand, the data type and on the other hand the content of the variable for equality. The standard comparison operator (==) in PHP behaves differently. This tries to convert both variables into the same data type before the comparison and only then checks whether the content of these variables is the same. The following results are obtained:
<?php
var_dump( 1 == 1 ); // true
var_dump( 1 == '1' ); // true
var_dump( 1 == 2 ); // false
var_dump( 1 == '2' ); // false
var_dump( 1 == true ); // true
var_dump( 1 == false ); // false
?>
PHP Triple Equals === :
This operator also checks the datatype of the variable and returns (bool)true only if both variables have the same content and the same datatype. The following would therefore be correct:
<?php
var_dump( 1 === 1 ); // true
var_dump( 1 === '1' ); // false
var_dump( 1 === 2 ); // false
var_dump( 1 === '2' ); // false
var_dump( 1 === true ); // false
var_dump( 1 === false ); // false
?>
Read more in What is the difference between == and === in PHP
You would use === to test whether a function or variable is false rather than just equating to false (zero or an empty string).
$needle = 'a';
$haystack = 'abc';
$pos = strpos($haystack, $needle);
if ($pos === false) {
echo $needle . ' was not found in ' . $haystack;
} else {
echo $needle . ' was found in ' . $haystack . ' at location ' . $pos;
}
In this case strpos would return 0 which would equate to false in the test
if ($pos == false)
or
if (!$pos)
which is not what you want here.
Variables have a type and a value.
$var = "test" is a string that contain "test"
$var2 = 24 is an integer vhose value is 24.
When you use these variables (in PHP), sometimes you don't have the good type.
For example, if you do
if ($var == 1) {... do something ...}
PHP have to convert ("to cast") $var to integer. In this case, "$var == 1" is true because any non-empty string is casted to 1.
When using ===, you check that the value AND THE TYPE are equal, so "$var === 1" is false.
This is useful, for example, when you have a function that can return false (on error) and 0 (result) :
if(myFunction() == false) { ... error on myFunction ... }
This code is wrong as if myFunction() returns 0, it is casted to false and you seem to have an error. The correct code is :
if(myFunction() === false) { ... error on myFunction ... }
because the test is that the return value "is a boolean and is false" and not "can be casted to false".
<?php
/**
* Comparison of two PHP objects == ===
* Checks for
* 1. References yes yes
* 2. Instances with matching attributes and its values yes no
* 3. Instances with different attributes yes no
**/
// There is no need to worry about comparing visibility of property or
// method, because it will be the same whenever an object instance is
// created, however visibility of an object can be modified during run
// time using ReflectionClass()
// http://php.net/manual/en/reflectionproperty.setaccessible.php
//
class Foo
{
public $foobar = 1;
public function createNewProperty($name, $value)
{
$this->{$name} = $value;
}
}
class Bar
{
}
// 1. Object handles or references
// Is an object a reference to itself or a clone or totally a different object?
//
// == true Name of two objects are same, for example, Foo() and Foo()
// == false Name of two objects are different, for example, Foo() and Bar()
// === true ID of two objects are same, for example, 1 and 1
// === false ID of two objects are different, for example, 1 and 2
echo "1. Object handles or references (both == and ===) <br />";
$bar = new Foo(); // New object Foo() created
$bar2 = new Foo(); // New object Foo() created
$baz = clone $bar; // Object Foo() cloned
$qux = $bar; // Object Foo() referenced
$norf = new Bar(); // New object Bar() created
echo "bar";
var_dump($bar);
echo "baz";
var_dump($baz);
echo "qux";
var_dump($qux);
echo "bar2";
var_dump($bar2);
echo "norf";
var_dump($norf);
// Clone: == true and === false
echo '$bar == $bar2';
var_dump($bar == $bar2); // true
echo '$bar === $bar2';
var_dump($bar === $bar2); // false
echo '$bar == $baz';
var_dump($bar == $baz); // true
echo '$bar === $baz';
var_dump($bar === $baz); // false
// Object reference: == true and === true
echo '$bar == $qux';
var_dump($bar == $qux); // true
echo '$bar === $qux';
var_dump($bar === $qux); // true
// Two different objects: == false and === false
echo '$bar == $norf';
var_dump($bar == $norf); // false
echo '$bar === $norf';
var_dump($bar === $norf); // false
// 2. Instances with matching attributes and its values (only ==).
// What happens when objects (even in cloned object) have same
// attributes but varying values?
// $foobar value is different
echo "2. Instances with matching attributes and its values (only ==) <br />";
$baz->foobar = 2;
echo '$foobar' . " value is different <br />";
echo '$bar->foobar = ' . $bar->foobar . "<br />";
echo '$baz->foobar = ' . $baz->foobar . "<br />";
echo '$bar == $baz';
var_dump($bar == $baz); // false
// $foobar's value is the same again
$baz->foobar = 1;
echo '$foobar' . " value is the same again <br />";
echo '$bar->foobar is ' . $bar->foobar . "<br />";
echo '$baz->foobar is ' . $baz->foobar . "<br />";
echo '$bar == $baz';
var_dump($bar == $baz); // true
// Changing values of properties in $qux object will change the property
// value of $bar and evaluates true always, because $qux = &$bar.
$qux->foobar = 2;
echo '$foobar value of both $qux and $bar is 2, because $qux = &$bar' . "<br />";
echo '$qux->foobar is ' . $qux->foobar . "<br />";
echo '$bar->foobar is ' . $bar->foobar . "<br />";
echo '$bar == $qux';
var_dump($bar == $qux); // true
// 3. Instances with different attributes (only ==)
// What happens when objects have different attributes even though
// one of the attributes has same value?
echo "3. Instances with different attributes (only ==) <br />";
// Dynamically create a property with the name in $name and value
// in $value for baz object
$name = 'newproperty';
$value = null;
$baz->createNewProperty($name, $value);
echo '$baz->newproperty is ' . $baz->{$name};
var_dump($baz);
$baz->foobar = 2;
echo '$foobar' . " value is same again <br />";
echo '$bar->foobar is ' . $bar->foobar . "<br />";
echo '$baz->foobar is ' . $baz->foobar . "<br />";
echo '$bar == $baz';
var_dump($bar == $baz); // false
var_dump($bar);
var_dump($baz);
?>
All of the answers so far ignore a dangerous problem with ===. It has been noted in passing, but not stressed, that integer and double are different types, so the following code:
$n = 1000;
$d = $n + 0.0e0;
echo '<br/>'. ( ($n == $d)?'equal' :'not equal' );
echo '<br/>'. ( ($n === $d)?'equal' :'not equal' );
gives:
equal
not equal
Note that this is NOT a case of a "rounding error". The two numbers are exactly equal down to the last bit, but they have different types.
This is a nasty problem because a program using === can run happily for years if all of the numbers are small enough (where "small enough" depends on the hardware and OS you are running on). However, if by chance, an integer happens to be large enough to be converted to a double, its type is changed "forever" even though a subsequent operation, or many operations, might bring it back to a small integer in value. And, it gets worse. It can spread - double-ness infection can be passed along to anything it touches, one calculation at a time.
In the real world, this is likely to be a problem in programs that handle dates beyond the year 2038, for example. At this time, UNIX timestamps (number of seconds since 1970-01-01 00:00:00 UTC) will require more than 32-bits, so their representation will "magically" switch to double on some systems. Therefore, if you calculate the difference between two times you might end up with a couple of seconds, but as a double, rather than the integer result that occurs in the year 2017.
I think this is much worse than conversions between strings and numbers because it is subtle. I find it easy to keep track of what is a string and what is a number, but keeping track of the number of bits in a number is beyond me.
So, in the above answers there are some nice tables, but no distinction between 1 (as an integer) and 1 (subtle double) and 1.0 (obvious double). Also, advice that you should always use === and never == is not great because === will sometimes fail where == works properly. Also, JavaScript is not equivalent in this regard because it has only one number type (internally it may have different bit-wise representations, but it does not cause problems for ===).
My advice - use neither. You need to write your own comparison function to really fix this mess.
Difference between == (equal) and === (identical equal)
PHP provides two comparison operators to check equality of two values. The main difference between of these two is that '==' checks if the values of the two operands are equal or not. On the other hand, '===' checks the values as well as the type of operands are equal or not.
== (Equal)
=== (Identical equal)
Example =>
<?php
$val1 = 1234;
$val2 = "1234";
var_dump($val1 == $val2);// output => bool(true)
//It checks only operands value
?>
<?php
$val1 = 1234;
$val2 = "1234";
var_dump($val1 === $val2);// output => bool(false)
//First it checks type then operands value
?>
if we type cast $val2 to (int)$val2 or (string)$val1 then it returns true
<?php
$val1 = 1234;
$val2 = "1234";
var_dump($val1 === (int)$val2);// output => bool(true)
//First it checks type then operands value
?>
OR
<?php
$val1 = 1234;
$val2 = "1234";
var_dump($val1 === (int)$val2);// output => bool(true)
//First it checks type then operands value
?>
There are two differences between == and === in PHP arrays and objects that nobody mentioned: two arrays with different key sorts, and objects.
Two arrays with different key sorts
If you have two arrays with their keys sorted differently, but having equal key-value maps, they are strictly different (i.e. using ===). That might lead to problems, if you key-sort an array, and try to compare the sorted array with the original one.
For example:
$arrayUnsorted = [
"you" => "you",
"I" => "we",
];
$arraySorted = $arrayUnsorted;
ksort($arraySorted);
$arrayUnsorted == $arraySorted; // true
$arrayUnsorted === $arraySorted; // false
Objects
Keep in mind, the main rule is that two different objects are never strict-equal. Look at the following example:
$stdClass1 = new stdClass();
$stdClass2 = new stdClass();
$clonedStdClass1 = clone $stdClass1;
$stdClass1 == $stdClass2; // true
$stdClass1 === $stdClass2; // false
$stdClass1 == $clonedStdClass1; // true
$stdClass1 === $clonedStdClass1; // false
Note: Assigning an object to another variable does not create a copy - rather, it creates a reference to the same object. See here.
Note: As of PHP7, anonymous classes was introduced. There is no difference between a new class {} and a new stdClass() in the tests above.

Categories