Press "Enter" to skip to content

print不是函数

这个源自于一个看似很诡异的问题:

if (print("1\n") && print("2\n") && print("3\n") && print("4\n")) {
    ;
}

你期待这段代码输出什么呢?
实际上的输出是:

4
111

很多时候我们会忽略了print是一个语法结构(language constructs), 他并不是一个函数, 参数的list并不要求有括号(即使你写了括号, 括号也会在语法分析阶段被忽略), 他只是一个永远返回结果是1的"表达式(expr)":

expr :
   T_PRINT expr
 | '(' expr ')'
;

所以其实上面的代码在php看来是:

if (print ("1\n" && print ("2\n" && print ("3\n" && print "4\n")))) {
  ;
}

所以就是, 输出4, 然后输出 "3\n" && print的结果1 , 然后输出 "2\n" && 1, 最后是 "1\n" && 1
而如果想要达到上面代码的本身想要的意图, 我们应该这么写:

if ((print "1\n") && (print "2\n") && (print "3\n") && (print "4\n")) {
    ;
}

83 Comments

  1. gaurav
    gaurav February 3, 2020

    i m very glad thanks nice post you shared with us

  2. 广州中专学校
    广州中专学校 January 7, 2020

    网站内容还是挺不错的,谢谢博主。还有博客应该是WORDPRESS做的吧,感觉美观度还可以提高,谢谢。我自已是搞前端设计的,你的代码可以做精简一点。

    • 匿名用户
      匿名用户 January 9, 2020

      给我看笑了

    • 霸王别激
      霸王别激 February 24, 2020

      厉害,勇气可嘉,给你点个赞。

    • 嘿嘿嘿
      嘿嘿嘿 June 8, 2020

      给爷整笑了

  3. intro
    intro December 10, 2019

    if (print 0 && print 1){
    echo “aaa”;
    }
    为何这个输出的只有“aaa”? 不是 print 1 输出1 返回 1 然后 print 0&&1 输出(0或1 ?) 返回1 吗? 应该如何理解?

    • ph
      ph January 14, 2020

      print 0 && print 1 ===等价于===> print (0 && print 1) ===等价于===> print false ===返回===> 1
      (0 && print 1) 这个语句中因为是‘&&’(前面为假,后面就不会执行),所以print 1不会执行,直接返回false。
      php中 print false 或者 echo false 这种语句都不会有任何输出,而print 语句本身返回1(真),所以就执行if内的语句,输出 aaa

  4. 13
    13 December 6, 2019

    你好请问 eval 怎么禁用 从源码里面 修改禁止执行

  5. tan
    tan December 3, 2019

    评论好多链接啊

  6. 胡昂
    胡昂 November 18, 2019

    虽然实际编码没人会使用这个知识点,但了解一下挺有意思的

  7. Kavin
    Kavin November 14, 2019

    支持一下不错

  8. cvv shop
    cvv shop November 1, 2019

    你是最好的人! 非常感谢你!

  9. 36加盟网
    36加盟网 October 27, 2019

    很多时候我们会忽略了print是一个语法结构(language constructs), 他并不是一个函数, 参数的list并不要求有括号(即使你写了括号, 括号也会在语法分析阶段被忽略), 他只是一个永远返回结果是1的”表达式(expr)”

  10. 小二郎
    小二郎 September 20, 2019

    学习了

  11. jack
    jack September 3, 2019

    鸟哥,我们phper该转Go吗?前途迷茫啊,不知道哪天就整个PHP项目组被裁掉…

  12. mx
    mx August 28, 2019

    学习了

  13. SKY8G
    SKY8G August 26, 2019

    讲解的不错,非常喜欢,另外我也写了有关PHP面向对象的总结,分享给大家阅读。
    PHP 高级教程-面向对象编程(OOP)[第一章] https://www.sky8g.com/news/3107/

  14. miss zhy
    miss zhy August 9, 2019

    print和echo差不多都是语言结构,只不过echo可以一次多个值。那上面的例子print换成echo为什么就报错了

  15. Zaky
    Zaky August 3, 2019

    我想学习,我喜欢这种解释方式,我期待下一次更新。你能救我吗?

    • Loy
      Loy August 14, 2019

      能救你的只有你自己。

  16. Dovino
    Dovino July 16, 2019

    do you open a place for a course if you provide a place for courses there is an address that I can contact

  17. puffty
    puffty June 19, 2019

    受教了

  18. Koey
    Koey June 12, 2019

    我一开始不能理解,但是在我百度了“表达式”这个词后就理解了。但是我还是觉得PHP应该跟我一样笨才对,为啥要看成这样if (print (“1\n” && print (“2\n” && print (“3\n” && print “4\n”)))) {
    ;
    }
    而不是看成这样 if ((print “1\n”) && (print “2\n”) && (print “3\n”) && (print “4\n”)) {
    ;
    }

    • Yam
      Yam June 20, 2019

      还是不是挺明白,能解析下吗

  19. Happydong
    Happydong May 27, 2019

    受教了

  20. jake
    jake May 11, 2019

    简单明了

  21. Coo
    Coo April 15, 2019

    Cool

  22. Terry
    Terry April 10, 2019

    还以为鸟哥忘记了博客密码

    • white_hole
      white_hole April 15, 2019

      哈哈

  23. noone
    noone March 27, 2019

    确实容易混淆

  24. Dave
    Dave March 27, 2019

    感觉PHP语法太宽松了,这样反而容易出错。

  25. 七彩方糖
    七彩方糖 March 15, 2019

    妈妈说,凡是遇到有运算符号的,请一律加括号。

  26. cvv shop
    cvv shop March 11, 2019

    这是最简单明了的解释! 非常感谢你!

  27. test test
    test test March 8, 2019

    大佬收徒弟吗

  28. marskang
    marskang March 5, 2019

    跟python2中的print一样,不是一个函数,不过到python3中已经变成函数了。

  29. 爱开源
    爱开源 March 5, 2019

    博客速度变快很多!!!
    是不是有什么黑科技? 求鸟哥分享.

  30. NiZerin
    NiZerin March 5, 2019

    博客终于更新了,蹭下热度! 2333333

  31. CFC4N
    CFC4N March 5, 2019

    嘿,鸟哥的BLOG更新了新模板…终于跟得上时代了。

    • Laruence
      Laruence March 4, 2019

      我把那段表述不正确的删除了,不过isset和unset依旧是语言结构, 他们会在编译阶段直接翻译为对应的opcode, 只不过他们对应的语法解析规则中定义为了需要有括号。。

  32. 黄江宇
    黄江宇 March 3, 2019

  33. libais
    libais March 2, 2019

    举个栗子:
    die(‘a’); //打印a并终止程序
    die ‘a’; //语法错误
    既然不是函数,不知道这个怎么理解

  34. 西枫里博客
    西枫里博客 March 1, 2019

    从没仔细思考过这个问题,只认知print不是函数。。。

  35. ?
    ? March 1, 2019

    在升级PHP7的时候应该考虑将print定义成内置函数,而不是语法结构。这种特性会莫名增加语言的复杂度。
    难道是特别特别早的时候,PHP还没有函数。所以临时定义了一个这样的语法结构?
    不然早就已经废掉了。

Leave a Reply to SKY8G Cancel reply

Your email address will not be published. Required fields are marked *