「第5回初心者向けPHP講座」の記録 〜変数と配列 その2 変数、定数、配列〜
その1ではPHPを書くに当たってのポイントを解説しました。今回は変数と配列について学習します。変数や配列はどのプログラミング言語でも必ずと言っていいほど出てくるくらい重要なものです。PHPにおける注意点を踏まえながら基本的な部分から学習していきます。
変数について(テキスト P14〜)
変数とは、端的に言えば「プログラム上で値を保持しておく箱」である。プログラム上ではソースコードを書けば様々な処理を行う事が出来るが、計算結果等の処理中の値を保持したい場合が多数ある。そんなときに変数という機能を使って値を保持しておくのである。
PHPプログラム上では$(ダラー)の後に変数名を書く事で変数の定義が行える。その際、イコールを書いて左辺に変数名、右辺に代入したい値を書くと変数の初期化が行える。変数の初期化を下記の例で分かりやすく言うと、「この『suuji』という箱は最初に99を入れてから使い始めますよ」という意味だ。
例:
$suuji = 99;
ちなみに変数の初期化を省略することも可能だ。変数名の定義だけ行えば自動でデフォルト値(数字ならゼロ、文字列なら空白等)で初期化してくれるプログラミング言語もあるが、明示的にプログラマが初期化してから変数を使用しないとエラーになる言語もある。PHPの場合は初期化しなくてもエラーにはならずいきなり変数を使う事が出来る。しかし最初に初期化しておくことを推奨する。可読性を高めたり、予測出来ない挙動を防ぐ事が出来るからだ。
※予測出来ない挙動とは?
初期化を行っていない変数は、値がなんだか分からない状態だ。つまり初期化していない変数をそのまま使用することは、値が不明なものに対して計算等の処理を行う事になり、予測しえない動きをする可能性がある。
予測できない挙動の例:
$suuji1 = 1; // 初期化した変数suuji1 $suuji2; // 初期化してない変数suuji2 // suuji1とsuuji2を足し算する(右辺の結果が左辺に代入される) $suuji1 = $suuji1 + $suuji2;
上記の例だと、suuji2の値が不明なため、最終的にsuuji1に何が入るかが分からない。PHPの場合はエラーにもならず処理されるが、ソースコードの可読性の観点からもよくないので、下記の様に0なら0で必ず初期化すること。
上記の例を修正して初期化した例:
$suuji1 = 1; // 初期化した変数suuji1 $suuji2; // 初期化してない変数suuji2 $suuji2 = 0; // 変数定義時は初期化していなかったが、0で初期化する。 // suuji1とsuuji2を足し算する(右辺の結果が左辺に代入される) $suuji1 = $suuji1 + $suuji2;
定数について
定数とは、変数がその名の通り「変わる数」に対して、値が不変な変数のことだ。定数を最初に初期化したら、その後は値をプログラム上で変更出来ない。この様な事を「ハードコーディング」とも呼ぶ。
例えばプログラムの最初で決まった値の定数を定義し、複数の箇所で同じ値を参照したい場合によく使う。そうすることによって、プログラム上でその値を使いたい箇所で定数を参照する様にしておけば、定数定義の値1カ所を変えるだけで、定数を参照している箇所は全て変わるのだ。
PHPでの定数はdifineを使って定義する。以下に例を示す。
例:
difine("suuji1", 99); // 定数としてsuuji1を定義 $suuji2 = 1; // 変数としてsuuji2を定義
上記の例は、「『suuji1』という定数に99を設定し、その後変更しないが、suuji2は通常の変数として定義する」という意味になる。
echoについて(テキスト P15)
echoは、PHPプログラムにて画面上に値を表示させるためのコマンドだ。PHPのコマンドであり、前述の関数ではないのだが、プログラマがそれを明確に意識する必要はない。書式は以下の通り。
$suuji = 1; // 数字を定義 $moji = "hogehoge"; // 文字列を定義 // 最後に画面出力(ピリオドで文字列同士を結合できるので、改行タグを入れている) echo $suuji."<BR>"; echo $moji."<BR>";
PHPにおける変数の型(テキスト P17〜)
変数には数字や文字列等を入れる事が出来るが、「型(かた)」とは、変数に格納する値の種類を表す。型の概念がない言語もあるが、PHPの場合は変数には型という属性がある。属性といってもソースコード上で目に見えるものではなく、PHPが処理中に裏側で管理している(変数に付随する)情報だ。
PHPにおける変数の型は以下の通り。
配列とは?(テキスト P19〜)
変数が値を1つだけ入れておける箱だとすると、「配列(はいれつ)」は複数の値を入れておける箱の様なものだ。変数を配列として定義すると、複数の値を持つことができる。変数の末尾に [] を付ける事によって配列として定義することが出来る。
なお、PHPでは配列は2種類ある。順番に説明する。
通常の配列(テキスト P27〜)
通常の配列は、配列に保持された複数の値に対して「添え字(そえじ)」、または「インデックス」と呼ばれる数字を使ってアクセスする。インデックスはゼロから始まり、数字が飛ばされる事はない。そして「配列がもつ要素数−1」が最大値になる。(例:配列が3つの値を持つ場合、インデックスは0〜2になる) インデックスを指定する際は変数名後の[]内に記述する。下記の例では文字列を格納しているが、数値等を格納しても構わない。
通常の配列の例:
$hairetsu1[]; // 配列として定義 // 配列の1つめ(インデックスはゼロ)に代入 $hairetsu1[0] = "aaa"; // インデックスを指定せずに代入すると、自動的に末尾に新規作成する("bbb"が入るインデックスは1) $hairetsu1[] = "bbb"; // array関数を使用して配列にまとめて入れる事も可能(インデックスの0〜2に自動的に入る) $hairetsu2 = array("AAA","BBB","CCC"); // array関数を使用するときは、変数名に[]を付けないこと。 // count関数で配列の要素数を取得出来る $cnt1 = count($hairetsu1); $cnt2 = count($hairetsu2);
連想配列について(テキスト P30〜)
通常の配列はインデックスと値が紐付いてペアになっていたが、連想配列はインデックスではなくキー値(文字列)と値が紐付く。書き方は下記の通り。
定義するとき
$hairetsu = array("キー名" => 格納する値 [,キー名 => 格納する値]...);
取り出すとき
$moji = $hairetsu["キー名"];
通常の配列と同様、格納する値は数値でも文字列等でも可。違いはインデックスで管理するか?、キー値で管理するか?、である。
連想配列の例:
// array関数を使って連想配列として作成 $hairetsu = array("key1" => "aaa", "key2" => "bbb", "key3" => "ccc"); // arrayを使わなくても追加可能 $hairetsu["key4"] = "ddd"; // 通常の配列と同様count関数で配列の要素数を取得出来る $cnt = count($hairetsu); // key2の値を取り出す $moji = $hairetsu["key2"];
キー値が毎回異なる必要があるため、キーと値がマッピング出来るデータに向いているのが連想配列である。(必ずしもマッピング出来ないなら通常の配列を使う)
自動型変換(テキスト P22〜)
「PHPにおける変数の型」の項で説明した通り、型は目に見えない。つまり変数を定義し、初期化すると自動的に型が決定する。それから別な型にどう変換されるか?を本項で取り扱う。
整数と浮動小数点数との計算(自動型変換)
自動的に大きい方(浮動小数点数)に変換してから計算される。
// 整数と小数がある数を定義 $seisu = 1; $shosu = 1.1; // 計算結果を表示する(結果は2.1と表示され、小数点は切り捨てられない) echo $seisu + $shosu;
数値と文字列との計算(自動型変換)
PHPでは文字列と数値での演算も行える。
// 整数の定義 $suji = 100; $moji1 = "あいうえお"; $moji2 = "11かきくけこ"; $moji3 = "12"; // 値の表示 echo $suji + $moji1; echo "<br>"; echo $suji + $moji2; echo "<br>"; echo $suji + $moji3;
1行目は最初から数字の変化が起こっていない。2行目は、$moji2の先頭の11を足した結果が表示されている。つまり、先頭の数字部分のみ読み取って計算をする。しかし実際には$moji2の様な変数で計算を行う事はあまりないだろう。$moji3はダブルクォーテーションで囲った文字列ではあるが、実際の中身は数字だけである。この場合は自動で数字に型が変換され、演算が行われる。
明示的に型を変換する(テキスト P25〜)
変数の型を変換する事を「型キャストする」と呼ぶ。上記の「PHPにおける変数の型」の表に載っている型同士で明示的にキャストできる。明示的にキャストするというのは、前項の自動型変換と異なり、プログラマが「この変数を○○型にキャストしますよ」と宣言することだ。型キャストするには、変数の前に()を付けて、括弧内に変更したい型を書けばいい。以下の例を参照して欲しい。
// 整数の定義 $suuji1 = 10.1; $suuji2 = 20; // 型キャストして表示する(浮動小数点数→整数) echo "キャスト前1:".$suuji1; echo "<br>"; echo "キャスト後1:".(integer)$suuji1; echo "<br>"; // 型を変更して表示する(整数→浮動小数点数) echo "キャスト前2:".$suuji2; echo "<br>"; echo "キャスト後2:".(float)$suuji2; echo "<br>";
1回目の浮動小数点から整数のキャストは、小数点が取れているのが分かるだろう。逆に2回目のキャストでは、元々「小数点以下がない整数」から「小数点以下も保持出来る浮動小数点」に変換しても、元から小数点がないので変化がないのが分かるだろう。
for文(テキスト P73〜)
プログラムでは繰り返し処理が必ずと言っていいほど発生する。繰り返し処理を使わないと同じ様な処理を全部ソースコード上に記述する必要があり、効率が良くない。繰り返しなので「ループ」と呼ぶ事もある。PHPで使える繰り返しの構文はいくつかあるのだが、今回はfor文を紹介する。
for(初期化部; 継続条件; 増分) { ループ中の処理 ・ ・ ・ }
括弧内に1.初期化部、2.継続条件、3.増分を書く事が出来、それをセミコロンで区切る。
1つずつ説明していく。
1.初期化部
ループでは通常カウントアップする変数を使用して、それをループカウントとして使う。つまり「今のループは何回目ですよ」の何回目かを保持する変数だ。その変数を初期化するのが初期化部で、ループの1回目の一番最初にのみ一度だけ実行される。通常はループカウンタがいくつから始まるかを定義する。
2.継続条件
ループを続ける条件式を記述する。毎回ループの最初に条件式が評価され、「条件式が成り立っているか?」を確認する。成り立っていれば増分を行ってからループ内の処理に入る。
3.増分
初期化部で初期化した変数に対して毎回決まった数を増やしていく。増分というセクションにしたが、必要なければ何も書かなくていいし、ループカウンタは大きい数からスタートして減らして行く事も可能だ。
ちなみに1ずつ増えていくことを「インクリメント」、1ずつ減らしていくことを「デクリメント」と呼ぶ。PHPではインクリメントとデクリメントは省略して下記の様に書く事が出来る。
-
- インクリメント(変数名:$i):$i++ または ++$i
- デクリメント(変数名:$j):$j-- または --$j
+ か - の演算子を変数名の前か後に2つ連続で記述する。前か後ろかで意味が異なるが、通常は後ろに書く事が多い。
インクリメント、またはデクリメントの実行直後の状態を下記に示す。
-
- 後ろに書いた場合:値を戻してから1をプラス(またはマイナス)して上書きする
- 前に書いた場合:1をプラス(またはマイナス)して変数に上書きしてから値を戻す
実際の値は以下の例を見て欲しい。
//初期値 $a = 0; $b = 0; // インクリメント echo $a++."<br>"; // 出力結果は 0 になる(表示後にインクリメント) echo ++$b."<br>"; // 出力結果は 1 になる(表示前にインクリメント済)
違いがわかるだろうか?
そしてfor文は以下の様に書く。
// 5回の繰り返し開始 for($i = 0; $i < 5; $i++) { echo "繰り返し".$i."回目<br>"; }
5回繰り返した後終了する。