プログラム言語のキホンである変数、条件判定とループ:PHPではどう表すのか?

2015年2月9日(月)
野田 貴子

はじめに

これから始めるPHP入門コラムでは、PHPを学ぶ人が、PHPで簡単なプログラムを書けるようになるまでに必要な知識とポイントをTips的に書いていきます。今後PHPのスキルを身につけて仕事に役立てたい、という方のために「PHP技術者認定初級試験」の出題範囲を意識しながら進めていきますので、ぜひ最後までお付き合いください。

今回のあらすじ

  1. 変数
  2. 判定
  3. 繰り返し文

変数とは

前回までの連載でも使っていましたが、「変数」とは中に文字や数値などの値を入れておくことができるものです。名前に「数」という文字が入っていますが、数字以外だけでなく、文字列や関数など様々なものを入れられます。

$helloという変数の中に "こんにちは" という文字列を入れておけば、下の2つのechoは同じ結果を出力します。

echo "こんにちは";
echo $hello;

変数を使えば、変数の中身を入れ替えるだけでプログラムの挙動を変更できます。プログラミングにはなくてはならない機能ですね。

変数名の決め方

PHPの変数には、以下のルールがあります。

  • 先頭にドル記号($)を付ける
  • 変数名の1文字目は、アンダースコア記号(_)と半角英字(A-Za-z)が使える
  • 変数名の2文字目以降は、アンダースコア記号と半角英字、半角数字(0-9)が使える
  • 英字の大文字と小文字は区別される
PHPでの変数名のルール

図1:PHPでの変数名のルール

つまり、以下のような変数名はすべて有効です。

$myname
$my_name
$myName
$MyName
$_my_name

またこれらの変数は、すべて別々の変数として扱われます。ですが、$myname、$myName、$MyNameはとても紛らわしいので、同時に使わないようにしましょう。どの形式の変数を使うかは、プログラムを書く人の好みや、プロジェクトチームのコーディングルールなどによって決まります。次に示すのは、一般的な変数の命名法の例です。

表1:代表的な変数名の付け方

変数名(呼称)説明利点欠点
$myname全部小文字でつなげるシンプル長い名前になると読みにくい
$my_name
(スネークケース)
全部小文字で、単語の間にアンダースコアを入れる読みやすいアンダースコアがある分変数名が長くなる
$myName
((ローワー)キャメルケース)
2単語目以降を大文字で始める普及している大文字にするのを忘れると違う変数になってしまう
$MyName
((アッパー)キャメルケース)
全ての単語を大文字で始める…あるかな?「クラス名を大文字で始める」という慣習と紛らわしい
$_my_name先頭にアンダースコアをつける。ローカル変数(その場だけで使う変数)に使うことが多い

変数名の先頭に中に入れる値の種類を付けると、プログラムを書く人にとっての手助けになるかもしれません。後半で述べますが、PHPでは文字の「0」と数値の「0」が正反対の意味になることがあるので、このように変数名で分かるようにしておく手法もあります。

$sMyName = “Whoami”; // string(文字列)
$iMyAge = 15; // integer(数値)
$tMyBirthDay = mktime(0, 0, 0, 1, 2, 2000); // timestamp(タイムスタンプ)

また、どこから入力された値なのか、分かるようにしておくのもよいでしょう。プログラミングでは、プログラムが直接設定した値以外(例えばデータベースから取得した値、ユーザーが入力した値、外部のAPIから取得した値)は「全て」リスクがあります。悪意のある改変がされているかもしれないですし、悪意はなくても入力が間違っているかもしれないからです。これらの区別を分かりやすくしておくと、バグの発見に役立つことがあります。

表2:値の由来が分かるようにした変数名の例

$inLoginIdユーザーが入力したログインID
$okLoginId$inLoginId の中身をチェックした後に小文字に変換したもの。データベースの保存などに使っても安全なもの
$dbUserNameデータベースから取得したユーザー名
$outUserName$dbUserName をHTML出力用に直したもの

変数への代入

変数に値を入れる(「代入」と言います)には、「代入演算子(=)」を使います。数学の等号記号とは使い方が少し違うので、注意してくださいね。

構文(書き方のルール)
変数 = 中に入れたい値;

<?php
// 月収は20万円
$monthly = 200000;
?>

代入する文の右辺には、式や関数を使うこともできます。

