gpt4 book ai didi

php - 引用 : Comparing PHP's print and echo

转载 作者:行者123 更新时间:2023-12-01 16:30:14 25 4
gpt4 key购买 nike

PHP的print有什么区别和 echo ?

Stack Overflow 上有很多关于 PHP 的问题 printecho关键字用法。

这篇文章的目的是提供一个规范的 reference PHP的问答printecho关键字并比较它们的差异和用例。

最佳答案

为什么是两个构造?

关于打印和 echo 的真相是,虽然它们在用户看来是两个不同的结构,但如果您深入了解基础,即查看内部源代码,它们实际上都是 echo 的阴影。该源代码涉及解析器以及操作码处理程序。考虑一个简单的操作,例如显示数字零。无论您使用 echo 还是 print,都将调用相同的处理程序“ZEND_ECHO_SPEC_CONST_HANDLER”。 print 处理程序在调用 echo 处理程序之前会做一件事,它确保 print 的返回值为 1,如下所示:

ZVAL_LONG(&EX_T(opline->result.var).tmp_var, 1);

(见 here for reference )

如果希望在条件表达式中使用打印,返回值是一种方便。为什么是 1 而不是 100?在 PHP 中,1 或 100 的真实性是相同的,即真,而 bool 上下文中的 0 等同于假值。在 PHP 中,所有非零值(正和负)都是真实值,这源自 PHP 的 Perl 遗产。

但是,如果是这种情况,那么人们可能想知道为什么 echo 接受多个参数而 print 只能处理一个。对于这个答案,我们需要求助于解析器,特别是文件 zend_language_parser.y 。您会注意到 echo 具有内置的灵活性,因此它可以打印一个或多个表达式(请参阅 here )。而 print 仅限于打印一个表达式(请参阅 there )。

语法

在 C 编程语言和受其影响的语言如 PHP 中,语句和表达式是有区别的。从语法上讲, echo expr, expr, ... expr 是一个语句,而 print expr 是一个表达式,因为它的计算结果是一个值。因此,与其他语句一样, echo expr 独立存在,不能包含在表达式中:
5 + echo 6;   // syntax error

相比之下, print expr ,可以单独形成一个语句:
print 5; // valid

或者,成为表达式的一部分:
   $x = (5 + print 5); // 5 
var_dump( $x ); // 6

人们可能会倾向于将 print 视为一元运算符,例如 !~ 但它不是运算符。 !, ~ and print 的共同点是它们都内置在 PHP 中,并且每个都只接受一个参数。您可以使用 print 创建以下奇怪但有效的代码:
    <?php 
print print print print 7; // 7111

乍一看,最后一个打印语句首先打印其操作数 '7' 的结果似乎很奇怪。但是,如果您深入挖掘并查看实际操作码,就会发现:
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
3 0 > PRINT ~0 7
1 PRINT ~1 ~0
2 PRINT ~2 ~1
3 PRINT ~3 ~2
4 FREE ~3
5 > RETURN 1

生成的第一个操作码对应于“print 7”。 '~0' 是一个临时变量,其值为 1。该变量成为下一个打印操作码的操作数,该操作码又返回一个临时变量并重复该过程。最后一个临时变量根本没有被使用,所以它被释放了。

为什么 print 返回一个值而 echo 没有?

表达式求值为值。例如 2 + 3 的计算结果为 5 ,而 abs(-10) 的计算结果为 10 。由于 print expr 本身就是一个表达式,那么它应该保存一个值并且确实如此, 1 的一致值表示一个真实的结果,并且通过返回一个非零值,该表达式对于包含在另一个表达式中变得有用。例如,在此代码段中,print 的返回值可用于确定函数序列:
<?php

function bar( $baz ) {
// other code
}
function foo() {
return print("In and out ...\n");
}

if ( foo() ) {

bar();
}

在进行动态调试时,您可能会发现具有特定值的打印,如下例所示:
<?php
$haystack = 'abcde';
$needle = 'f';
strpos($haystack,$needle) !== FALSE OR print "$needle not in $haystack";

// output: f not in abcde

作为旁注,一般来说,语句不是表达式;它们不返回值。异常(exception),当然是使用打印的表达式语句,甚至是用作语句的简单表达式,例如 1; ,PHP 继承自 C 的语法。 表达式语句可能看起来很奇怪,但它非常有用,可以传递参数到功能。
print 是一个函数吗?

