PHPのstring(文字列)型

PHPで文字列を扱う際には、string型を使用します。PHPの文字列は可変長文字列であるため、文字列の長さを気にする必要はありません。変数をstring型として初期化するには、いくつか方法があります。

シングルクォート・ダブルクォート

まず簡単な手法として、シングルクォートまたはダブルクォートで括られた文字列はstring型となります。ダブルクォート内に変数があった場合、変数に格納されている値が展開されます。これを変数展開と言います。同様にダブルクォート内ではエスケープ文字も展開されます。一方、シングルクォート内では、変数やエスケープ文字は展開されません。

下記の例では、ダブルクォート内の変数は展開されて出力されますが、シングルクォート内の変数は、そのまま文字列として出力されます。また、ダブルクォート内にダブルクォートを入れる場合やシングルクォート内にシングルクォートを入れる場合は、エスケープする必要があります。

PHP

<?php
$string_00 = 'world';
var_dump($string_00); // 出力:string(5) "world"
var_dump("He said \"Hello $string_00\""); // 出力:string(21) "He said "Hello world""
var_dump('He said "Hello $string_00"'); // 出力:string(26) "He said "Hello $string_00""
?>

ダブルクォート内で変数を展開させる際、その後ろにPHPの識別子として使える文字列が続くと、どこまでが変数名か解らなくなります。この場合、変数名を波括弧{}で囲うことにより、どこまでが変数名かを明示することができます。下記コードの3行目では、$string_02yearsという変数名と解釈されてエラーが出力されますが、4行目では変数を波括弧{}で囲っているので、正しく出力できています。

PHP

<?php
$string_01 = 'I\'m';
$string_02 = "17";
var_dump("$string_01 $string_02years old."); // 出力:Notice: Undefined variable: string_02years
var_dump("$string_01 ${string_02}years old."); // 出力:string(16) "I'm 17years old."
?>

ヒアドキュメント

PHPでは、複数行の文字列をstring型として手軽に扱うためにヒアドキュメントという構文が用意されています。ヒアドキュメントでは、まずヒアドキュメント構文<<<の後に終端IDを指定し、次にその終端IDが行頭にくるまでが文字列となります。

ヒアドキュメント内では、変数は展開されますが、ダブルクォートはそのまま出力されます。ダブルクォートをエスケープする必要がないため、HTMLの記述が楽になります。

PHP

<?php
$string_03 = 'I\'m';
$string_04 = "17";
$string_05 = <<<EOHD
\n<p>
ヒアドキュメントでは、複数行のテキストをそのまま記述できます。<br />
<span style="color:#FF0000;">
$string_03 ${string_04}years old.
</span>
</p>\n
EOHD;
var_dump($string_05);
/* 出力:
string(170) "
<p>
ヒアドキュメントでは、複数行のテキストをそのまま記述できます。<br />
<span style="color:#FF0000;">
I'm 17years old.
</span>
</p>
"
*/
?>

Nowdoc

PHP5.3からは、ヒアドキュメントと似たNowdoc構文を使用することができます。Nowdocでは、<<<に続く終端IDをシングルクォートで括ります。ヒアドキュメントと違い、Nowdoc内では変数やエスケープ文字は展開されません。下記コードでは、Nowdoc内の変数やエスケープ文字が展開されず、そのまま文字列として出力されていることが確認できます。

PHP

<?php
$string_06 = 'I\'m';
$string_07 = "17";
$string_08 = <<<'EOND'
\n<p>
Nowdocも複数行のテキストをそのまま記述できます。<br />
<span style="color:#FF0000;">
$string_06 ${string_07}years old.
</span>
</p>\n
EOND;
var_dump($string_08);
/* 出力:
string(165) "\n<p>
Nowdocも複数行のテキストをそのまま記述できます。<br />
<span style="color:#FF0000;">
$string_06 ${string_07}years old.
</span>
</p>\n"
*/
?>

string型へのキャスト

string型へ明示的にキャストする場合は、(string)またはstrval()を使用します。まず、float型からstring型へキャストしてみます。数値を文字列に型変換した場合、基本的にはその数値の文字列となりますが、7.0をキャストした結果が"7"である点には注意が必要です。

PHP

<?php
$string_09 = (string)7.0;
var_dump($string_09); // 出力:string(1) "7"

$string_10 = strval(7.1);
var_dump($string_10); // 出力:string(3) "7.1"

$string_11 = (string)7e2;
var_dump($string_11); // 出力:string(3) "700"
?>

論理型を文字列型に型変換した場合は、TRUEは"1"、FALSEは""(空文字列)となります。

PHP

<?php
$string_12 = strval(TRUE);
var_dump($string_12); // 出力:string(1) "1"

$string_13 = (string)FALSE;
var_dump($string_13); // 出力:string(0) ""
?>

string型の比較演算における注意点

PHPでは、異なる型で演算を行った場合など、自動的にキャストして処理を行ってくれます。これは便利である反面、よく理解していないと思わぬバグを生むことになりかねません。特にstring型の比較演算においては注意が必要です。

例として、PHPマニュアル:比較演算子にも記載されていますが、下記コードの比較演算では、すべてtrueが出力されます。

PHP

<?php
var_dump(0 == "a"); // 出力:bool(true)
var_dump("1" == "01"); // 出力:bool(true)
var_dump("10" == "1e1"); // 出力:bool(true)
var_dump(100 == "1e2"); // 出力:bool(true)
?>

以上の結果から、特にstring型の比較演算においては、できる限り===による厳密な比較演算をするべきだと感じました。