<?php
// 年収は月収の16倍(ボーナスは4ヶ月分♪)
$yearly = $monthly * 16;
?>

変数に値を加減乗除(四則演算)する場合は、省略した書き方もあります。以下の例では、それぞれ (a) と (b) は同じ処理をします。(b)が省略した書き方です。

<?php
// 体重を2kg増やす
$weight = $weight + 2; // (a)
$weight += 2; // (b)
?>

<?php
// 利子を2倍にする
$interest = $interest * 2; // (a)
$interest *= 2; // (b)
?>

<?php
// 小遣いを半分にする
$money = $money / 2; // (a)
$money /= 2; // (b)
?>

値を1増やす(「インクリメント」と言います)ときは、「加算子(++)」を使うこともできます。以下の(a)~(d)の4つの例は、どれを選んでも、結果が同じになります。

<?php
$count = $count + 1; // (a)
$count += 1; // (b)
$count++; // (c)
++$count; // (d)
?>

加算子は変数の前にも後ろにも置けます。加算子を単体で使うときは両者に違いはありませんが、式や関数の中で使うときは挙動が違うので注意してください。「++」を前に付ける(d)とインクリメントが先に行われ、後ろに付ける(c)と変数の値が参照された後にインクリメントされます。以下の2つの例で、その違いが分かるでしょう。

<?php
$count = 100;
echo ++$count; // 101(1増やしてから値を返すため)
echo $count; // 101
?>

<?php
$count = 100;
echo $count++; // 100(値を返してから1増やすため)
echo $count; // 101
?>

同様に、変数の値を1減らす(「デクリメント」)ときは「減算子(--)」が使えます。

文字列の場合

文字列も同様に、右辺で連結式を使うことができます。

<?php
$hello = "こんにちは";
$title = $hello . "、みなさん!";
echo $title; // こんにちは、みなさん!
?>

次の2つは、どちらを選んでも同じ処理をします。

<?php
$title = $title . "ようこそ!"; // (a)
$title .= "ようこそ!"; // (b)
?>

文字列の中のにある変数

ダブルクォーテーション(”)で文字列を囲んでいる場合は、囲んだ中で変数の中身を参照できます。

<?php
$weight = 50;
echo "体重は$weightキロです。"; // 体重は50キロです。
?>

変数と文字列の区切りを明確にしたいときには、波カッコ({})で変数を囲います。

<?php
echo "体重は$weightkgです。"; // 体重はです。($weightkgという変数がないので、何も表示されない)
echo "体重は{$weight}kgです。"; // 体重は50kgです。
?>

真偽値(true、false)による判定

通常、プログラムには分岐点がいくつもあります。例えば新規ユーザー登録をする場合、以下のような分岐点が考えられるでしょうか。

プログラムでの分岐処理の例(新規ユーザーの登録)

図2:プログラムでの分岐処理の例(新規ユーザーの登録)

分岐点では、条件式(お題のこと)がYESかNOかによって、その後の処理が分岐されます。このYESかNOかというのは、プログラミングでは「true(真)」と「false(偽)」と表現します。PHPでは数字、文字、式のすべてが、trueまたはfalseのどちらかに振り分けられます。

PHP:論理型 (boolean) - Manual

表3:値と真偽値の対照

型(値の種類のこと)真偽値
真偽値truetrue
falsefalse
数値-1true
0false
0.123true
1true
文字列“”false
“ “true
“0”true
"abc!"true
数式1 + 2true
1 - 1false
その他ヌル値(null)false
未定義の変数false

特に注意したいのは、数値の0はfalseですが、文字の「0」はtrueだというところです。数値の1や0というのは、数量があるかないかを表すので、それぞれtrueとfalseになります。一方、文字の「0」には「ない」という意味はなく、この形の文字(コンピュータ的には文字コード)が「存在している」ということなので、trueになります。同様に、文字列の「zero」や「零」もtrueです。

if文による条件分岐

このtrueとfalseを使って処理を分岐するためには、主に「if文」を使います。if文の文法は以下のようになります。

構文(1)

if (A) /* Aがtrueの場合セミコロンまで処理が実行される */ ;

※この書き方はif文の範囲が分かりにくいので、構文(2)の例のように{}を使った方がよいでしょう。

構文(2)

if (A) {
    // Aがtrueの場合
    // ここに書かれた処理が実行される
}

構文(3)

