PHPにおける文字列のフォーマット化と数値の扱い方

2014年10月17日(金)
野田 貴子

このようにフォーマット化する利点は、2つあります。

1つは、文章だけを別の場所(別ファイルなど)にまとめられることです。そうすると、文章だけをスペルチェックできたり、同じ文章を使いまわせたりします。またプログラムの変更の影響も受けにくくなります。例えばプログラムの処理が変わり、$moneyという変数が別の名前に変わっても、文章ファイルを変更する必要はありません。逆に文章ファイルの変更も、プログラムに影響を与えにくくなります。

もし、出力する文章がプログラムの中に直接日本語で書かれていたら、このプログラムを他の言語で提供することになったとき、プログラムの中に書いてある日本語をすべて探し出して、翻訳し、書き直さないといけません。しかし、printfで文章と変数を分けておけば、翻訳者には文章ファイルを書き換えてもらうだけで済みますし、全部で文章がいくつあるのかも一目瞭然です。

プログラム本体

>printf($_lang_you_lost_x_dollars, $money);
printf($_lang_you_have_x_dollars, $money);

文章ファイル

>// 日本語の場合
$_lang_you_lost_x_dollars = "あなたは%dドル紛失しました。";
$_lang_you_have_x_dollars = "あなたの所持金は%dドルです。";
// 英語の場合
$_lang_you_lost_x_dollars = "You lost %d dollars.";
$_lang_you_have_x_dollars = "Now you have %d dollars.";

置き換える値の順番を入れ替えられる点は、特に翻訳などにおいて重要ですよね。

プログラム本体

>printf($_lang_updated, $year, $month, $date);

文章ファイル

>// 日本語の場合
$_lang_updated = "更新日: %d-%d-%d";     // 更新日: 2014-5-16
// 英語の場合
$_lang_updated = 'Updated: %3$d-%2$d-%1$d;' // Updated: 16-5-2014

2つ目の利点は、書式を変更できることです。$moneyには数値が入っていますが、ある数値を表現する方法はいくつもあります。例えば 1200 を表現する方法は、「1200」「1,200(英語式)」「1.200(ドイツ語式)」「1200.00(小数点あり)」「千二百(日本語の漢字)」など多数存在します。printf関数では、その表現方法を指定できます。

%dは、文字でも何でも無理やり数値に変換します。例えば "abc" を渡せば 0 に、true は 1 になります。この辺りの変換(型変換といいます)は、PHPの特殊な部分です。知らないとバグを起こしやすくなりますので、おりを見てマニュアルを熟読してくださいね。

%dの出力は、以下のように変化させることもできます。

printf("残高: %d ドル\n", $money);      // 残高: 1200 ドル

「+」は符号(+/-)を付けます。

printf("残高: %+d ドル\n", $money);     // 残高: +1200 ドル

「06」は0を使って6桁になるように埋めます。

printf("残高: %06d ドル\n", $money);    // 残高: 001200 ドル

%f は浮動小数点数に変換します。浮動小数点数とは、整数部分の大きさによって、小数点の位置が浮動する(動く)数です。%dと同様、出力を変化させることもできます。

printf("残高: %f ドル\n", $money);      // 残高: 1200.000000 ドル

「.2」 は小数点以下が2桁になるように表示します。

printf("残高: %.2f ドル\n", $money);   // 残高: 1200.00 ドル

文字列のフォーマット方法もたくさんあります。

$abc='ABC';
printf("[%s]\n",      $abc); // 標準の文字列出力
printf("[%10s]\n",    $abc); // 空白を使用して右詰め
printf("[%-10s]\n",   $abc); // 空白を使用して左詰め
printf("[%010s]\n",   $abc); // ゼロ埋めは文字列でも可能です
printf("[%'#10s]\n",  $abc); // ゼロの代わりに独自の文字 '#' で埋めます
printf("[%10.10s]\n", $abc); // 左詰めを行い、10 文字以上は切り捨てます
<code style="background:#fee;">[ABC]
[       ABC]
[ABC       ]
[0000000ABC]
[#######ABC]
[          ]
</code>

printf(…)は、 sprintf(…)の結果を出力したものと同じです。すぐに出力する必要がない場合はsprintfを以下のように使えます。

$balance = sprintf("残高: %d ドル\n", $money);
// :
// : 何か別の処理
// :
print $balance;

前回紹介した文字列関数や、今回の sprintf / printf 以外にも文字列を操作する関数はたくさんあります。HTMLに関連した関数が多いのも、PHPの特徴です。その他の文字列関数は、PHPマニュアルで確認できます。

数値の扱い方

PHPで扱える数値には、「整数」と「浮動小数点数」があります。

整数には負数(マイナス値)と正数(プラス値)とゼロがあり、10進数、16進数、8進数、2進数の表現を使うことができます。

$a = 1234;       // 10進整数
$a = <span style="color:red;">-</span>123;       // 負の数
$a = <span style="color:red;">0</span>123;       // 8進数 (10進数の83)
$a = <span style="color:red;">0x</span>1A;       // 16進数 (10進数の26)
$a = <span style="color:red;">0b</span>11111111; // 2進数 (10進数の255)

どれだけ大きい桁数の整数を扱えるかは、使用する環境に依存しますが、2147483647であることが多いです(32ビットのパソコンでマイナス値も扱う場合)。それ以上の数を扱おうとすると、大きい数を扱うためのライブラリなどが必要になってきます。

浮動小数点数は、以下のような数値です。

$a = 1.23456789;
$b = 1.2e3;      // 1200
$c = 7E-10;      // 0.0000000007

PHPは小数点数の取り扱いが苦手です。それは、小数点の桁数に限りがあるため、0.11111…のような無限小数(正確には2進数で表したときに無限小数になるもの)を管理しきれないからです。小数同士の計算を重ねていくと、誤差が大きくなってきます。正確な結果が欲しい場合は、小数を1000倍するなどして一度整数に直し、計算し終わったあとで、また1000分の1にすると確実です。

PHPでの四則演算は、通常の計算と同じようにできます。「×」と「÷」は「+」と「−」よりも優先されますし、丸カッコも使えます。PHPで対応する記号は以下の通りです。これらを「演算子(とくに代数演算子)」といいます。

加算(+): +
減算(−): -
乗算(×): *
除算(÷): /

echo 2 + 3 * 4;     // 14
echo (2 + (3 * 4)); // 14
echo (2 + 3) * 4;   // 20

除算の余りは「%」で表します。例えば曜日の計算などに使えます。

剰余: %

echo 24 % 7; // 3

PHP5.6からは累乗の演算子も追加されました。累乗の結果は大きな数になりやすいので、やりすぎると整数の最大値をオーバーフローしますよ。

累乗: **

echo 2 ** 3 ** 4; // 4096

今回は以上です。お疲れ様でした!次回は今までなんとなく使ってきた変数について、特徴や注意点を書きたいと思います。

1983年生まれ。大学卒業後、ソフトウェア開発の営業を経て、ソフトウェア開発業務に転向。現在は自社パッケージのフロントエンド開発のほか、PHPでの受託開発案件、日→英のローカライズ案件などを担当。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています