참조 : PHP의 인쇄 및 에코 비교


182

PHP printecho? 의 차이점은 무엇입니까 ?

스택 오버플로에는 PHP printecho키워드 사용법 에 대한 많은 질문이 있습니다.

이 게시물의 목적은 PHP 및 키워드 에 대한 표준 참조 질문과 답변 을 제공 하고 차이점과 사용 사례를 비교하는 것입니다.printecho


3
여기에 인쇄 반환 값이 충분하지 않다고 생각합니다. 인쇄는 빠른 디버그 출력 또는 이와 유사한 것에 유용합니다. strpos ($ x, $ y)! == FALSE 또는 "something"인쇄. 빠르게 입력하고 읽을 수 있습니다. 그리고 "함수를 인쇄합니다"는 어떤 이유로 읽기가 어색했습니다.
XzKto

1
여기에서해야 할 일을 열어 두려면 다음과 같이하십시오. 1. 질문과 답변으로 나뉩니다. 2. 스택 오버플로 (여기서는 Kind : stackoverflow.com/questions/3737139/… ) 주제에 관한 기존 내용에 대한 참조 / 링크 . 3. CW가 필요합니다.
Kev

"관련 칼럼"은 괜찮지 만 그다지 집중되어 있지는 않습니다. 정식 참조 질문 및 답변으로서의 가치를 높이려면 또한 잘 연구되어야하며 다른 특정 정답에 대한 링크는 가치를 추가 할 것입니다.
Kev

질문은 실제로 실제 질문 이어야합니다 . 일단 당신이 끝나면 표준 부분에 관한 배너를 추가 할 수 있습니다.
Tim Post

답변:


185

왜 두 가지 구조입니까?

인쇄반향 에 대한 진실은 사용자에게 두 개의 다른 구성으로 표시되지만 기본에 도달하면 내부 반향 코드를 보면 모두 반향의 음영입니다. 이 소스 코드에는 파서 및 opcode 처리기가 포함됩니다. 숫자 0을 표시하는 것과 같은 간단한 조치를 고려하십시오. echo 또는 print를 사용하든 동일한 핸들러 "ZEND_ECHO_SPEC_CONST_HANDLER"가 호출됩니다. print 처리기는 echo 처리기를 호출하기 전에 한 가지 작업을 수행하며 다음과 같이 print의 반환 값이 1인지 확인합니다.

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

(참고 를 위해 여기를 보십시오 )

리턴 값은 조건식에서 print를 사용하려는 경우 편리합니다. 왜 100이 아닌 1입니까? PHP에서 1 또는 100의 진실성은 동일합니다. 즉, 부울 컨텍스트의 0은 거짓 값과 같습니다. PHP에서 0이 아닌 모든 값 (양수와 음수)은 진실한 값이며 이는 PHP의 Perl 레거시에서 파생됩니다.

그러나 이것이 사실이라면, 왜 echo가 여러 인수를 취하는 지 궁금해 할 수 있지만 print는 하나만 처리 할 수 ​​있습니다. 이 답변을 위해 파서, 특히 파일 zend_language_parser.y로 설정해야 합니다. echo에는 유연성이 내장되어있어 하나 또는 여러 개의 표현식을 인쇄 할 수 있습니다 ( 여기 참조 ). 인쇄는 하나의 인쇄 식으로 제한되는 반면 (참조 : ).

통사론

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

언뜻보기에는 마지막 print 문이 피연산자 '7'을 먼저 인쇄하는 것이 이상하게 보일 수 있습니다 . 그러나 더 깊이 파고 실제 opcode를 보면 의미가 있습니다.

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

생성되는 첫 번째 opcode는 'print 7'에 해당합니다. '~ 0'은 값이 1 인 임시 변수입니다. 해당 변수는 다음 인쇄 opcode에 대해 피연산자가되어 임시 변수를 반환하고 프로세스가 반복됩니다. 마지막 임시 변수는 전혀 사용되지 않으므로 해제됩니다.

print값을 반환 echo합니까?

표현식은 값으로 평가됩니다. 예를 들어로 2 + 3평가 5하고로 abs(-10)평가합니다 10. 그 print expr자체가 표현식 이므로 값을 보유해야합니다. 일관된 값은 1진실한 결과 를 나타내며 0이 아닌 값을 반환하면 다른 표현식에 포함하는 데 유용합니다. 예를 들어이 코드 조각에서 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

부수적으로 일반적으로 진술은 표현이 아닙니다. 그들은 값을 반환하지 않습니다. 물론 예외는 print를 사용하는 표현식 명령문이며 1;PHP에서 C에서 상속하는 구문 과 같은 명령문으로 사용되는 간단한 표현식 입니다. 표현식 명령문은 이상하게 보일 수 있지만 매우 유용하여 인수를 기능.

인가 print하는 기능은?

아니요, 언어 구성입니다. 모든 함수 호출은 표현식이지만 print (expr)함수 호출 구문을 사용하는 것처럼 보이는 비주얼에도 불구하고 표현식입니다. 실제로 이러한 괄호는 괄호 -expr 구문이며 표현식 평가에 유용합니다. 이는 표현식이 단순한 표현식 인 경우 선택 사항이라는 사실을 설명합니다 print "Hello, world!". print (5 ** 2 + 6/2); // 28괄호 와 같이보다 복잡한 표현 을 사용하면 표현을 평가할 수 있습니다. 함수 이름과 달리 print구문 적으로는 키워드 이며 의미 적으로는 "language construct" 입니다.

