PHPの違いは何であるprint
とはecho
?
Stack Overflowには、PHP print
とecho
キーワードの使用について多くの質問があります。
この投稿の目的は、 PHP とキーワードに関する標準的な参照質問と回答を提供し、それらの違いとユースケースを比較することです。print
echo
PHPの違いは何であるprint
とはecho
?
Stack Overflowには、PHP print
とecho
キーワードの使用について多くの質問があります。
この投稿の目的は、 PHP とキーワードに関する標準的な参照質問と回答を提供し、それらの違いとユースケースを比較することです。print
echo
回答:
印刷とエコーの真実は、ユーザーには2つの異なる構成要素として表示されますが、基本、つまり内部ソースコードを見ると、どちらも実際にはエコーの陰影です。そのソースコードには、パーサーとオペコードハンドラーが含まれます。数字の0を表示するなどの単純なアクションを考えます。エコーと印刷のどちらを使用しても、同じハンドラ「ZEND_ECHO_SPEC_CONST_HANDLER」が呼び出されます。printのハンドラーは、echoのハンドラーを呼び出す前に1つのことを行います。これは、次のように、printの戻り値が1であることを確認します。
ZVAL_LONG(&EX_T(opline->result.var).tmp_var, 1);
条件式でprintを使用したい場合、戻り値は便利です。なぜ100ではなく1なのですか?PHPでは、1または100の真実性は同じ、つまり真ですが、ブール値のコンテキストでの0は偽の値と同等です。PHPでは、ゼロ以外のすべての値(正と負)は真の値であり、これはPHPのPerlレガシーに由来します。
しかし、これが当てはまる場合、echoが複数の引数を取るのに、printは1つの引数しか処理できないのに不思議に思うかもしれません。この回答では、パーサー、特にzend_language_parser.yファイルを参照する必要があります。エコーには、1つまたは複数の式を出力できるように柔軟性が組み込まれていることに注意してください(ここを参照)。一方、printは1つの式のみを印刷するように制限されています(そこを参照)。
Cプログラミング言語およびPHPのようなCプログラミング言語によって影響を受ける言語では、ステートメントと式に違いがあります。構文的に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」を最初に出力するという結果は奇妙に見えるかもしれません。しかし、深く掘り下げて実際のオペコードを見ると、理にかなっています。
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
truthy結果を示し、式が別の式に含めるために有用となるゼロ以外の値を返すこと。たとえば、次のスニペットでは、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)
関数呼び出し構文を使用しているかのように見えるビジュアルにもかかわらず、すべての関数呼び出しは式ですが、式です。実際には、これらの括弧は括弧式の式であり、式の評価に役立ちます。これは、式がのような単純なものである場合、オプションとなる場合があることを説明していprint "Hello, world!"
ます。print (5 ** 2 + 6/2); // 28
括弧などのより複雑な式では、式の評価に役立ちます。関数名とprint
は異なり、は構文的にはキーワードであり、意味的には「言語構造」です。
PHPの「言語構造」という用語は、通常、isset
またはのような「疑似」関数を指しempty
ます。これらの「構文」は関数とまったく同じに見えますが、実際にはfexprsです。つまり、引数は評価されずに渡されます。これには、コンパイラーによる特別な処理が必要です。print
たまたま関数と同じ方法で引数を評価することを選択するfexprです。
違いは印刷によって確認できます。リストされている機能get_defined_functions()
はありませんprint
。(とはいえprintf
、友達とは:とは異なりprint
、真の機能です。)
それが機能するのと同じ理由でecho(foo)
。これらの括弧は、式に関係するため、関数呼び出しの括弧とはかなり異なります。そのため、コーディングecho ( 5 + 8 )
を行うと13の結果が表示されることが期待できます(参照を参照)。これらの括弧は、関数を呼び出すのではなく、式の評価に関与します。注:if条件式、代入リスト、関数宣言など、PHPのかっこの使用法は他にもあります。
print(1,2,3)
とecho(1,2,3)
構文エラーになりますか?構文はprint expr
、echo expr
またはecho expr, expr, ..., expr
です。PHPはに遭遇すると(1,2,3)
、それを単一の式として解析しようとして失敗します。これは、Cとは異なり、PHPには実際には2項カンマ演算子がないためです。コンマは区切り文字としてより役立ちます。(それでも、PHPのforループ、Cから継承された構文では、バイナリコンマが見つかるかもしれません。)
このステートメントecho e1, e2, ..., eN;
は、の構文糖として理解できますecho e1; echo e2; ...; echo eN;
。
すべての式はステートメントであり、echo e
常にと同じ副作用がありprint e
、print e
ステートメントとして使用した場合、の戻り値は無視されるためecho e
、の構文シュガーとして理解できprint e
ます。
これらの2つの観察は、のecho e1, e2, ..., eN;
構文糖と見なすことができることを意味しますprint e1; print e2; ... print eN;
。(ただし、以下の非セマンティックランタイムの違いに注意してください。)
したがって、のセマンティクスを定義するだけで済みますprint
。print e
、評価時:
e
を評価し、結果の値を文字列に型キャストしますs
。(したがって、print e
と同等print (string) e
です。)s
を出力バッファーにストリーミングします(最終的には標準出力にストリーミングされます)。1
ます。print
戻り値の変数(疑似コード)を設定するための小さなオーバーヘッドが含まれます
print 125;
PRINT 125,$temp ; print 125 and place 1 in $temp
UNSET $temp ; remove $temp
シングルはecho
、1つのオペコードにコンパイルします。
echo 125;
ECHO 125
複数値echo
が複数のオペコードにコンパイルされます
echo 123, 456;
ECHO 123
ECHO 456
複数値echo
は引数を連結しませんが、1つずつ出力します。
リファレンス: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)
where zend_print_variable()
は実際の「印刷」を実行します(実際には、専用のSAPI関数にリダイレクトするだけです)。
echo x
vsprint x
echoとは異なり、printは一時変数を割り当てます。ただし、このアクティビティに費やされる時間はごくわずかであるため、これら2つの言語構造の違いはごくわずかです。
echo a,b,c
vsecho a.b.c
最初のものは、3つの個別のステートメントにコンパイルされます。2番目は、式全体を評価しa.b.c.
、結果を出力して、すぐに破棄します。連結にはメモリの割り当てとコピーが含まれるため、最初のオプションの方が効率的です。
Webアプリケーションでは、出力は主にテンプレートに集中します。テンプレートは使用するため<?=
の別名である、echo
論理的に固執すると思われるecho
だけでなく、コードの他の部分で。echo
複数の式を連結せずに出力できるという追加の利点があり、一時的な戻り変数を生成するオーバーヘッドがありません。したがって、を使用しますecho
。
echo $a,$b,$c
文字列変数の連結に使用する方が良いという意味ですか?正直なところ、これが使用されているのを見たことがありません。
print
1つの引数のみを許可し、echo
複数の引数を持つことができます。echo
can print
とreturnの間、式の一部になることはできません...; いくつかのパフォーマンスの要約があるかもしれません。そして、それらすべての「なぜ」および「ボンネットの下」の部分
私は遅れていることを知っていますが、追加したいことの1つは私のコードにあることです
$stmt = mysqli_stmt_init($connection) or echo "error at init";
「構文エラー、予期しない「エコー」(T_ECHO)」というエラーが発生する
ながら
$stmt = mysqli_stmt_init($connection) or print "error at init";
正常に動作します。
エコーに関するドキュメントには、「エコー(他の言語構造とは異なり)は関数のように動作しない」とあります が、印刷ドキュメントについては、「印刷は実際には実際の関数ではありません(言語構造です)」とあります。だから私はなぜだかわかりません。また、echoとprint docsについては、「echoとの主な違いは、printは単一の引数しか受け入れず、常に1を返すことです。」ここに
誰かがこの行動についていくつかの光を当てることができれば幸いです。