プログラム言語のキホンである変数、条件判定とループ:PHPではどう表すのか?
はじめに
これから始めるPHP入門コラムでは、PHPを学ぶ人が、PHPで簡単なプログラムを書けるようになるまでに必要な知識とポイントをTips的に書いていきます。今後PHPのスキルを身につけて仕事に役立てたい、という方のために「PHP技術者認定初級試験」の出題範囲を意識しながら進めていきますので、ぜひ最後までお付き合いください。
今回のあらすじ
- 変数
- 判定
- 繰り返し文
変数とは
前回までの連載でも使っていましたが、「変数」とは中に文字や数値などの値を入れておくことができるものです。名前に「数」という文字が入っていますが、数字以外だけでなく、文字列や関数など様々なものを入れられます。
$helloという変数の中に "こんにちは" という文字列を入れておけば、下の2つのechoは同じ結果を出力します。
変数を使えば、変数の中身を入れ替えるだけでプログラムの挙動を変更できます。プログラミングにはなくてはならない機能ですね。
変数名の決め方
PHPの変数には、以下のルールがあります。
- 先頭にドル記号($)を付ける
- 変数名の1文字目は、アンダースコア記号(_)と半角英字(A-Za-z)が使える
- 変数名の2文字目以降は、アンダースコア記号と半角英字、半角数字(0-9)が使える
- 英字の大文字と小文字は区別される
つまり、以下のような変数名はすべて有効です。
またこれらの変数は、すべて別々の変数として扱われます。ですが、$myname、$myName、$MyNameはとても紛らわしいので、同時に使わないようにしましょう。どの形式の変数を使うかは、プログラムを書く人の好みや、プロジェクトチームのコーディングルールなどによって決まります。次に示すのは、一般的な変数の命名法の例です。
変数名(呼称) | 説明 | 利点 | 欠点 |
---|---|---|---|
$myname | 全部小文字でつなげる | シンプル | 長い名前になると読みにくい |
$my_name (スネークケース) | 全部小文字で、単語の間にアンダースコアを入れる | 読みやすい | アンダースコアがある分変数名が長くなる |
$myName ((ローワー)キャメルケース) | 2単語目以降を大文字で始める | 普及している | 大文字にするのを忘れると違う変数になってしまう |
$MyName ((アッパー)キャメルケース) | 全ての単語を大文字で始める | …あるかな? | 「クラス名を大文字で始める」という慣習と紛らわしい |
$_my_name | 先頭にアンダースコアをつける。ローカル変数(その場だけで使う変数)に使うことが多い |
変数名の先頭に中に入れる値の種類を付けると、プログラムを書く人にとっての手助けになるかもしれません。後半で述べますが、PHPでは文字の「0」と数値の「0」が正反対の意味になることがあるので、このように変数名で分かるようにしておく手法もあります。
また、どこから入力された値なのか、分かるようにしておくのもよいでしょう。プログラミングでは、プログラムが直接設定した値以外(例えばデータベースから取得した値、ユーザーが入力した値、外部のAPIから取得した値)は「全て」リスクがあります。悪意のある改変がされているかもしれないですし、悪意はなくても入力が間違っているかもしれないからです。これらの区別を分かりやすくしておくと、バグの発見に役立つことがあります。
$inLoginId | ユーザーが入力したログインID |
---|---|
$okLoginId | $inLoginId の中身をチェックした後に小文字に変換したもの。データベースの保存などに使っても安全なもの |
$dbUserName | データベースから取得したユーザー名 |
$outUserName | $dbUserName をHTML出力用に直したもの |
変数への代入
変数に値を入れる(「代入」と言います)には、「代入演算子(=)」を使います。数学の等号記号とは使い方が少し違うので、注意してくださいね。
構文(書き方のルール)
変数 = 中に入れたい値;
代入する文の右辺には、式や関数を使うこともできます。
変数に値を加減乗除(四則演算)する場合は、省略した書き方もあります。以下の例では、それぞれ (a) と (b) は同じ処理をします。(b)が省略した書き方です。
値を1増やす(「インクリメント」と言います)ときは、「加算子(++)」を使うこともできます。以下の(a)~(d)の4つの例は、どれを選んでも、結果が同じになります。
加算子は変数の前にも後ろにも置けます。加算子を単体で使うときは両者に違いはありませんが、式や関数の中で使うときは挙動が違うので注意してください。「++」を前に付ける(d)とインクリメントが先に行われ、後ろに付ける(c)と変数の値が参照された後にインクリメントされます。以下の2つの例で、その違いが分かるでしょう。
同様に、変数の値を1減らす(「デクリメント」)ときは「減算子(--)」が使えます。
文字列の場合
文字列も同様に、右辺で連結式を使うことができます。
次の2つは、どちらを選んでも同じ処理をします。
文字列の中のにある変数
ダブルクォーテーション(”)で文字列を囲んでいる場合は、囲んだ中で変数の中身を参照できます。
変数と文字列の区切りを明確にしたいときには、波カッコ({})で変数を囲います。
真偽値(true、false)による判定
通常、プログラムには分岐点がいくつもあります。例えば新規ユーザー登録をする場合、以下のような分岐点が考えられるでしょうか。
分岐点では、条件式(お題のこと)がYESかNOかによって、その後の処理が分岐されます。このYESかNOかというのは、プログラミングでは「true(真)」と「false(偽)」と表現します。PHPでは数字、文字、式のすべてが、trueまたはfalseのどちらかに振り分けられます。
型(値の種類のこと) | 値 | 真偽値 |
---|---|---|
真偽値 | true | true |
false | false | |
数値 | -1 | true |
0 | false | |
0.123 | true | |
1 | true | |
文字列 | “” | false |
“ “ | true | |
“0” | true | |
"abc!" | true | |
数式 | 1 + 2 | true |
1 - 1 | false | |
その他 | ヌル値(null) | false |
未定義の変数 | false |
特に注意したいのは、数値の0はfalseですが、文字の「0」はtrueだというところです。数値の1や0というのは、数量があるかないかを表すので、それぞれtrueとfalseになります。一方、文字の「0」には「ない」という意味はなく、この形の文字(コンピュータ的には文字コード)が「存在している」ということなので、trueになります。同様に、文字列の「zero」や「零」もtrueです。
if文による条件分岐
このtrueとfalseを使って処理を分岐するためには、主に「if文」を使います。if文の文法は以下のようになります。
※この書き方はif文の範囲が分かりにくいので、構文(2)の例のように{}を使った方がよいでしょう。
※この書き方はif文、else文の範囲が分かりにくいので、構文(4)のように{}を使った方がよいでしょう。
※この書き方はif文、elseif文、else文の範囲が分かりにくいので、構文(6)のように{}を使った方がよいでしょう。
※elseifはいくつでも増やすことができます。
※elseifはelse ifと分けて書いても同じ処理をします。
A や B は、条件式といいます。条件式には数値や文字列などを直接入れたり
変数を入れたり
関数を入れることができます。
これらの判定を逆にしたい場合は、「否定演算子(!)」を使います。
比較演算子
さらに条件式には、以下のような比較演算子を入れることができます。
等価判定
A == B
AとBが等しい場合はtrue、そうでない場合はfalseになります。AとBの種類(型)が違う場合は、どちらかに合わせて判断されます。
評価式 | 真偽値 | メモ |
---|---|---|
1 == 1 | true | |
1 == “1” | true | 数値と文字の比較 |
1 == 2 | false | |
1 == true | true | if (1) と同じ |
0 == false | true | if (!0) と同じ |
'abc' == 'abc' | true | |
'abc' == ' abc ' | false | 空白あり |
'abc' == 'ABC' | false | 小文字と大文字の比較 |
1 + 2 == 3 | true | 計算式の比較(左辺) |
1 == 3 % 2 | true | 計算式の比較(右辺) |
A === B
AとBの型も値も等しい場合はtrue、そうでない場合はfalseになります。
評価式 | 真偽値 | メモ |
---|---|---|
1 === 1 | true | |
1 === '1' | false | 型が違う |
1 === true | false | 型が違う |
'abc' === 'abc' | true |
不等価判定
等価判定の逆バージョンです。
A != B
AとBが等しくない場合はtrue、そうでない場合はfalseになります。AとBの種類(型)が違う場合は、どちらかに合わせて判断されます。
評価式 | 真偽値 | メモ |
---|---|---|
1 != 1 | false | |
1 != 2 | true | |
1 != true | false | |
1 != false | true | |
'abc' != 'abc' | false | |
'abc' != ' abc ' | true |
A !== B
AとBの型か値が等しくない場合はtrue、そうでない場合はfalseになります。
評価式 | 真偽値 | メモ |
---|---|---|
1 !== 1 | false | |
1 !== '1' | true | 型が違う |
1 !== true | true | 型が違う |
'abc' !== 'abc' | false |
大小の比較
大小を比較する演算子は4種類あります。少しでもバグを減らすために、数値なら数値、文字なら文字と、比較するもの同士の型は揃えるようにしましょう。違う型同士で比較すると、予想外の結果になることがあります。
A < B
AがBより小さい場合はtrue、そうでない場合はfalseになります。
評価式 | 真偽値 | メモ |
---|---|---|
1 < 0 | false | |
1 < 1 | false | |
1 < 2 | true |
A > B
AがBより大きい場合はtrue、そうでない場合はfalseになります。
評価式 | 真偽値 | メモ |
---|---|---|
0 > 1 | false | |
1 > 1 | false | |
2 > 1 | true |
A <= B
AがBより小さい、または等しい場合はtrue、そうでない場合はfalseになります。
評価式 | 真偽値 | メモ |
---|---|---|
1 <= 0 | false | |
1 <= 1 | true | |
1 <= 2 | true |
A >= B
AがBより大きい、または等しい場合はtrue、そうでない場合はfalseになります。
評価式 | 真偽値 | メモ |
---|---|---|
0 >= 1 | false | |
1 >= 1 | true | |
2 >= 1 | true |
種類(型)の異なるものを比較すると、どちらかの型に合わせて判断されます。
小数を比較する際の注意点
コンピュータでは扱える小数点の桁数(有効桁数)に限りがあるため、正確に表せない小数がたくさんあります。PHPでは多すぎる小数点の桁数は丸めるので、小数同士を比較しようとすると、意図しない結果になることも少なくありません。しかもどの小数が不正確なのかは、見ただけでは分かりません。例えば十進数では簡単な小数に見える0.1のような数も、PHPの内部では二進数で扱われるため、無限小数(の桁数を丸めたもの)になっています。以下の簡単な例で確認できます。
これはとても簡単な足し算に見えますが、$x == 0.8はtrueになりません。$x は0.8のように見えますが、内部では「0.79999999999999991118...」というようになっているのです。ですので、小数同士を比較する場合は常に、小数点以下何桁までを含めて比較するかという「有効桁数」を意識する必要があります。
具体的には以下のような方法が考えられます。
- 比較したい桁までが整数になるように10x倍する
- 2つの値の差が有効桁数以内で0なら等しいとする
(例:if(abs(1.2345 – 1.2346) < 0.01) {...}) - 複雑な小数を扱うためのPHPライブラリを使う
文字列の比較をするときの注意点
文字列の大小は、辞書を基準に決められています。英語ならばアルファベット順、日本語ならば五十音順ですので、例えば「おおきい」は「ちいさい」よりも小さくなります(お < ち)。特に数字(文字列の数字)を扱うときは、注意してくださいね。比較する2つの文字列の1文字目から順番に比較していくので、「110」は「20」よりも小さくなります(1 < 2)。
文字列型の数字を「<」や「>」などの演算子を使って比較しても、数値として比較されてしまいます。もし文字列として比較をしたい場合は「strcmp」という関数を使うとよいでしょう。
論理演算子
複数の条件式をつないで、もっと複雑な条件式を作ることもできます。以下の「論理演算子」を用いて、条件式をいくつでもつなぐことができます。
A || B | または | AまたはBがtrueならばtrue。それ以外はfalse |
---|---|---|
A && B | かつ | AとBがともにtrueならばtrue。それ以外はfalse(||より優先) |
※優先順位を変えるにはカッコを使います。
繰り返し文
次は、条件分岐を使った繰り返し(ループ)の方法です。条件式がtrueの間だけ処理を繰り返します。
while文による繰り返し
PHPで一番簡単に繰り返しを書く方法が「while文」です。
while文は簡単ですが、気をつけないと無限ループ(止まらないループ)になってしまいます。
※実際にはWebサーバーがクラッシュするなどしてwhile文のループの途中で止まります。
while文を終わらせる方法は、二通りあります。ひとつは、いつかは条件式の結果がfalseになるようにすることです。
もうひとつは、while文の中にwhile文を終了させる命令(break)を書くことです。breakするかどうかは、if文を使って決められるので、複雑な条件分岐をさせることもできます。
for文による繰り返し
ループの条件式が簡単な場合は、for文も使いやすいです。for文の使い方はこのようになります。
while文で使ったカウントダウンをfor文で書くとこのようになります。この場合はfor文の方がシンプルに書けますね。
foreach文
他にも配列をループさせるforeach文がありますが、こちらはまた後日、配列について解説をした後で取り上げたいと思います。
おわりに
いかがでしたか。今回は少し内容が多かったかもしれませんが、これらを使うことで、プログラムの流れ(アルゴリズム的なもの)を再現できるので、とても楽しいところだと思いますよ。それではまた。