はじめに
こちらは、PHP5上級試験/準上級試験まとめ の一環として、PHPの文字列について順を追って解説した記事です。
試験対象はPHP5ですが、PHP7くらいまでなら対応できるよう、汎用的な内容を心がけています。内容に間違いがある場合はご指摘ください。
なお2021年秋には PHP8技術者認定上級試験 が始まる予定ですので、最新情報は公式ページよりご確認ください。
文字列とは
文字列とは、文字通り(?)文字で構成された値のことですが、PHPで文字列を表現するには 'シングルクォート(引用符)'
や "ダブルクォート(二重引用符)"
で文字を囲う必要があります。
例えば 1
とだけ書かれた値は数値の1を表し、'1'
や "1"
と書かれた値は文字列としての1を表します。
(ヒアドキュメントやNowdocという機能で文字列を表現することもできますが、これについては後述します。)
echo 1; // 1
echo '1'; // 1
// どちらも出力されるのは 1 だが、内部的には数値の 1 か、文字の 1 かが区別されている
文字列内でシングルクォートやダブルクォートを使用したい場合はどうするかと言うと、エスケープシーケンスを使用します。エスケープシーケンスとは、プログラムにとって特別な意味を持つ文字の直前に \バックスラッシュ
を書くことによって、その文字のプログラム的な意味を無効化させることを言います。
ちなみにバックスラッシュという文字そのものも、他の文字をエスケープさせる特別な意味があるため、ただの文字として使用するにはバックスラッシュでバックスラッシュをエスケープする必要があります。(使用するOSによってはバックスラッシュが ¥
の記号で表される場合があります。)
echo '\\'; // \
シングルクォートとダブルクォートでは、エスケープシーケンスの使用できる文字に違いがあります。
シングルクォート内で可能なエスケープと使用例
- バックスラッシュ
\
→\\
- シングルクォート
'
→\'
ダブルクォート内で可能なエスケープと使用例
- バックスラッシュ
\
→\\
- ダブルクォート
"
→\"
- ドル記号
$
→\$
- 改行記号
n
→\n
- タブ記号
t
→\t
それ以外のエスエープシーケンスについてはPHPマニュアルを参照してください。
PHPマニュアル - 文字列
文字列内での変数展開について
シングルクォートやNowdoc内では変数展開(変数のパース、埋め込んだ変数の中身が展開されること)はされませんが、ダブルクォートやヒアドキュメント内では変数展開が行われます。
$str = 'test';
echo '$str'; // $str
$str = 'test';
echo "$str"; // test
ダブルクォートで囲っていても変数名のすぐ後に文字が続くと変数展開ができないので、その場合は {}
で変数の部分だけを囲います。
$str = 'テスト';
echo "今日は$strです。"; // [エラー] Notice: Undefined variable: strです。 in /sample/index.php on line 3
$str = 'テスト';
echo "今日は{$str}です。"; // 今日はテストです。
変数展開用の {}
記号は、下記のように$記号を外に出して書いても同様の結果となります。
$str = 'テスト';
echo "今日は${str}です。"; // 今日はテストです。
ヒアドキュメント
改行されて何行にも渡るような文字列を表すには、ヒアドキュメントという機能を利用するのが便利です。
コード内で <<<EOS
から始まり EOS;
で終わるようなセクションがヒアドキュメントになりますが、EOS (End of String)
のような終端IDは自由に命名可能です。命名規則は変数や関数と同様になります。
echo <<<EOS
<h1>タイトル</h1>
<p>段落</p>
<p>段落</p>
<p>段落</p>
EOS;
ヒアドキュメントの中で使用された変数は展開され、空白文字、改行、シングルクォート、ダブルクォートはそのまま出力されますが、最後の行末の改行だけは無視されます。
$str = 'テスト';
echo '<span>';
echo <<<EOS
$str
$str
EOS;
echo '<span>';
<span>テスト
テスト<span>
終端IDはインデントしたり、同じ行にコメントを書いたりはできません。ヒアドキュメントの終わりに記述できるのは、終端IDとセミコロンだけです。
<?php
echo '<span>';
echo <<<EOS
テスト
テスト
EOS;
echo '<span>';
Parse error: syntax error, unexpected end of file, expecting variable (T_VARIABLE) or heredoc end (T_END_HEREDOC) or ${ (T_DOLLAR_OPEN_CURLY_BRACES) or {$ (T_CURLY_OPEN) in /sample/index.php on line 8
(余談として、自分の環境で試したところPHP 5.4では終端IDをインデントするとエラーになり、PHP 7.3ではならなかったんですが、PHPの公式マニュアルでも「終端IDとセミコロンだけにしてね」と書いてあるので従っておくのが無難かなと思います。)
Nowdoc
ヒアドキュメントに似た機能ではNowdocというものがあり、ヒアドキュメントがダブルクォーテーションで文字列を囲ったときの動きに近いとすれば、Nowdocはシングルクォーテーションで文字列を囲ったときの動きに近くなります。PHP 5.3以降ならば利用可能で、Nowdoc開始時の終端IDをシングルクォーテーションで囲うことと、変数展開がされないこと以外は基本的にヒアドキュメントと同じ動きになります。
$str = 'テスト';
echo '<span>';
echo <<<'EOS'
$str
$str
EOS;
echo '<span>';
<span>$str
$str<span>
echoとprint
その他、今までのコードにも出てきていますが、文字列の出力には echo
print
printf
などを使用します。
厳密に言えば echo
や print
は関数ではなく言語構造であり、引数となる後ろ側の部分を丸カッコで囲っても囲わなくても機能します。
print 'Hello world!'; // Hello world!
print('Hello world!'); // Hello world!
echo 'Hello world!'; // Hello world!
echo('Hello world!'); // Hello world!
その他の言語構造についてはPHPマニュアルを参照してください。
echo
はカンマで区切って複数の値を引数として与えられますが、print
ではカンマ区切りの複数の値を与えることはできません。
また、echo
を使いカンマ区切りで複数の値を出力するときは、丸カッコで引数を囲うことはできません。
(複数の値を出力するときは、カンマを使わずドットで連結することの方が多いかもしれませんが。)
print 'Hello ', 'world!'; // [エラー] Parse error: syntax error, unexpected ',' in /sample/index.php on line 2
print('Hello ', 'world!'); // [エラー] Parse error: syntax error, unexpected ',' in /sample/index.php on line 2
echo 'Hello ', 'world!'; // Hello world!
echo('Hello ', 'world!'); // [エラー] Parse error: syntax error, unexpected ',' in /sample/index.php on line 2
echo
と print
の違いとして他には、print
には返り値があり、常に数値の 1
を返すため式の一部として使うことができますが、 echo
には返り値がありません。
if(echo 'echo'){
echo 'OK';
}
// [エラー] Parse error: syntax error, unexpected 'echo' (T_ECHO) in /sample/index.php on line 2
true ? echo 'OK' : echo 'NG';
// [エラー] Parse error: syntax error, unexpected 'echo' (T_ECHO) in /sample/index.php on line 3
if(print 'print'){
print 'OK';
}
// printOK
true ? print 'OK' : print 'NG';
// OK
echo
と print
の違いについては別な記事でもまとめているので、興味のある方は読んでみてください。
PHP : echoとprintの違い
printf
printf()
は、言語構造ではなく組み込み関数で、書式文字列を使って文字列をフォーマットすることができます。
書式文字列は 置換マーク %
で始まり、修飾子 02
-5
などは必要に応じて付け、型指定子 d
s
などで終わります。
printf('[置換マーク][修飾子][型指定子]');
printf('%d',9); // 9 // dは10進数のdecimalを表す型指定子
printf('%2d',9); // 9 // 9の直前に空白が置かれて2桁になっている
printf('%02d',9); // 09 // 2桁で出力し、足りない桁数は0で埋める
printf('%f', 3.14); // 3.140000 // fは浮動小数点数のfloatを表す型指定子
printf('%1.2f', 3.14); // 3.14 // 整数1桁.小数2桁
printf('%s','Hello world!'); // Hello world! // sは文字列のstringを表す型指定子
printf('%12s','world!'); // world! // 文字列の前に空白が置かれ12桁になっている
printf('%-12s','Hello'); // Hello // 文字列の後に空白が置かれ12桁になっている
printf('%d%s%d%s', 1, '年', 1, '組'); // 1年1組 // 左から順に対応する引数を出力
printf('%%'); // % // %文字を出力
より詳しい printf()
の仕様はマニュアルを確認してください。
PHPマニュアル - printf — フォーマット済みの文字列を出力する
print_r と var_dump
print_r()
や var_dump()
を使用すると、変数の値などをデバッグ用にわかりやすく出力してくれます。
パッと見で読みやすいのは print_r()
かもしれませんが、var_dump()
の方はデータ型や null
false
もきちんと文字列で出力してくれます。
可読性優先だったら print_r()
、より詳細に情報を出力したいときは var_dump()
を使うと良いでしょう。
$array = array( null, false, 'string', 1 );
var_dump($array);
print_r($array);
Array ( [0] => [1] => [2] => string [3] => 1 )
array(4) { [0]=> NULL [1]=> bool(false) [2]=> string(6) "string" [3]=> int(1) }
strlenとmb_strlen
strlen()
と mb_strlen()
では、文字列の文字数を調べることができます。
日本語の文字はマルチバイト文字といって通常の半角英数字とは異なるので、マルチバイト文字の文字数を調べたいときは mb_strlen()
の方を使います。
echo strlen('Hello!'); // 6
echo strlen('こんにちは!'); // 18 // strlenで日本語の文字数は数えられない
echo mb_strlen('Hello!'); // 6 // mb_strlenでは半角英数も対応する
echo mb_strlen('こんにちは!'); // 6
PHPマニュアル - strlen — 文字列の長さを得る
PHPマニュアル - mb_strlen — 文字列の長さを得る
マニュアルにもありますが、strlen()
というのは厳密には文字のバイト数(大きさ、容量のようなもの)を調べる組み込み関数です。
半角英数字は1文字1バイトなので バイト数=文字数 と読み替えても不都合はあまりありませんが、日本語のようなマルチバイト文字というのは1文字が3バイトとか4バイトしたりすることもあるので、strlen()
でバイト数を調べると文字数よりも大きな数値が出てしまうということになります。
trim / ltrim / rtrim
trim()
ltrim()
rtrim()
のそれぞれの関数は、文字列から特定の文字を削除してくれます。
trim()
は文字列の両端から削除、ltrim()
は文字列の左側(left)のみ削除、rtrim()
は文字列の右側(right)のみ削除します。
第一引数には削除処理を適用したい文字列、第二引数には削除したい文字を指定することができます。第二引数は省略することも可能で、省略した場合は 空白, タブ, リターン, 改行, NULバイト, 垂直タブ を削除します。
echo trim(' Hello '); // Hello // 文字列の左右両側から空白文字が除去される
ちなみに削除する文字を指定する際、trim('Hello','He')
などとした場合は He
という文字列を削除するのではなく、H
と e
の文字を削除しようとします。trim('Hello','Hel')
などとした場合は Hel
という文字列ではなく H
と e
と l
の文字を削除しようとするので、次の2つ目の例では l
が2文字とも削除されて o
だけが残っています。
echo trim('Hello','He'); // llo
echo trim('Hello','Hel'); // o
PHPマニュアル - trim — 文字列の先頭および末尾にあるホワイトスペースを取り除く
PHPマニュアル - ltrim — 文字列の最初から空白 (もしくはその他の文字) を取り除く
PHPマニュアル - rtrim — 文字列の最後から空白 (もしくはその他の文字) を取り除く
strtolower / strtoupper / ucfirst / ucwords
大文字・小文字を変換するには、strtolower()
strtoupper()
ucfirst()
ucwords()
などの関数が便利です。
strtolower()
は、引数に与えられた文字列の中でアルファベットの部分をすべて小文字にして返します。
echo strtolower('Hello World!'); // hello world!
strtoupper()
は、引数に与えられた文字列の中でアルファベットの部分をすべて大文字にして返します。
echo strtoupper('Hello World!'); // HELLO WORLD!
ucfirst()
は、引数に与えられた文字列の最初の文字がアルファベットの場合に、それを大文字にします。
echo ucfirst('hello world!'); // Hello world!
echo ucfirst('こんにちは world!'); // こんにちは world! // 1文字目がアルファベットでないため変化なし
ucwords()
は、引数に与えられた文字列のアルファベットにおいて、各単語の1文字目を大文字にします。各単語の区切りはデフォルトだと空白文字や改行などですが、第二引数に区切り文字を指定すると、指定の区切り文字の直後が大文字に変換されるようになります。
echo ucwords('hello world!'); // Hello World! // 半角スペースを区切りと認識
echo ucwords("hello \nworld!"); // Hello World! // 改行(\n)を区切りと認識
echo ucwords('hello world!', 'l'); // HelLo worlD! // l(エル)を区切りと認識
PHPマニュアル - strtolower — 文字列を小文字にする
PHPマニュアル - strtoupper — 文字列を大文字にする
PHPマニュアル - ucfirst — 文字列の最初の文字を大文字にする
PHPマニュアル - ucwords — 文字列の各単語の最初の文字を大文字にする
参考URL
PHPの変数展開は、{$variable}構文を使うのがいいみたいです
PHP 文字列リテラルにおける変数展開ノ全テ
浮動小数点って何?