Strange echo, print behaviour in PHP?

前端 未结 4 2083
半阙折子戏
半阙折子戏 2020-12-02 00:57

The following code outputs 43211, why?

  echo print(\'3\').\'2\'.print(\'4\');
4条回答
  •  情书的邮戳
    2020-12-02 01:42

    Much of the confusion is due to the placement of parentheses around the arguments to print. As you know, parentheses are optional with language constructs; what you probably didn't know is that they're removed during parsing.

    Evaluation order

    Let's remove the parentheses first:

    echo print '3' . '2' . print '4';
    

    And illustrate the actual order of evaluation:

    echo (print ('3' . '2' . (print '4')))
    ^     ^      ^                     ^
    3     2      1--------->>----------1
    

    In the heart of this you will find a concatenation of strings or string representations; this is evaluated first:

    '3' . '2' . (print '4')
    

    The first two elements are concatenated:

    '32' . (print '4')
    

    Then, the value of (print '4') is evaluated; after printing its argument '4', the return value of print itself is always int(1); this is cast into a string '1' and concatenated with the other elements:

    '321'
    

    This concludes the first step. The second step passes the temporary results to another print statement:

    print '321'
    

    As before, '321' is printed and now int(1) is returned for the last step:

    echo 1
    

    Proof

    You can confirm this behaviour when you look at the opcodes that are generated (output column is added for clarity):

    line     # *  op          return  operands        output
    ------------------------------------------------+-------
       1     0  >   CONCAT      ~0      '3', '2'    |
             1      PRINT       ~1      '4'         | 4
             2      CONCAT      ~2      ~0, ~1      | 4
             3      PRINT       ~3      ~2          | 4321
             4      ECHO        ~3                  | 43211
    

    Explanation

    • "3" and "2" are concatenated - "32" - and stored into ~0.
    • "4" is printed and the return value int(1) is stored into ~1.
    • ~0 and ~1 are concatenated - "321" - and stored into ~2.
    • "321" is printed and the return value is stored into ~3.
    • int(1) is printed as "1" due to string casting.

提交回复
热议问题