Reputation: 3236
By using get_defined_constants function from php, I can see all the defined constants by system and myself.
Example:
<?php
define("MY_CONSTANT", 1);
print_r(get_defined_constants(true));
?>
Output:
Array
(
[Core] => Array
(
[E_ERROR] => 1
[E_RECOVERABLE_ERROR] => 4096
[E_WARNING] => 2
[E_PARSE] => 4
[E_NOTICE] => 8
[E_STRICT] => 2048
[E_DEPRECATED] => 8192
[E_CORE_ERROR] => 16
[E_CORE_WARNING] => 32
[E_COMPILE_ERROR] => 64
[E_COMPILE_WARNING] => 128
[E_USER_ERROR] => 256
[E_USER_WARNING] => 512
[E_USER_NOTICE] => 1024
[E_USER_DEPRECATED] => 16384
[E_ALL] => 30719
[DEBUG_BACKTRACE_PROVIDE_OBJECT] => 1
[DEBUG_BACKTRACE_IGNORE_ARGS] => 2
....
Question: How did they come up with the integer value to some constants? For example E_ALL
has a value of 30719
. Why 30719
and not a random number?
Upvotes: 2
Views: 148
Reputation: 39550
This all comes down to binary:
[E_ERROR] => 1 //000000000000001
[E_WARNING] => 2 //000000000000010
[E_PARSE] => 4 //000000000000100
[E_NOTICE] => 8 //000000000001000
[E_CORE_ERROR] => 16 //000000000010000
[E_CORE_WARNING] => 32 //000000000100000
[E_COMPILE_ERROR] => 64 //000000001000000
[E_COMPILE_WARNING] => 128 //000000010000000
[E_USER_ERROR] => 256 //000000100000000
[E_USER_WARNING] => 512 //000001000000000
[E_USER_NOTICE] => 1024 //000010000000000
[E_STRICT] => 2048 //000100000000000
[E_RECOVERABLE_ERROR] => 4096 //001000000000000
[E_DEPRECATED] => 8192 //010000000000000
[E_USER_DEPRECATED] => 16384 //100000000000000
[E_ALL] => 30719 //111011111111111 (everything but E_STRICT)
If you'd want E_ERROR and E_USER_ERROR, you'd perform a bitwise OR
statement:
define("E_ERROR_ALL", E_ERROR | E_USER_ERROR);
This is the same as the following
000000000000001 //E_ERROR
000000100000000 //E_USER_ERROR
------|-------|
000000100000001 //Our custom E_ERROR_ALL
as OR
is super simple:
0 - 0 = 0
0 - 1 = 1
1 - 0 = 1
1 - 1 = 1
When checking, we can simply use a bitwise AND
operation, and if the result is more than 0 then that bit is included:
<?php
$errorCode = E_PARSE | E_CORE_ERROR;
if (($errorCode & E_PARSE) > 0) {
echo "Error code includes E_PARSE" . PHP_EOL;
}
if (($errorCode & E_NOTICE) > 0) {
echo "Error code includes E_NOTICE" . PHP_EOL;
}
if (($errorCode & E_CORE_ERROR) > 0) {
echo "Error code includes E_CORE_ERROR" . PHP_EOL;
}
?>
Will output
Error code includes E_PARSE
Error code includes E_CORE_ERROR
The reason this works is because AND
uses the following logic:
0 - 0 = 0
0 - 1 = 0
1 - 0 = 0
1 - 1 = 1
Therefore, if we check our custom error code (10100
) against E_CORE_ERROR
(10000
), we get the following operation:
10100
AND 10000
|----
10000 = 16 (therefore larger than 0)
but if we check with E_NOTICE
(01000
), the following operation is performed:
10100
AND 01000
-----
00000 = 0 (No match)
Upvotes: 8