PHP에서 용어 "언어 구조는"보통 같은 "의사"기능을 의미 isset하거나 empty. 이러한 "구문"은 함수와 똑같아 보이지만 실제로는 fexprs입니다 . 즉, 인수는 평가없이 전달되어 컴파일러의 특별한 처리가 필요합니다. print함수와 같은 방식으로 인수를 평가하도록 선택하는 fexpr입니다.

차이점은 인쇄를 통해 확인할 수 있습니다 . 나열된 기능 get_defined_functions()이 없습니다 print. (그러나 printf친구와는 달리 : print그들은 진정한 기능입니다.)

그러면 print (foo)가 왜 작동합니까?

같은 이유로 echo(foo)작동합니다. 이 괄호는 대신 표현식과 관련되므로 함수 호출 괄호와는 상당히 다릅니다. 그렇기 때문에 echo ( 5 + 8 )13 개의 결과가 표시 될 것으로 예상 할 수 있습니다 (참고 자료 참조 ). 이 괄호는 함수를 호출하지 않고 표현식을 평가하는 데 사용됩니다. 참고 : if 조건식, 할당 목록, 함수 선언 등과 같은 PHP의 괄호는 다른 용도로 사용됩니다.

print(1,2,3)echo(1,2,3)구문 오류가 발생할?

구문은 print expr, echo exprecho expr, expr, ..., expr. PHP가 발생 (1,2,3)하면 C와 달리 이진 쉼표 연산자가 없으므로 PHP는 단일 표현식으로 구문 분석을 시도하고 실패합니다. 쉼표는 구분자로 사용됩니다. (그럼에도 불구하고 PHP의 for-loops에서 구문 쉼표를 찾을 수 있습니다. 구문은 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평가시 :

  1. 그 하나의 인자를 평가 e유형 - 캐스트 문자열로 결과 값을 s. (따라서와 print e같습니다 print (string) e.)
  2. 문자열 s출력 버퍼 로 스트리밍합니다 (결과적으로 표준 출력으로 스트리밍 됨).
  3. 정수로 평가합니다 1.

바이트 코드 레벨의 차이점

print 리턴 변수 (의사 코드)를 채우는 작은 오버 헤드가 포함됩니다.

print 125;

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

단일 echoopcode로 단일 컴파일 :

echo 125;

ECHO 125

여러 값 echo을 여러 opcode로 컴파일

echo 123, 456;

ECHO 123
ECHO 456

다중 값 echo은 인수를 연결하지 않지만 하나씩 하나씩 출력합니다.

참조 : zend_do_print, zend_do_echo.

런타임 차이

ZEND_PRINT 다음과 같이 구현됩니다 (의사 코드)

PRINT  var, result:

    result = 1
    ECHO var

따라서 기본적으로 1결과 변수를 넣고 실제 작업을 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 xvsprint x

달리 에코 , 인쇄 임시 변수를 할당합니다. 그러나이 활동에 소요되는 시간은 미미하므로이 두 언어 구성의 차이는 무시할 만합니다.

속도 : echo a,b,cvsecho a.b.c

첫 번째 문장은 세 개의 개별 문장으로 컴파일됩니다. 두 번째는 전체 표현식을 평가하고 a.b.c.결과를 인쇄하여 즉시 처리합니다. 연결에는 메모리 할당 및 복사가 포함되므로 첫 번째 옵션이 더 효율적입니다.

그래서 어느 것을 사용해야합니까?

웹 응용 프로그램에서 출력은 대부분 템플릿에 집중되어 있습니다. 템플릿 <?=은의 별칭 인을 사용하기 때문에 코드의 다른 부분에도 적용 echo되는 것이 논리적으로 보입니다 echo. echo여러 표현식을 연결하지 않고 인쇄 할 수 있다는 추가 이점이 있으며 임시 리턴 변수를 채우는 오버 헤드가 없습니다. 따라서을 사용하십시오 echo.


5
나는 이것을 광범위하게 편집하고 명확히하고 의미론에 대한 섹션을 추가했습니다. 나는 그것을 확신하지만 누군가는 그것을 다시 확인할 수 있습니다.
jameshfisher

1
그렇다면 echo $a,$b,$c문자열 변수를 연결 하는 것이 더 낫다는 것을 의미합니까 ? 나는 솔직히 이것을 사용하는 것을 본 적이 없다.
geoff

1
기능적 차이점을 설명하는 TL; DR 섹션은 어떻습니까? Like : print하나의 인수 만 허용하며 echo여러 개를 가질 수 있습니다. echocan print및 returns ...; 동안 표현식의 일부가 될 수 없습니다 . 성능 요약 일 수 있습니다. 그리고 모든 "왜"와 "후드 아래"부분
YakovL

0

나는 늦었다는 것을 알고 있지만 추가하고 싶은 한 가지는 내 코드에서

 $stmt = mysqli_stmt_init($connection) or echo "error at init"; 

"구문 오류, 예기치 않은 '에코'(T_ECHO)"오류 발생

동안

 $stmt = mysqli_stmt_init($connection) or print "error at init";

잘 작동합니다.

에코에 대한 문서는 "함수처럼 작동하지 않습니다 (다른 언어 구조와는 달리) 에코"를 말한다 여기 또한 "인쇄 실제로 실제 함수 (언어 구조입니다) 아니다"라고하지만, 인쇄 문서에 대해 여기 . 그래서 나는 왜 그런지 모르겠다. 또한 echo 및 print 문서에 대해서는 echo의 주요 차이점은 print가 단일 인수 만 허용하고 항상 1을 반환한다는 것입니다. 여기

이 행동에 대해 누군가가 밝힐 수 있다면 기쁠 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.