2

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?

2
  • 1
    Because E_ALL is a effectively a mask. Its decimal value is totally meaningless; what's important is the value of each bit by itself. See php.net/manual/en/errorfunc.constants.php Commented Sep 4, 2013 at 11:33
  • Those are bitmask values - if you notice, they're all powers of 2 (except for E_ALL, which is all bits 1+2+4+8+16+32... except E_STRICT); there's nothing random about them Commented Sep 4, 2013 at 11:35

1 Answer 1

8

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

DEMO

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)
Sign up to request clarification or add additional context in comments.

2 Comments

@Kirka121 It's an amazing thing to use in your own projects as well (I use it all the time when parsing simple boolean options, as they're very easy to chain.)
Now I understand it. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.