LoginSignup
141
98

More than 3 years have passed since last update.

echoとprintの違い

Posted at

PHPのechoprintはどちらも関数ではなく言語構造です。どちらも文字列を出力バッファに書き出すという機能では同じですが、使われかたが異なります。

echo 1, 2, 3; // ← syntax error ではない
print 1, 2, 3; // ← これは syntax error

echo print 1; // ← syntax error ではない
print echo 1; // ← これは syntax error

形式的に言うと

  • echoprintはどちらも出力バッファに書き込む機能です
    • まれに「標準出力する」と言及されますが、それは間違いです
    • fwrite(STDOUT, $str)の実行結果とは一致しないということです
  • echoは文ですがprintは式です
  • echoは複数の引数をとりますが、printは1つの引数をとります
  • 便宜上関数マニュアルに掲載されているが関数ではありません

どれを使えばいいの?

好みで何を使ってもいいと思うのですが、printを使うメリットは特にないのでechoを薦めます。

echo $string;

または

echo $str1, $str2, PHP_EOL;

この形式だけを使えばいいと思います。

また、 echoprintはどちらも関数ではないので echo($v)print($v)のような関数呼び出し風の記述は誤解を呼ぶので使わない方が良いと思います。

echo

echo — 1 つ以上の文字列を出力する

print との主な違いは、 echo がリスト形式の引数を受け付け、返り値を持たないことです。

たしかにPHPの文は式の項にならない(値を返さない)ので、説明通りです。

まれにechoを関数のように呼び出すひとがいます。

echo("str");

しかし、この ()$i = 1 + 2; と書いても $i = (1 + 2);と書いても結果が変わらないのと同じで、余分なカッコを書いているだけです。

これで、以下のような式がsyntax errorになることを説明できます。

echo("str1", "str2");

これは関数呼び出しで例えると f(1, 2) と書くべきものを f((1, 2)) と書いていることと同じです。PHPには関数呼び出しや言語構造の引数以外に(1, 2)のように値を列挙する式はありません。

print

print — 文字列を出力する

echoとの主な違いは、printが単一の引数のみ受け付け、常に 1 を返すことです。

この説明からはわかりにくいですが、printは式であり、式の中に書くことができるということです。

どうしてわざわざ、echoとは異なるこのような仕様があるのでしょうか。

わたしが考えつく限り、この仕様のユースケースは以下のようなものです。

foo() and print "success\n";
bar() or print "error\n";

これらの式はifを使って以下のように書き直せます。

if (foo()) {
    echo "error", PHP_EOL;
}

if (!bar()) {
    echo "error", PHP_EOL;
}

これらは、わざわざショートコーディングを正当化するためには心許ない例です。書き捨てのコードでデバッグ用途で一瞬使うだけならともかく、もっとわかりやすく書いた方がよいでしょう。

printは関数呼び出しではなく言語構造なので、print(1)と書いても(print 1)と書いても同じことです。print(1, 2)と書いてしまうと関数呼び出しのように錯覚させてしまいますが、これは関数呼び出し式ではないため、純粋にsyntax errorです。

printf()

せっかくなのでprintf()にも言及しておきましょう。echoprintは言語構造でしたが、printf()はPHPの組み込み関数です。

printf — フォーマット済みの文字列を出力する

これも出力バッファに文字列を書き出すという意味では共通していますが、意味が異なります。echoprintが単に文字列を出力するだけのものであるのに対して、printf()はフォーマット文字列を整形する、一種のテンプレートエンジンと呼べるものです。

printf('%d + %d = %d', $a, $b, $a + $b);

printf()は高機能なので活用すると便利ですが、echoprintとは違う使いかたを意識する必要があります。

// 安全なコード
echo "こんにちは {$name} さん! ({$num}回め)";

// 危険なコード
printf("こんにちは {$name} さん! (%d回め)", $num);

後者のコードでは$name%が含まれると実行時エラーやテンプレートの位置をずらされるといった問題が起きえます。sprintf()を使って文字を組み立てる場合などもバグや脆弱性の原因となりうることがあるでしょう。

printf("こんにちは %s さん! (%d回め)", $name, $num);

printf()sprintf()などの第一引数には変数を直接展開せず、printf()%sなどを使ってください。

オペコードとの関係

PHP5時代はオペコードレベルでPRINTECHOは別の命令でしたが、PHP7ではECHO命令に統合されており最適化も施されるので特に違いは生じないはずです。

2015年9月に出版されたPHPはどのように動くのか ~PHPコアから読み解く仕組みと定石ではprintよりもechoの方がパフォーマンスに優れていると読み取れる記述があるのですが、実際には2015年12月にはPHP 7.0がリリースされており、実態にそぐわない記述になってしまいました。

読者への課題

PHP-Parserを使って、以下のようなソースコードを生成してみましょう。

<?php

echo 1;
print 2;
141
98
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
141
98