PHPのデバッグで使う print_r、var_dump、var_exportの動作の違い
2024/06/27
PHPのデバッグで使う print_r、var_dump、var_exportの動作の違い
PHPでプログラム開発を行う時のデバッグなどで変数の中身を確認する際に「print_r()」「var_dump()」「var_export()」「echo()」を使うかと思います。
人によって使う関数が異なり、たぶん、初めて使った関数を何気なくずっと使い続けているのではないかと思いますし、複数の関数を使い分けている方はほぼいないのではないかと思います。
と言うわけで、それぞれの関数にどのような特徴があるのか、調べてみました。
print_r、var_dump、var_exportの出力形式の違い
まずは、それぞれ配列を出力させてみて、どのような違いがあるかを確認します。
// 下記の配列を出力します。 $array = [ "aaa" => 123, "bbb" => "123", "ccc" => "123 ", "ddd" => "あああ", ]; print_r($array); var_dump($array); var_export($array);
出力結果は以下の通りとなりました。
// print_r($array);
Array
(
[aaa] => 123
[bbb] => 123
[ccc] => 123
[ddd] => あああ
)
// var_dump($array);
array(4) {
["aaa"]=>
int(123)
["bbb"]=>
string(3) "123"
["ccc"]=>
string(4) "123 "
["ddd"]=>
string(9) "あああ"
}
// var_export($array);
array (
'aaa' => 123,
'bbb' => '123',
'ccc' => '123 ',
'ddd' => 'あああ',
)
出力結果の違いとしては、以下のような感じです。
「print_r()」は、非常にシンプル。また、「ccc」にある空白が確認出来ないためデバッグに使うには問題がありそうです。
「var_dump()」は、数値と認識されているか、文字と認識されているかの違いや、文字数(桁数)も確認出来ます。また、「ccc」の空白も確認出来ます。
「var_export()」は、文字数は分かりませんが、「ccc」の空白を確認することができます。最大の特徴は、出力された配列をそのまま PHPの配列として再利用できる点です。
(入力した変数と同じ形式ですので、PHPの配列としてコピペして使用できます。)
ちなみに、「echo」は配列を扱えないため、デバッグに使用するにはかなり限定的な使用になるかと思います。
print_r、var_dump、var_exportの出力先の違い・戻り値を受け取れるか
「print_r()」「var_dump()」「var_export()」の機能の違いとしては、戻り値を返す機能があるかどうか、です。
デフォルトでは、いずれも標準出力(画面に出力)する使用になっていますが、画面に表示する内容を戻り値として受け取り、変数に格納することができるか否か、の機能が異なります。
「print_r()」「var_export()」は、戻り値を受け取ることが出来ます。
「var_dump()」は、戻り値を受け取る仕様がありません。
$response = print_r($array, true); $response = var_export($array, true);
「print_r()」「var_export()」は、上記のように第 2引数(パラメータ)に「true」を指定することで、標準出力ではなく、戻り値として戻すようになりますので、その値を変数に格納することが出来ます。
CakePHP4でログ出力に際しては、直接配列を扱えなくなりましたので、「var_export()」を使う必要が出てきましたが、CakePHP4のログ出力に関しては下記に記事を書いていますので併せて参考にしてください。
CakePHP4でロギングスコープやログレベルを使用してログを出し分ける方法を解説
print_r、var_dump、var_exportの動作の違いのまとめ
上記の違いから、デバッグをする際に標準出力を行って確認をする場合は、「var_dump()」「var_export()」が有用だと思います。
ですが、ログ出力をする際に戻り値を必要とする場合は、「var_export()」を使うことになります。
(「print_r()」では出力される情報が不足しているため、確実なデバッグには難があるといわざるを得ません。)
と言うわけで、デバッグに使うなら「var_export()」がオススメ!って事になりますね。
かく言う私は「print_r()」を使っていた
かく言う私は「print_r()」をずっと使っていましたが、他の関数の仕様を詳しく調べることなくこれまで過ごしてきました。
特に不便に思うこともなかったわけですが、CakePHP4でログ出力する際に配列を扱う場合は「var_export()」を使う使う必要があるため、『「print_r()」と「var_export()」は、何が違うんだ?』と思ったことがきっかけでした。
ですが、しっかり調べてみると、「print_r()」を使うメリットが見えないな、と改めて思った次第です。
参考サイト
「var_export()」
https://www.php.net/manual/ja/function.var-export.php
一番最初に「var_export() は、 渡された変数に関する構造化された情報を返します。この関数は var_dump() に似ていますが、 返される表現が有効な PHP コードであるところが異なります。」と書いてありますので、明確な目的がある関数ですね。
「print_r()」
https://www.php.net/manual/ja/function.print-r.php
「var_dump()」
https://www.php.net/manual/ja/function.var-dump.php
「ブラウザに直接結果を出力する すべてのものと同様に、出力制御関数 を使用してこの関数の出力をキャプチャーし、(例えば)文字列 (string)に保存することが可能です。」
と記載がある「出力制御(出力バッファリング)」に関しては下記に記事を書いていますので併せて参考にしてください。
ob_start、ob_get_contents関数でPHPの標準出力をバッファリング・変数に代入
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
-
PHPパーミッション変更のchmod関数・モードを変数で指定する方法
パーミッション変更関数であるchmod関数の第二引数、ファイルモードの指定に変数を使う場合は8進数に変換するoctdec関数を使って変換します。
-
-
QRコード(二次元バーコード)作成サービスを公開
QRコード(二次元バーコード)を生成するサービス。QRコードにする文字列を入力するだけで QRコードが簡単に作れる。オプションとして、画像サイズ、余白サイズ、エラー訂正レベルがある。
-
-
PHPで1ヵ月前、先月、今月1日、来月末の日付などの算出はDateTimeImmutableを使う
PHPには日時をオブジェクトとして生成する関数「DateTimeImmutable」「DateTime」が用意されている。これを利用して1ヶ月後、月初日、月末日、5日後などを指定して日付を取得できる。
-
-
ECCUBEの商品一覧ページのSEO対策!rel=”next” rel=”prev”を設定
Googleは関連あるページはその旨明示するよう求めています。ECCUBEの商品一覧ページでその求めに応じるための「rel=”next”」「rel=”prev”」について解説します。
-
-
ob_start、ob_get_contents関数でPHPの標準出力をバッファリング・変数に代入
標準出力をバッファリングし変数に代入することができるob_start()関数の解説。include()の処理をバッファリングすることで自由な場所に処理を記述することが可能。
-
-
ECCUBE mtb_constants initパラメータ設定の項目を追加する方法
ECCUBEのパラメータ設定で設定できる項目を追加する方法を説明します。
-
-
ECCUBE2.13.3で商品規格の在庫数が無制限から変更できないバグがある
2.13.3固有のバグである商品規格の在庫数の入力エリアがアクティブにならない不具合を解消する解説です。product_class.tplの2行を修正するだけの簡単対応です。
-
-
リダイレクトループが原因で「ERR_TOO_MANY_REDIRECTS」「このページを表示できません」が出たときの対策12事例+α
リダイレクトループ、自動転送設定ループの原因の解説とその対応方法を含め事例 12例を挙げて説明。
-
-
カオナビAPI Ver.2.0のtokenを取得する PHP+cURLのサンプルプログラム
PHPのcURLを使用してカオナビAPIのアクセスに必要なtoken、シートの情報を取得するサンプルプログラムを作成。cURLの処理は関数化しているため他のAPIでも流用できる。
-
-
include、requireのパス指定をdirname(__FILE__)、__DIR__と書く理由
include、requireのパスの指定を dirname(__FILE__)、__DIR__で記述する理由に付いて解説。相対パス、絶対パスを直書き、パスを書かない場合は何が問題かを説明。