if (A) /* Aがtrueの場合セミコロンまで処理が実行される */ ;
else /* それ以外(Aがfalse)の場合セミコロンまで処理が実行される */ ;

※この書き方はif文、else文の範囲が分かりにくいので、構文(4)のように{}を使った方がよいでしょう。

構文(4)

if (A) {
    // Aがtrueの場合
    // ここに書かれた処理が実行される
}
else {
    // それ以外(Aがfalse)の場合
    // ここに書かれた処理が実行される
}

構文(5)

if (A); /* Aがtrueの場合セミコロンまで処理が実行される */ ;
elseif /* AがfalseでBがtrueの場合セミコロンまで処理が実行される */ ;
else /* それ以外(A、Bともにfalse)の場合セミコロンまで処理が実行される */ ;

※この書き方はif文、elseif文、else文の範囲が分かりにくいので、構文(6)のように{}を使った方がよいでしょう。
※elseifはいくつでも増やすことができます。
※elseifはelse ifと分けて書いても同じ処理をします。

構文(6)

if (A) {
    // Aがtrueの場合
    // ここの処理が実行される
}
elseif (B) {
    // AがfalseでBがtrueの場合
    // ここの処理が実行される
}
else {
    // それ以外(A、Bともにfalse)の場合
    // ここの処理が実行される
}

A や B は、条件式といいます。条件式には数値や文字列などを直接入れたり

if (true) {
    // 実行されます
}
if (0) {
    // 実行されません
}
if ("abc") {
    // 実行されます
}

変数を入れたり

$userId = 123;
if ($userId) {
    // 実行されます
}
$check = false;
if ($check) {
    // 実行されません
}

関数を入れることができます。

$name = "JohnSmith";
if (strlen($name)) { // 9 なので true
    // 実行されます
}

これらの判定を逆にしたい場合は、「否定演算子(!)」を使います。

if (true) {
    // 実行されます
}
if (!true) {
    // 実行されません
}

$count = 0;
if ($count) {
    // 実行されません
}
if (!$count) {
    // 実行されます
}

比較演算子

さらに条件式には、以下のような比較演算子を入れることができます。

等価判定

A == B

AとBが等しい場合はtrue、そうでない場合はfalseになります。AとBの種類(型)が違う場合は、どちらかに合わせて判断されます。

PHP:比較演算子 - Manual

表4:等価判定の例(==)

評価式真偽値メモ
1 == 1true
1 == “1”true数値と文字の比較
1 == 2false
1 == truetrueif (1) と同じ
0 == falsetrueif (!0) と同じ
'abc' == 'abc'true
'abc' == ' abc 'false空白あり
'abc' == 'ABC'false小文字と大文字の比較
1 + 2 == 3true計算式の比較(左辺)
1 == 3 % 2true計算式の比較(右辺)

A === B

AとBの型も値も等しい場合はtrue、そうでない場合はfalseになります。

表5:等価判定の例(===)

評価式真偽値メモ
1 === 1true
1 === '1'false型が違う
1 === truefalse型が違う
'abc' === 'abc'true

不等価判定

等価判定の逆バージョンです。

A != B

AとBが等しくない場合はtrue、そうでない場合はfalseになります。AとBの種類(型)が違う場合は、どちらかに合わせて判断されます。

表6:不等価判定の例(!=)

評価式真偽値メモ
1 != 1false
1 != 2true
1 != truefalse
1 != falsetrue
'abc' != 'abc'false
'abc' != ' abc 'true

A !== B

AとBの型か値が等しくない場合はtrue、そうでない場合はfalseになります。

表7:不等価判定の例(!==)

評価式真偽値メモ
1 !== 1false
1 !== '1'true型が違う
1 !== truetrue型が違う
'abc' !== 'abc'false

大小の比較

大小を比較する演算子は4種類あります。少しでもバグを減らすために、数値なら数値、文字なら文字と、比較するもの同士の型は揃えるようにしましょう。違う型同士で比較すると、予想外の結果になることがあります。

A < B

AがBより小さい場合はtrue、そうでない場合はfalseになります。

表8:大小の比較(<)

評価式真偽値メモ
1 < 0false
1 < 1false
1 < 2true

A > B

AがBより大きい場合はtrue、そうでない場合はfalseになります。

表9:大小の比較(>)

評価式真偽値メモ
0 > 1false
1 > 1false
2 > 1true

A <= B

