【PHP】特殊文字をシングルクォーテーションで囲むのは危険!

公開日:
更新日:
カテゴリー: PHP

PHPでコードを書くとき「シングルクォーテーション」と「ダブルクォーテーション」の違いを意識して書いていますか?

私は恥ずかしながらいい加減な性格で、特に明確な区別をせずに使っており、本日、単純で大きなミスに気づきました。

「シングルクォーテーション」と「ダブルクォーテーション」の違い

PHPをやり始めたときに「シングルクォーテーション」と「ダブルクォーテーション」の違いを学びました。

どのような違いがあるかというと、シングルクォーテーションは特殊文字を「文字列」として処理します。

そのため、特殊文字(ここでは例として改行コード「\n」)を含む文字列をシングルクォーテーションで囲んで出力すると

//特殊文字である改行コード「\n」を含む文字列
$str = 'あいうえお\nかきくけこ\nさしすせそ\nたちつてと';

//出力
echo $str;

このように、特殊文字(改行コード)が文字列として出力されます。

あいうえお\nかきくけこ\nさしすせそ\nたちつてと

一方、ダブルクォーテーションの場合だと、

//特殊文字である改行コード「\n」を含む文字列
$str = "あいうえお\nかきくけこ\nさしすせそ\nたちつてと";

//出力
echo $str;

特殊文字(改行コード)は特殊文字として出力されます。

あいうえお
かきくけこ
さしすせそ
たちつてと

「シングルクォーテーション」と「ダブルクォーテーション」の違いはあともう一つあって、ある変数をシングルクォーテーションで囲むと「文字列」として扱われ、ダブルクォーテーションで囲むと「変数」として扱われます。

ここは本題ではないのでさっくり説明すると、

//変数「$hoge」の定義
$hoge = "ほげ";

//シングルクォーテーションで囲む
$str = 'シングルクォーテーションの場合は$hoge';

//出力
echo $str;

この結果はこのようになります。

シングルクォーテーションの場合は$hoge

次にダブルクォーテーションで囲むと

//変数「$hoge」の定義
$hoge = "ほげ";

//ダブルクォーテーションで囲む
$str = "ダブルクォーテーションの場合は$hoge";

//出力
echo $str;

この結果はこのようになります。

ダブルクォーテーションの場合はほげ

特殊文字をシングルクォーテーションで囲むミス

ここまでは知識のところで、「シングルクォーテーション」と「ダブルクォーテーション」の違いはある程度私も把握していました。

しかし実用段階では全く意識できておらず、【PHP】改行コードを置換して配列に格納するにあるように、次のようなミスを犯していました(説明を簡略化するために一部変更)。

改行コードで区切って配列に格納

改行コード「\n」を含む文字列を、explode関数を使って「\n」で区切ってみたいと思います。

まずはダブルクォーテーションの場合だと、

//特殊文字である改行コード「\n」を含む文字列
$str = "あいうえお\nかきくけこ\nさしすせそ\nたちつてと";

//改行コード「\n」で配列に格納
$array = explode("\n", $str);

//出力
print_r($array);

改行コードで区切られてちゃんと配列に納まっています。

Array
(
    [0] => あいうえお
    [1] => かきくけこ
    [2] => さしすせそ
    [3] => たちつてと
)

次にシングルクォーテーションの場合だと、

//特殊文字である改行コード「\n」を含む文字列
$str = 'あいうえお\nかきくけこ\nさしすせそ\nたちつてと';

//改行コード「\n」で配列に格納
$array = explode("\n", $str);

//出力
print_r($array);

文字列をシングルクォーテーションで囲んだため、特殊文字は文字列として扱われ、うまく配列に格納できません。

Array
(
    [0] => あいうえお\nかきくけこ\nさしすせそ\nたちつてと
)

では、次は発想を変えて文字列「$str」はダブルクォーテーションで、explode間数の第一引数はシングルクォーテーションで囲んでみたいと思います。

//特殊文字である改行コード「\n」を含む文字列
$str = "あいうえお\nかきくけこ\nさしすせそ\nたちつてと";

//改行コード「\n」で配列に格納
$array = explode('\n', $str);

//出力
print_r($array);

この場合、こうなります。

Array
(
    [0] => あいうえお
かきくけこ
さしすせそ
たちつてと
)

これはなぜかというと、文字列「$str」はダブルクォーテーションで囲まれているので特殊文字「\n」は特殊文字として扱われ、explode間数の第一引数「\n」はシングルクォーテーションで囲まれているので文字列として扱われ、そもそもマッチしないため上手く機能しませんでした。

次に、文字列「$str」はシングルクォーテーションで、explode間数の第一引数もシングルクォーテーションで囲んでみたいと思います。

これはどうなるかわかりますよね?

//特殊文字である改行コード「\n」を含む文字列
$str = 'あいうえお\nかきくけこ\nさしすせそ\nたちつてと';

//改行コード「\n」で配列に格納
$array = explode('\n', $str);

//出力
print_r($array);

この場合、こうなります。

Array
(
    [0] => あいうえお
    [1] => かきくけこ
    [2] => さしすせそ
    [3] => たちつてと
)

これはなぜかというと、文字列「$str」はシングルクォーテーションで囲まれているので特殊文字「\n」は文字列として扱われ、explode間数の第一引数「\n」もシングルクォーテーションで囲まれているので文字列として扱われ、マッチしてexplode関数が機能しました。

まとめ

以上のように、特殊文字をシングルクォーテーションで囲むと「文字列」として扱われるので、今後コードを組むときは明確に

  • シングルクォーテーション
  • ダブルクォーテーション

の違いを意識してプログラムしないと意図した動きにならないだけでなく、ミスをミスとして気づけず無駄な労力がかかる危険性があります。

普段から意識できている人にとっては常識だったと思いますが、私みたいな大雑把な人間は今回の失敗を肝に銘じて置こうと思います。

 

あわせて読んでほしい!

 

コメント

まだコメントはありません。

コメントフォーム
お名前
コメント