[PHP]変数に添え字を使って値を取得する

Read More

今日はPHPのちょっと変な仕様。

文字列への文字単位のアクセス方法について書く。

これはstring型変数に対して添え字を使って値が取得できるというもの。
以下に例を。

■添え字を指定して値を取得する例
<?php
$str = 'abcde';
echo 'normal:'. $str;
echo '<br />';
echo 'key0:'. $str[0];
echo '<br />';
echo 'key1:'. $str{1};
?>


■実行結果
>>normal:abcde
>>key0:a
>>key1:b


このように角括弧(大カッコ)でも波括弧(中カッコ)でも文字を取得することができる。


上記の結果からわかることは、PHPでは
文字列は文字の配列として考えられている
ということ。

PHPはそもそも英語圏なのでシングルバイトエンコーディングの文字列が基本。
内部的には文字列はバイト配列であり、通常1バイト=1文字として扱われている。


なおマルチバイトエンコーディングの文字列だった場合は上記の限りではない。
マルチバイトの場合、例えばUTF-8の場合はこの方法で取得すると文字化けする。


■マルチバイトエンコーディングの場合
<?php
$str = 'あいうえお';
echo 'normal:'. $str;
echo 'key0:'. $str[0];
?>


■実行結果
>>normal:あいうえお
>>key0:�


UTF-8の場合1バイト目の文字は文字化けしている。
'あ'を取得したいのならば、
echo $str[0]. $str[1]. $str[2];
と書かなければならない。



しかしこのようなアクセス方法は公式ではっきりとマルチバイト対応ではないと書かれているのでやらない方がいい。
警告

内部的には、PHP の文字列はバイト配列です。
そのため、角括弧を使った配列形式での文字列へのアクセスは、 マルチバイト対応ではありません。
この方法は、 ISO-8859-1 のようなシングルバイトエンコーディングの文字列に対してだけしか使えません。
原文ママ

http://jp.php.net/manual/ja/language.types.string.php#language.types.string.substr



この件に限った話ではないが、通常PHPについて語られる場合多くはシングルバイトエンコーディングを基として考えられている。
日本のようなマルチバイトは特殊と考えられているのでそちらを主体に考えるべきではない。




ぶっちゃけた話このようなアクセス方法があったことをすっかり忘れてしまっていた。



あーあとこんな挙動もある。
■例2
<?php
$str = 'abcde';
$str[10] = 'k';
echo $str;
?>


■実行結果
>> abcde     k
※ブラウザによっては半角スペースが1つに省略されて表示される。
※この場合HTMLのソースコードを表示して確認する。

こちらも仕様として書かれている。
警告

範囲外のオフセットに書き込んだ場合は、空いた部分に空白文字が埋められます。
整数型以外の型は整数型に変換されます。
無効なオフセット形式を指定した場合は E_NOTICE を発行します。
負のオフセットを指定した場合は、書き込み時は E_NOTICE を発行しますが読み込み時は空の文字列を返します。
文字列を代入した場合は最初の文字だけを使用します。
空文字列を代入した場合は NULL バイトを代入します。
原文ママ

つまり間の配列は半角空白が入っている。



ちなみにこれはstring型の変数の話であり、integer型の変数だとまた挙動が違う。

まあめんどくさいので書かないけど。


普段から書くときはstring型にしろinteger型にしろ、変数への添え字アクセスにならないように気をつけることが大事だと言える。



--
ほんと、PHPって訳のわからん仕様がいっぱいあるなあ