AがBより小さい、または等しい場合はtrue、そうでない場合はfalseになります。

表10:大小の比較(<=)

評価式真偽値メモ
1 <= 0false
1 <= 1true
1 <= 2true

A >= B

AがBより大きい、または等しい場合はtrue、そうでない場合はfalseになります。

表11:大小の比較(>=)

評価式真偽値メモ
0 >= 1false
1 >= 1true
2 >= 1true

種類(型)の異なるものを比較すると、どちらかの型に合わせて判断されます。

小数を比較する際の注意点

コンピュータでは扱える小数点の桁数(有効桁数)に限りがあるため、正確に表せない小数がたくさんあります。PHPでは多すぎる小数点の桁数は丸めるので、小数同士を比較しようとすると、意図しない結果になることも少なくありません。しかもどの小数が不正確なのかは、見ただけでは分かりません。例えば十進数では簡単な小数に見える0.1のような数も、PHPの内部では二進数で扱われるため、無限小数(の桁数を丸めたもの)になっています。以下の簡単な例で確認できます。

<?php
$x = 0.1 + 0.7;
var_dump($x); // 0.8
var_dump($x == 0.8); // false
?>

これはとても簡単な足し算に見えますが、$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」という関数を使うとよいでしょう。

論理演算子

複数の条件式をつないで、もっと複雑な条件式を作ることもできます。以下の「論理演算子」を用いて、条件式をいくつでもつなぐことができます。

表12:論理演算子

A || BまたはAまたはBがtrueならばtrue。それ以外はfalse
A && BかつAとBがともにtrueならばtrue。それ以外はfalse(||より優先)

※優先順位を変えるにはカッコを使います。

<?php
if (1 + 2 === 3 && (“This is a test.” || 0)) {
    // true && (true || false) なので
    // 実行されます
}
?>

繰り返し文

次は、条件分岐を使った繰り返し(ループ)の方法です。条件式がtrueの間だけ処理を繰り返します。

条件分岐を用いた繰り返し処理のイメージ

図3:条件分岐を用いた繰り返し処理のイメージ

while文による繰り返し

PHPで一番簡単に繰り返しを書く方法が「while文」です。

<構文>

while (A) {
    // Aがtrueの間、ここの処理が実行される
}

while文は簡単ですが、気をつけないと無限ループ(止まらないループ)になってしまいます。

<?php
while (1) {
    // 怖いセリフを永遠に出力し続ける
    echo “Hello, Clarice.”;
}
// while文が永遠に終わらないので、ここの処理は実行されない
echo “Good bye.”;
?>

※実際にはWebサーバーがクラッシュするなどしてwhile文のループの途中で止まります。

while文を終わらせる方法は、二通りあります。ひとつは、いつかは条件式の結果がfalseになるようにすることです。

<?php
$count = 10;
while ($count >= 0) {
    // カウントダウンを表示
    echo $count;
    // カウントを1減らす(いつかは-1になるので、条件に合わなくなる)
    $count--;
}
?>

もうひとつは、while文の中にwhile文を終了させる命令(break)を書くことです。breakするかどうかは、if文を使って決められるので、複雑な条件分岐をさせることもできます。

<?php
$count = 10;
while (true) {
    // カウントダウンを表示
    echo $count;
    // カウントを1減らす
    $count--;
    // カウントが0未満になっているかチェックする
    if ($count < 0) {
        // while文から外に出るための命令
        break;
    }
}
?>

for文による繰り返し

ループの条件式が簡単な場合は、for文も使いやすいです。for文の使い方はこのようになります。

<構文>

for (A; B; C) {
    // 最初に1度だけAが実行され
    // Bの条件を満たす間、{}内の処理が実行される
    // ループの最後に毎回Cが実行される
}

while文で使ったカウントダウンをfor文で書くとこのようになります。この場合はfor文の方がシンプルに書けますね。

<?php
for ($count = 10; $count >= 0; $count--) {
    echo $count;
}
?>

foreach文

他にも配列をループさせるforeach文がありますが、こちらはまた後日、配列について解説をした後で取り上げたいと思います。

おわりに

いかがでしたか。今回は少し内容が多かったかもしれませんが、これらを使うことで、プログラムの流れ(アルゴリズム的なもの)を再現できるので、とても楽しいところだと思いますよ。それではまた。

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

連載バックナンバー

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

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

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

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