不,它是一种语言结构。虽然所有函数调用都是表达式,但 print (expr) 是一个表达式,尽管它看起来好像在使用函数调用语法。事实上,这些括号是括号表达式语法,对表达式求值很有用。这说明了这样一个事实:如果表达式很简单,例如 print "Hello, world!" ,它们有时是可选的。对于更复杂的表达式,例如 print (5 ** 2 + 6/2); // 28,括号有助于表达式的计算。与函数名不同, print is syntactically a keyword 和语义上的 a "language construct"

PHP 中的术语“语言构造”通常指的是“伪”函数,如 issetempty 。尽管这些“构造”看起来和函数一模一样,但它们实际上是 fexprs ,即参数传递给它们而不进行评估,这需要编译器进行特殊处理。 print 恰好是一个 fexpr,它选择以与函数相同的方式评估其参数。

通过打印 get_defined_functions() 可以看出区别:没有列出 print 函数。 (虽然 printf 和 friend 是:与 print 不同,它们是真正的函数。)

为什么 print(foo) 工作呢?

出于与 echo(foo) 工作相同的原因。这些括号与函数调用括号有很大不同,因为它们与表达式有关。这就是为什么可以编写 echo ( 5 + 8 ) 并期望显示 13 的结果(请参阅 reference )。这些括号涉及评估表达式而不是调用函数。注意:PHP 中的括号还有其他用途,例如 if 条件表达式、赋值列表、函数声明等。

为什么 print(1,2,3)echo(1,2,3)会导致语法错误?

语法是 print exprecho exprecho expr, expr, ..., expr 。当 PHP 遇到 (1,2,3) 时,它​​尝试将其解析为单个表达式并失败,因为与 C 不同,PHP 并没有真正的二进制逗号运算符;逗号更多地用作分隔符。 (你可能会在 PHP 的 for 循环中找到一个二进制逗号,它继承自 C 的语法。)

语义
echo e1, e2, ..., eN; 语句可以理解为 echo e1; echo e2; ...; echo eN; 的语法糖。

由于所有的表达式都是语句,而 echo e 总是和 print e 有同样的副作用,而且 print e 的返回值在用作语句时会被忽略,所以我们可以将 echo e 理解为 print e 的语法糖。

这两个观察结果意味着 echo e1, e2, ..., eN; 可以被视为 print e1; print e2; ... print eN; 的语法糖。 (但是,请注意下面的非语义运行时差异。)

因此,我们只需要定义 print 的语义。 print e ,评估时:
  • 将其单个参数 etype-casts 评估为字符串 s 的结果值。 (因此, print e 等价于 print (string) e 。)
  • 将字符串 s 流式传输到 the output buffer(最终将流式传输到标准输出)。
  • 计算为整数 1

  • 字节码级别的差异
    print 涉及填充返回变量(伪代码)的小开销
    print 125;

    PRINT 125,$temp ; print 125 and place 1 in $temp
    UNSET $temp ; remove $temp

    单个 echo 编译为一个操作码:
    echo 125;

    ECHO 125

    多值 echo 编译为多个操作码
    echo 123, 456;

    ECHO 123
    ECHO 456

    请注意,多值 echo 不会连接其参数,而是将它们一一输出。

    引用: zend_do_print zend_do_echo

    运行时差异

    ZEND_PRINT 实现如下(伪代码)
    PRINT  var, result:

    result = 1
    ECHO var

    所以它基本上将 1 放在结果变量中,并将真正的工作委托(delegate)给 ZEND_ECHO 处理程序。 ZEND_ECHO 执行以下操作
    ECHO var:

    if var is object
    temp = var->toString()
    zend_print_variable(temp)
    else
    zend_print_variable(var)

    其中 zend_print_variable() 执行实际的“打印”(实际上,它只是重定向到专用的 SAPI 函数)。

    速度: echo xprint x
    echo 不同, print 分配一个临时变量。然而,花在这项事件上的时间很少,所以这两种语言结构之间的差异可以忽略不计。

    速度: echo a,b,cecho a.b.c
    第一个编译成三个单独的语句。第二个计算整个表达式 a.b.c. ,打印结果并立即处理它。由于串联涉及内存分配和复制,第一个选项将更有效。

    那么使用哪一种呢?

    在 Web 应用程序中,输出主要集中在模板中。由于模板使用 <?= ,它是 echo 的别名,因此在代码的其他部分也坚持使用 echo 似乎是合乎逻辑的。 echo 有一个额外的优势,即能够打印多个表达式而不连接它们,并且不涉及填充临时返回变量的开销。所以,使用 echo

    关于php - 引用 : Comparing PHP's print and echo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7094118/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com