Search code examples
phpfunctionerror-reporting

Why exactly does this code do? And what kind of operator is &?


I was searching the manual for error_reporting. There I found an example which lists all the error reporting levels in the browser window. I went through the code and some coding style seems unfamiliar to me and I couldn't understand what exactly it does.

In the manual, it says error_reporting () returns:

Returns the old error_reporting level or the current level if no level parameter is given

I know error_reporting(level) determines what type of error to show or not to show. But what it returns when it is assigned to a variable ? like the following:

$errLvl = error_reporting(); 

I have printed $errLvl and it returned 22527. I don't understand what it means? Can any one explain it to me in plain English?

There is a function called FriendlyErrorType($type) which will accept an error type and print it in the browser. But it is given a parameter ($errLvs & pow(2,i)). What does & operator supposed to do? I mean what is the function of & operator in the argument?

print FriendlyErrorType($errLvl & pow(2, $i))

fullCode:

$errLvl = error_reporting();
echo $errLvl.'</br>';
for ($i = 0; $i < 15;  $i++ ) {
    print FriendlyErrorType($errLvl & pow(2, $i)) . "<br>\\n";
}

function FriendlyErrorType($type)
{
    switch($type)
    {
        case E_ERROR: // 1 //
            return 'E_ERROR';
        case E_WARNING: // 2 //
            return 'E_WARNING';
        case E_PARSE: // 4 //
            return 'E_PARSE';
        case E_NOTICE: // 8 //
            return 'E_NOTICE';
        case E_CORE_ERROR: // 16 //
            return 'E_CORE_ERROR';
        case E_CORE_WARNING: // 32 //
            return 'E_CORE_WARNING';
        case E_COMPILE_ERROR: // 64 //
            return 'E_COMPILE_ERROR';
        case E_COMPILE_WARNING: // 128 //
            return 'E_COMPILE_WARNING';
        case E_USER_ERROR: // 256 //
            return 'E_USER_ERROR';
        case E_USER_WARNING: // 512 //
            return 'E_USER_WARNING';
        case E_USER_NOTICE: // 1024 //
            return 'E_USER_NOTICE';
        case E_STRICT: // 2048 //
            return 'E_STRICT';
        case E_RECOVERABLE_ERROR: // 4096 //
            return 'E_RECOVERABLE_ERROR';
        case E_DEPRECATED: // 8192 //
            return 'E_DEPRECATED';
        case E_USER_DEPRECATED: // 16384 //
            return 'E_USER_DEPRECATED';
    }
    return "";

Solution

  • So your code is just checking which error types you have on and returns the constant name of that error type.

    But first to clarify what & operator this is. It is a bitwise AND operator (Also see this as reference: Reference - What does this symbol mean in PHP?).

    So basically it does this:

      A    |    B    &   results 
    -----------------------------
      0    |    0   ->     0
      0    |    1   ->     0
      1    |    1   ->     1
      1    |    0   ->     0
    

    So a plain english example woulde be:

    If the sun is shining AND it I don't have to work at this day THEN I go outside (otherwise NOT).


    So now your code just get's your current error level:

    $errLvl = error_reporting();
    

    For you it is:

    22527  //Which in binary is: 0101'0111 1111'1111
    

    After this it goes through the loop 15 times and basically always checks if the next digit is 1 or 0, e.g:

    1. Iteration:

    0101'0111 1111'1111            // your error level
                      1            // pow(2, $i) -> 2^0 -> 1
    ------------------- &
                      1  =      1  //argument for the function call
    

    2. Iteration:

    0101'0111 1111'1111            // your error level
                     10            // pow(2, $i) -> 2^1 -> 2
    ------------------- &
                     10  =      2  //argument for the function call
    

    ...

    15. Iteration:

    0101'0111 1111'1111            // your error level
    0100'0000 0000'0000            // pow(2, $i) -> 2^14 -> 16384
    ------------------- &
    0100'0000'0000'0000  = 16'384  //argument for the function call
    

    And then in the function it simply is a switch statement to get the right term to return if it the corresponding digit is set.

    You can also see all predefined error constants here: http://php.net/manual/en/errorfunc.constants.php

    Here visualized:

    0000'0000 0000'0000
    |||| |||| |||| |||| ----- E_ERROR              =      1
    |||| |||| |||| ||| ------ E_WARNING            =      2
    |||| |||| |||| || ------- E_PARSE              =      4
    |||| |||| |||| | -------- E_NOTICE             =      8
    |||| |||| ||||
    |||| |||| |||| ---------- 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        =  1'024
    |||| | ------------------ E_STRICT             =  2'048
    ||||
    |||| -------------------- E_RECOVERABLE_ERROR  =  4'096
    ||| --------------------- E_DEPRECATED         =  8'192
    || ---------------------- E_USER_DEPRECATED    = 16'384
    | ----------------------- E_ALL                = 32'767
    

    Now if you want to ask why it doesn't check for the last digit (E_ALL), because basically E_ALL == all error types. So if you get all error types back you have error reporting: E_ALL


    So for the end your error level visualized:

    0101'0111 1111'1111
     | |  ||| |||| |||| ----- E_ERROR         
     | |  ||| |||| ||| ------ E_WARNING          
     | |  ||| |||| || ------- E_PARSE   
     | |  ||| |||| | -------- E_NOTICE   
     | |  ||| ||||
     | |  ||| |||| ---------- E_CORE_ERROR      
     | |  ||| ||| ----------- E_CORE_WARNING   
     | |  ||| || ------------ E_COMPILE_ERROR    
     | |  ||| | ------------- E_COMPILE_WARNING 
     | |  |||
     | |  ||| --------------- E_USER_ERROR   
     | |  || ---------------- E_USER_WARNING     
     | |  | ----------------- E_USER_NOTICE    
     | |
     | | -------------------- E_RECOVERABLE_ERROR  
     |  
     | ---------------------- E_USER_DEPRECATED   
    
    
    
    output of your code:
    
    E_ERROR 
    E_WARNING
    E_PARSE  
    E_NOTICE
    E_CORE_ERROR 
    E_CORE_WARNING  
    E_COMPILE_ERROR 
    E_COMPILE_WARNING 
    E_USER_ERROR  
    E_USER_WARNING
    E_USER_NOTICE
    E_RECOVERABLE_ERROR  
    E_USER_DEPRECATED