文字列
string は、文字が連結されたものです。PHP では、
文字は 1 バイトと同じです。つまり、256 個の異なる文字を使用可能です。
これは、PHP が Unicode をネイティブにサポートしていないことも意味します。
いくつかの Unicode サポートについてはutf8_encode()
および utf8_decode() を参照してください。
注意:
文字列が非常に大きくなっても問題ありません。
PHP に課せられる文字列のサイズの実用上の制限はありません。
このため、長い文字列に関して恐れる必要は全くありません。
構文
文字列リテラルは、4 つの異なる方法で指定することが可能です。
引用符
文字列を指定する最も簡単な方法は、引用符 (文字
') で括ることです。
引用符をリテラルとして指定するには、多くの他の言語と同様にバックスラッシュ
(\) でエスケープする必要があります。
バックスラッシュを引用符の前または文字列の最後に置きたい場合は、
二重にする必要があります。この他の文字をエスケープする場合には、
バックスラッシュも出力されることに注意してください! このため、
通常はバックスラッシュ自体をエスケープする必要はありません。
注意:
他の三つの構文と異なり、
変数と特殊文字のエスケープシーケンスは、
引用符 (シングルクオート) で括られた文字列にある場合には展開されません。
二重引用符
文字列が二重引用符 (") で括られた場合、
PHP は、より多くの特殊文字のエスケープシーケンスを理解します。
エスケープされた文字
| 記述 |
意味 |
| \n |
ラインフィード (LF またはアスキーの 0x0A (10)) |
| \r |
キャリッジリターン (CR またはアスキーの 0x0D (13)) |
| \t |
水平タブ (HT またはアスキーの 0x09 (9)) |
| \v |
垂直タブ (VT またはアスキーの 0x0B (11)) (PHP 5.2.5 以降) |
| \f |
フォームフィード (FF またはアスキーの 0x0C (12)) (PHP 5.2.5 以降) |
| \\ |
バックスラッシュ |
| \$ |
ドル記号 |
| \" |
二重引用符 |
| \[0-7]{1,3} |
正規表現にマッチする文字シーケンスは、8 進数表記の 1 文字です。
|
| \x[0-9A-Fa-f]{1,2} |
正規表現にマッチする文字シーケンスは、16 進数表記の 1 文字です。
|
繰り返しますが、この他の文字をエスケープしようとした場合には、
バックスラッシュも出力されます!
PHP 5.1.1 より前のバージョンでは、\{$var}
のバックスラッシュは出力されません。
しかし、二重引用符で括られた文字列で最も重要なのは、
変数名が展開されるところです。詳細は、文字列のパースを参照ください。
ヒアドキュメント
文字列を区切る別の方法としてヒアドキュメント構文 ("<<<")
があります。この場合、ある ID (と、それに続けて改行文字)
を <<<
の後に指定し、文字列を置いた後で、同じ ID を括りを閉じるために置きます。
終端 ID は、その行の最初のカラムから始める必要があります。
使用するラベルは、PHP の他のラベルと同様の命名規則に従う必要があります。
つまり、英数字およびアンダースコアのみを含み、
数字でない文字またはアンダースコアで始まる必要があります。
警告
非常に重要なことですが、終端 ID がある行には、セミコロン
(;) 以外の他の文字が含まれていてはならないことに注意しましょう。
これは、特に ID はインデントしてはならないということ、
セミコロンの前に空白やタブを付けてはいけないことを意味します。
終端 ID の前の最初の文字は、使用するオペレーティングシステムで定義された
改行である必要があることにも注意を要します。
これは、例えば、Macintoshでは \r となります。
最後の区切り文字 (たいていはその後にセミコロンが続きます)
の後にもまた、改行を入れる必要があります。
この規則が破られて終端 ID が "clean" でない場合、
終端 ID と認識されず、PHP はさらに終端 ID を探し続けます。
適当な終了 ID がみつからない場合、
スクリプトの最終行でパースエラーが発生します。
ヒアドキュメント構文を、クラスのプロパティの初期化に用いることはできません。
PHP 5.3 以降では、変数を含まないヒアドキュメントではこの制約はなくなりました。
例1 間違った例
<?php
class foo {
public $bar = <<<EOT
bar
EOT;
}
?>
ヒアドキュメントは二重引用符を使用しませんが、
二重引用符で括られた文字列と全く同様に動作します。
しかし、この場合でも上記のリストでエスケープされたコードを使用することも可能です。
変数は展開されますが、文字列の場合と同様に
ヒアドキュメントの内部で複雑な変数を表わす場合には注意が必要です。
例2 ヒアドキュメントで文字列を括る例
<?php
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;
/* 変数を使用するより複雑な例 */
class foo
{
var $foo;
var $bar;
function foo()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'MyName';
echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;
?>
上の例の出力は以下となります。
My name is "MyName". I am printing some Foo.
Now, I am printing some Bar2.
This should print a capital 'A': A
ヒアドキュメント構文を用いて、
関数の引数にデータを渡すこともできます。
例3 ヒアドキュメントを引数に使用する例
<?php
var_dump(array(<<<EOD
foobar!
EOD
));
?>
PHP 5.3.0 以降、静的な変数やクラスのプロパティ/定数を
ヒアドキュメント構文で初期化できるようになりました。
例4 ヒアドキュメントを用いた静的な値の初期化
<?php
// 静的変数
function foo()
{
static $bar = <<<LABEL
Nothing in here...
LABEL;
}
// クラスのプロパティ/定数
class foo
{
const BAR = <<<FOOBAR
Constant example
FOOBAR;
public $baz = <<<FOOBAR
Property example
FOOBAR;
}
?>
PHP 5.3.0 では、ヒアドキュメントの宣言でダブルクォートを使用できるようにもなりました。
例5 ヒアドキュメントでのダブルクォート
<?php
echo <<<"FOOBAR"
Hello World!
FOOBAR;
?>
注意:
ヒアドキュメントは PHP 4 で追加されました。
Nowdoc
Nowdoc はヒアドキュメントと似ていますが、
ヒアドキュメントがダブルクォートで囲んだ文字列として扱われるのに対して、
Nowdoc はシングルクォートで囲んだ文字列として扱われます。
Nowdoc の使用方法はヒアドキュメントとほぼ同じですが、
その中身について パース処理を行いません。
PHP のコードや大量のテキストを埋め込む際に、
エスケープが不要になるので便利です。この機能は、SGML の
<![CDATA[ ]]>
(ブロック内のテキストをパースしないことを宣言する)
と同じようなものです。
Nowdoc の書き方は、ヒアドキュメントと同じように
<<< を使用します。
しかし、その後に続く識別子をシングルクォートで囲んで
<<<'EOT' のようにします。
ヒアドキュメントの識別子に関する決まりがすべて Nowdoc
の識別子にも当てはまります。特に終了識別子の書き方に関する決まりに注意しましょう。
例6 Nowdoc による文字列のクォートの例
<?php
$str = <<<'EOD'
Example of string
spanning multiple lines
using nowdoc syntax.
EOD;
/* 変数を使った、より複雑な例 */
class foo
{
public $foo;
public $bar;
function foo()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'MyName';
echo <<<'EOT'
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41
EOT;
?>
上の例の出力は以下となります。
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41
注意:
ヒアドキュメントと異なり、Nowdoc は任意の静的データコンテキストで使用できます。
典型的な使用例は、クラスのプロパティや定数の初期化です。
例7 静的データの例
<?php
class foo {
public $bar = <<<'EOT'
bar
EOT;
}
?>
注意:
Nowdoc のサポートは PHP 5.3.0 で追加されました。
変数のパース
スクリプトが二重引用符で括られるかヒアドキュメントで指定された場合、
その中の変数はパースされます。
構文の型には、単純な構文と
複雑な
構文の 2 種類があります。簡単な構文は、最も一般的で便利です。
この構文では、変数、配列値やオブジェクトのプロパティをパースすることが可能です。
複雑な構文は、PHP 4 で導入されました。
この構文は、式を波括弧で括ることにより認識されます。
簡単な構文
ドル記号 ($) を見付けると、
パーサは、有効な変数名を形成することが可能な最長のトークンを取得します。
変数名の終りを明示的に指定したい場合は、変数名を波括弧で括ってください。
同様に、配列添字とオブジェクトのプロパティをパースすることも可能です。
配列添字の場合、閉じ角括弧 (']') は添字の終りを意味し、
オブジェクトのプロパティの場合、同じ規則が簡単な変数として適用されます。
しかし、オブジェクトプロパティには、変数の場合のような手法はありません。
より複雑な場合は、複雑な構文を使用する必要があります。
複雑な (波括弧) 構文
この構文が「複雑(complex)な構文」と呼ばれているのは、
構文が複雑であるからではなく、
この方法では複雑な式を含めることができるからです。
事実、この構文により、文字列の中に名前空間内のあらゆる値を含めることが可能です。
文字列の外側に置く場合と同様に式を書き、これを
{ と } の間に含めてください。'{' はエスケープすることができないため、
この構文は $ が { のすぐ後に続く場合にのみ認識されます
(リテラル "{$" を指定するには、"{\$" を使用してください)。
以下のいくつかの例を見ると理解しやすくなるでしょう。
文字列内で、変数を使ってクラスのプロパティにアクセスすることもできます。
このような構文を使います。
注意:
{$} の内部における
関数やメソッドのコール、静的クラス変数、クラス定数は、PHP 5 から動作します。
しかし、アクセスする値は文字列が定義されたスコープにおける変数名として解釈します。
ひとつの波括弧 ({}) では、
関数やメソッドの返り値、クラス定数や静的クラス変数の値にはアクセスできません。
文字列への文字単位のアクセスと修正
$str[42] のように、
角括弧を使用してゼロから始まるオフセットを指定すると、
文字列内の任意の文字にアクセスし、修正することが可能です。
つまり、文字列を文字の配列として考えるわけです。
複数の文字を取り出したり変更したりしたいときは、関数
substr() および substr_replace()
が使えます。
注意:
$str{42} のように波括弧を使用してアクセスすることも可能です。
しかし、角括弧を使用する方法を推奨します。
なぜなら、{波括弧} 形式は PHP 5.3.0 で非推奨となったからです。かわりに、
$str[42] のように角括弧を使うようにしましょう。
警告
範囲外のオフセットに書き込んだ場合は、空いた部分に空白文字が埋められます。
整数型以外の型は整数型に変換されます。
無効なオフセット形式を指定した場合は E_NOTICE を発行します。
負のオフセットを指定した場合は、書き込み時は E_NOTICE
を発行しますが読み込み時は空の文字列を返します。
文字列を代入した場合は最初の文字だけを使用します。
空文字列を代入した場合は NUL バイトを代入します。
例8 文字列の例
<?php
// 文字列の最初の文字を取得します
$str = 'This is a test.';
$first = $str[0];
// 文字列の 3 番目の文字を取得します
$third = $str[2];
// 文字列の最後の文字を取得します
$str = 'This is still a test.';
$last = $str[strlen($str)-1];
// 文字列の最後の文字を変更します
$str = 'Look at the sea';
$str[strlen($str)-1] = 'e';
// {} を使用した、もうひとつの方法 (PHP 6 で廃止予定) です
$third = $str{2};
?>
注意:
その他の型の変数に対して [] や {}
でアクセスすると、何もメッセージを出さずに単に NULL を返します。
便利な関数および演算子
文字列は、'.' (ドット) 結合演算子で結合することが可能です。'+'
(加算) 演算子はこの例では出てこないことに注意してください。詳細については
文字列演算子
を参照ください。
文字列の修正を行う場合には、便利な関数がたくさん用意されています。
一般的な関数については、文字列関数の節
を参照ください。高度な検索/置換を行う正規表現関数については
Perl および
POSIX 拡張 の 2 種類がありますが、
それぞれの節を参照ください。
URL 文字列用関数や文字列の暗号化/
復号用の関数 (mcrypt および
mhash) もあります。
最後に、探しているものがまだ見付からない場合には、
文字型の関数も参照ください。
文字列への変換
(string) キャストや strval()
関数を使って変数を文字列へ変換することができます。
文字列型を必要とする式のスコープにおいて、文字列への変換は自動的に行われます。
echo() や print() 関数を使うとき、
あるいは可変変数を文字列を比較するときにこの自動変換が行われます。
マニュアルの型 と
型の相互変換
の項を読むとわかりやすいでしょう。
settype()も参照してください。
boolean の TRUE は文字列の "1" に、
FALSE は "" (空文字列) に変換されます。
これにより boolean と文字列の値を相互に変換することができます。
integer (整数) や浮動小数点数 ( float ) は
その数値の数字として文字列に変換されます (指数の表記や浮動小数点数を含めて)。
浮動小数点数は、指数表記
(4.1E+6) を使用して変換されます。
注意:
小数点を表す文字は、スクリプトのロケール (LC_NUMERIC カテゴリ)
によって決まります。
setlocale() を参照ください。
配列は常に "Array" という文字列に変換されるので、
array の中を見るために echo() や
print() を使ってダンプさせることはできません。
一つの要素を見るためには、echo $arr['foo']
のようにしてください。内容の全てをダンプ/見るためには以降の TIP をご覧ください。
PHP 4 のオブジェクトは、常に "Object" という文字列に変換されます。
デバッグ等のために object の内部の変数を出力するような場合には、
以下をご覧ください。オブジェクトがなんという名前のクラスの
インスタンスなのかを知るには get_class() をご覧ください。
PHP 5 以降では、もし存在すれば __toString() メソッドを使用します。
リソースは常に "Resource id #1"
という文字列に変換されます。1 は実行中の
PHP によって割り当てられる
resource のユニークな番号です。
リソースの型を知るためには get_resource_type()
を使用してください。
NULL は常に空文字列に変換されます。
以上に述べたように、配列、オブジェクト、リソースをプリントアウトしても
その値に関する有益な情報を得られるわけではありません。
デバッグのために値を出力するのによりよい方法が知りたければ、
print_r() や
var_dump() を参照ください。
PHP 変数を恒久的に保存するための文字列に変換することもできます。
この方法はシリアライゼーションと呼ばれ、
serialize() 関数によって実現できます。
WDDX サポートを有効にして PHP
をセットアップすれば、PHP 変数を XML 構造にシリアライズすることもできます。
文字列の数値への変換
数値として文字列が評価された時、結果の値と型は次のように定義されます。
文字列の中に '.' や 'e'、'E' といった文字が含まれず、
数値が integer 型の範囲内 (PHP_INT_MAX
で定義されています) におさまる場合は
integer として評価されます。それ以外の場合は、すべて
float として評価されます。
文字列の最初の部分により値が決まります。文字列が、
有効な数値データから始まる場合、この値が使用されます。その他の場合、
値は 0 (ゼロ) となります。有効な数値データは符号(オプション)の後に、
1 つ以上の数字 (オプションとして小数点を 1 つ含む)、
オプションとして指数部が続きます。指数部は 'e' または 'E' の後に
1 つ以上の数字が続く形式です。
この変換に関する詳細は、Unix のマニュアルページで
strtod(3) を参照ください。
本節の例を試したい場合、その例をカットアンドペーストしてから
動作を確認するために次の行を挿入してください。
(C 言語で行われるように) 数値に変換することで
一つの文字のコードを取得できると期待してはいけません。
文字と文字コードを相互に変換するには ord()
および chr() 関数を使用してください。