文字列

string は一連の文字です。PHPでは、文字は1バイトと同じ です。つまり、256個の異なる文字を使用可能です。これは、PHPは、 Unicodeをネーティブにサポートしていないことも意味します。 いくつかのUnicodeサポートについてはutf8_encode() および utf8_decode()を参照して下さい。

注意: 文字列が非常に大きくなっても問題ありません。PHPに課せられる文字列 のサイズの実用上の制限はありません。このため、長い文字列に関して 恐れる必要は全くありません。

構文

文字列リテラルは、3つの異なる方法で指定することが可能です。

引用符

文字列を指定する最も簡単な方法は、引用符(文字 ')で括ることです。

引用符をリテラルとして指定するには、多くの他の言語と同様にバック スラッシュ(\)でエスケープする必要があります。 バックスラッシュを引用符の前または文字列の最後に置きたい場合は、 2重にする必要があります。この他の文字をエスケープする場合には、 バックスラッシュも出力されることに注意して下さい! このため、通常、 バックスラッシュ自体をエスケープする必要はありません。

注意: PHP 3では、この場合、E_NOTICEレベルの警告が 出力されます。

注意: 他の二つの構文と異なり、 変数と特殊文字のエス ケープシーケンスは、引用符(シングルクオート)で括られた文字列に ある場合には展開されません

<?php
echo 'this is a simple string';

echo
'You can also have embedded newlines in
strings this way as it is
okay to do'
;

// Outputs: Arnold once said: "I'll be back"
echo 'Arnold once said: "I\'ll be back"';

// Outputs: You deleted C:\*.*?
echo 'You deleted C:\\*.*?';

// Outputs: You deleted C:\*.*?
echo 'You deleted C:\*.*?';

// Outputs: This will not expand: \n a newline
echo 'This will not expand: \n a newline';

// Outputs: Variables do not $expand $either
echo 'Variables do not $expand $either';
?>

2重引用符

文字列が2重引用符(")で括られた場合, PHPはより多くの特殊文字のエ スケープシーケンスを理解します。

表 6-1. エスケープされた文字

記述意味
\nラインフィード(LFまたはアスキーの0x0A (10))
\rキャリッジリターン (CRまたはアスキーの0x0D (13))
\t水平タブ(HTまたはアスキーの0x09 (9))
\\バックスラッシュ
\$ドル記号
\"2重引用符
\[0-7]{1,3} 正規表現にマッチする文字シーケンスは、8進数表記の1文字です。
\x[0-9A-Fa-f]{1,2} 正規表現にマッチする文字シーケンスは、16進数表記の1文字です。

繰り返しますが、この他の文字をエスケープしようとした場合には、バッ クスラッシュも出力されます!

しかし、二重引用符で括られた文字列で最も重要なのは、変数名が展開 されるところです。詳細は、文字列のパースを 参照下さい。

ヒアドキュメント

文字列を区切る別の方法としてヒアドキュメント構文("<<<") があります。この場合、あるIDを<<<の後 に指定し、文字列を置いた後で、同じIDを括りを閉じるために置きます。

終端IDは、その行の最初のカラムから始める必要があります。使用するラ ベルは、PHPの他のラベルと同様の名前に関する規則に従う必要がありま す。つまり、英数字およびアンダースコアのみを含み、数字でない文字ま たはアンダースコアで始まる必要があります。

警告

非常に重要なことですが、終端IDがある行には、セミコロン (;)以外の他の文字が含まれていてはならないこ とに注意して下さい。これは、特にIDはインデントしてはならないと いうことと、セミコロンの前に空白やタブを付けてはいけないことを 意味します。 終端IDの前の最初の文字は、使用するオペレーティングシステ ムで定義された改行である必要があることにも注意を要します。 これは、例えば、Macintoshでは \rとなります。

この規則が破られ、終端IDが"clean"でない場合、 終端IDと認識されず、PHPは探し続けます。 適当な終了IDがみつからない場合、スクリプトの最終行を発生 行とするパースエラーが発生します。

ヒアドキュメントは、2重引用符を使用しませんが、2重引用符で括られた 文字列と全く同様に動作します。しかし、この場合でも上記のリストでエ スケープされたコードを使用することも可能です。変数は展開されますが、 文字列の場合と同様にヒアドキュメントの内部で複雑な変数を表わす場合 には注意が必要です。

例 6-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;
?>

注意: ヒアドキュメントはPHP4で追加されました。

変数のパース

スクリプトが2重引用符で括られるかヒアドキュメントで指定された場 合、その中の変数はパースされます。

構文の型には、単純な構文と 複雑な 構文の2種類があります。簡単な構文は、最も一般的で便利です。 この構文では、変数、配列値やオブジェクトのプロパティをパースする ことが可能です。

複雑な構文は、PHP 4で導入されました。 この構文は、式を波括弧で括ることにより認識されます。

簡単な構文

ドル記号($)を見付けるとパーサは、有効な変数 名を形成することが可能な最長のトークンを取得します。変数名の終 りを明示的に指定したい場合は、変数名を波括弧で括って下さい。

$beer = 'Heineken';
echo "$beer's taste is great"; // 動作します。"'" は変数名として無効な文字です。
echo "He drunk some $beers"; // 動作しません。's' は、変数名として有効な文字です。
echo "He drunk some ${beer}s"; // 動作します。
echo "He drank some {$beer}s"; // 動作します。

同様に、配列添字とオブジェクトのプロパティをパースすることも可 能です。配列添字の場合、閉じ角括弧(']')は添字の終りを意味し、 オブジェクトのプロパティの場合、同じ規則が簡単な変数として適用 されます。しかし、オブジェクトプロパティには、変数の場合のよう な手法はありません。

<?php
// These examples are specific to using arrays inside of strings.
// When outside of a string, always quote your array string keys
// and do not use {braces} when outside of strings either.

// Let's show all errors
error_reporting(E_ALL);

$fruits = array('strawberry' => 'red' , 'banana' => 'yellow');

// シングルクオートの外では動作が異なることに注意してください。
echo "A banana is $fruits[banana].";

// 動作します。
echo "A banana is {$fruits['banana']}.";

// Works but PHP looks for a constant named banana first
// as described below.
echo "A banana is {$fruits[banana]}.";

// Won't work, use braces.  This results in a parse error.
echo "A banana is $fruits['banana'].";

// Works
echo "A banana is " . $fruits['banana'] . ".";

// Works
echo "This square is $square->width meters broad.";

// 動作しません。解決策については、複雑な構文を参照下さい。
echo "This square is $square->width00 centimeters broad.";
?>

より複雑な場合は、複雑な構文を使用する必要があります。

複雑な(波括弧)構文

この構文は、構文が複雑であるからではなく、この方法では複雑な式 を含めることができるため、複雑(complex)と呼ばれています。

事実、この構文により文字列の中に名前空間にあるあらゆる値を含め ることが可能です。文字列の外側に置く場合と同様に式を書き、これ を { と } の間に含めて下さい。'{'はエスケープすることができない ため、この構文は $が{のすぐ後に続く場合にのみ認識されます。 (リテラル"{$"を指定するには、"{\$"または"\{$"を使用して下さい) 以下のいくつかの例を見ると理解しやすくなるでしょう。

<?php
// Let's show all errors
error_reporting(E_ALL);

$great = 'fantastic';

// Won't work, outputs: This is { fantastic}
echo "This is { $great}";

// Works, outputs: This is fantastic
echo "This is {$great}";
echo
"This is ${great}";

// Works
echo "This square is {$square->width}00 centimeters broad.";

// Works
echo "This works: {$arr[4][3]}";

// This is wrong for the same reason as $foo[bar] is wrong
// outside a string.  In otherwords, it will still work but
// because PHP first looks for a constant named foo, it will
// throw an error of level E_NOTICE (undefined constant).
echo "This is wrong: {$arr[foo][3]}";

// Works.  When using multi-dimensional arrays, always use
// braces around arrays when inside of strings
echo "This works: {$arr['foo'][3]}";

// Works.
echo "This works: " . $arr['foo'][3];

echo
"You can even write {$obj->values[3]->name}";

echo
"This is the value of the var named $name: {${$name}}";
?>

文字列への文字単位のアクセス

波括弧の後に任意の文字をゼロから始まるオフセットで指定することに より、文字列内の文字にアクセスすることが可能です。

注意: 過去の互換性のため、配列括弧を使用することが可能です。しかし、 この構文はPHP 4に依存しています。

例 6-3. いくつかのstringの例

<?php
// Get the first character of a string
$str = 'This is a test.';
$first = $str{0};

// Get the third character of a string
$third = $str{2};

// Get the last character of a string.
$str = 'This is still a test.';
$last = $str{strlen($str)-1};
?>

便利な関数

文字列は、'.' (ドット)結合演算子で結合することが可能です。'+'(付 加)演算子はこの例では出てこないことに注意して下さい。詳細について は 文字列演算子 を参照下さい。

文字列の修正を行う場合に便利な関数がたくさんあります。

一般的な関数については、文字列関数の 節 を参照下さい。高度な検索/置換を行う正規表現関数について は、Perl および POSIX 拡張の2種類ありますが、そ れぞれの節を参照下さい。

URL文字列用関数や文字列の暗号化/ 復号化用関数(mcrypt および mhash)もあります。

最後に、探しているものがまだ見付からない場合には、 文字型の関数も参照下さい。

文字列への変換

(string)キャストやstrval()関数を 使って変数を文字列へ変換することができます。文字列型を必要とする 式のスコープにおいて文字列への変換は自動的に行われます。 echo()print()関数を使うとき、 あるいは可変変数を文字列を比較するときにこの自動変換が行われます。 マニュアルの型の相互変換の項を 読むとわかりやすいでしょう。 settype()も参照してください。

booleanTRUE は文字列の"1"に、 FALSE""(空文字列)に変換されます。 これによりbooleanと文字列の値を相互に変換することができます。

integer(整数)や浮動小数点数(float)は その数値の数字として文字列に変換されます(指数の表記や浮動小数点数を含めて)。

配列は常に"Array"という文字列に変換されるので、 arrayの中をるためにecho()print()を使ってダンプさせることはできません。 一つの要素を見るためには、echo $arr['foo']のように してください。内容の全てをダンプ/見るためには以降のTIPをご覧ください。

オブジェクトは常に"Object"という文字列に変換されます。 デバッグ等のためにobjectの内部の変数を出力するような 場合には、以下をご覧ください。オブジェクトがなんという名前のクラスの インスタンスなのかを知るにはget_class()をご覧ください。

リソースは常に"Resource id #1"という文字列に 変換されます。1は実行中のPHPによって割り当てられる resourceのユニークな番号です。 リソースの型を知るためにはget_resource_type()を 使用してください。

NULL は常に空文字列に変換されます。

以上に述べたように、配列、オブジェクト、リソースをプリントアウトしても その値に関する有益な情報を得られるわけではありません。デバッグのために 値を出力するのにベターな方法がprint_r()var_dump()等にあります。

PHP変数を恒久的に保存するための文字列に変換することもできます。 この方法はシリアライゼーションと呼ばれ、 serialize()関数によって実現できます。 WDDXサポートを有効にしてPHPを セットアップすれば、PHP変数をXML構造にシリアライズすることもできます。

文字列の変換

数値として文字列が評価された時、結果の値と型は次のように 定義されます。

文字列は、'.'、'e'、'E' のどれかが含まれている場合は float、それ以外は整数として評価されます。

文字列の最初の部分により値が決まります。文字列が、有効な数値デー タから始まる場合、この値が使用されます。その他の場合、値は 0 (ゼ ロ) となります。有効な数値データは符号(オプション)の後に、1つ以上 の数字(オプションとして小数点を一つ含む)、オプションとして指数部 が続きます。指数部は 'e' または 'E' の後に一つ以上の数字が続く形 式です。

最初の式が文字列の場合、変数の型は2番目の式に依存します。

<?php
$foo
= 1 + "10.5";              // $foo は float です (11.5)
$foo = 1 + "-1.3e3";            // $foo は float です (-1299)
$foo = 1 + "bob-1.3e3";         // $foo は integer です (1)
$foo = 1 + "bob3";              // $foo は integer です (1)
$foo = 1 + "10 Small Pigs";     // $foo は integer です (11)
$foo = 1 + "10 Little Piggies"; // $foo は integer です (11)
$foo = "10.0 pigs " + 1;        // $foo は integer です (11)
$foo = "10.0 pigs " + 1.0;      // $foo は float です (11)     
?>

この変換に関する詳細は、UNIXマニュアルstrtod(3) を参照下さい。

本節の例を試したい場合、その例をカットアンドペーストしてから 動作を確認するために次の行を挿入して下さい。

<?php
echo "\$foo==$foo; type is " . gettype ($foo) . "<br>\n";
?>

(C言語で行われるように)数値に変換することで一つの文字のコードを 取得できると期待してhあいけません。文字と文字コードを相互に変換 するにはord()chr()関数を 使用してください。