初心者のためのプログラミングことはじめ～変数～

[目次](https://qiita.com/sho0211/items/ab45f373dc219756e3d1)

# 本稿での目標

- 変数の使い方がわかる
- 変数の使いみちがわかる

# 変数
## なぜ変数が必要なのか

まず最初に、前稿のサンプルをおさらいしてみよう。

```php:selected_job.php
<html>
  <head>
    <title>選択された職業</title>
  </head>
  <body>
    <h1>あなたの職業</h1>
    <p>
      選んだ職業は<?php echo 'mage' ?>です。
    </p>
    <p>
      <strong>性格</strong>
      <?php if('warrier' == 'mage'){ ?>
        何事にも基本を大事にするタイプです。
      <?php } else { ?>
        まだ性格診断ができていません。
      <?php } ?>
    </p>
  </body>
</html>
```

このコードにどんな問題があるだろうか。

- ユーザの選択で動作が変わるものではない
- 編集を間違えると画面に表示している`mage`と判断結果に矛盾がでる可能性がある
    - `mage`と表示しているのに`warrier`として診断してしまうなど

こんな問題を解決するために変数が役に立つ

## ユーザからの入力を保存するための変数

```php:selected_job.php
<html>
  <head>
    <title>選択された職業</title>
  </head>
  <body>
    <h1>あなたの職業</h1>
    <p>
      選んだ職業は<?php echo $_REQUEST['job'] ?>です。
    </p>
    <p>
      <strong>性格</strong>
      <?php if('warrier' == $_REQUEST['job']){ ?>
        何事にも基本を大事にするタイプです。
      <?php } else { ?>
        まだ性格診断ができていません。
      <?php } ?>
    </p>
  </body>
</html>
```
こんな形でサンプルコードを変更して<http://localhost:8000/selected_job.php?job=warrier>へアクセスしてみよう。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/152901/64807633-377b-aa68-9982-1a95ae650f8f.png)|
|:-:|


PHPはもともとhtmlを拡張するために作られた背景もあり、ユーザからのリクエスト内容を処理するための機能が多く備わっている。`$_REQUEST`もその一つだ。
`$_REQUEST`にはURLパラメータと呼ばれる、URL中の`?`以降のパラメータが自動的に入るようになっている。
`$_REQUEST['パラメータ名']`で該当のパラメータを取得できる。
このように、PHPが動作時の情報を自動的に保持している変数を[スーパーグローバル変数](http://php.net/manual/ja/language.variables.superglobals.php)と呼ぶ。
スーパーでグローバルなんて盛りすぎて冗談じゃないかと目を疑うが、公式の名称なのだ。

## 繰り返し利用するための変数

先ほどの例では都度`$_REQUEST`を見ることで期待する動作を得られた。
しかし、例えばいつか気が変わって`job`ではなく`selected_job`というパラメータに変更したいと思ったとき、すべての`$_REQUEST['job']`出現箇所を`$_REQUEST['selected_job']`に書き換える必要が出てくる。
これではプログラムとして**変更に弱い**と揶揄されてしまう。
そこで`$_REQUEST['job']`と書くことの面倒くささを解消しよう。

```php:selected_job.php
<?php $job = $_REQUEST['job'] ?>
<html>
  <head>
    <title>選択された職業</title>
  </head>
  <body>
    <h1>あなたの職業</h1>
    <p>
      選んだ職業は<?php echo $job ?>です。
    </p>
    <p>
      <strong>性格</strong>
      <?php if('warrier' == $job){ ?>
        何事にも基本を大事にするタイプです。
      <?php } else { ?>
        まだ性格診断ができていません。
      <?php } ?>
    </p>
  </body>
</html>
```

変更点は`$job`に関する部分だ。
これで`$job`の値さえ変更すれば表示内容と診断結果の整合性が取れるようになることがおわかりだろうか。
このように、繰り返して利用する値は変数を用いることで、人が注意深く検証する必要がなくなる。

では、ここで出てきた変数の使い方を解説しよう。

### 代入
```php
$job = $_REQUEST['job']
```
と書くことで、以降`$_REQUEST['job']`の値を`$job`として利用できるようになる。
これを慣例的に「代入」とか「変数割当」と呼んでいる。

変数の概念を正しく知ろうとするとややこしい知識が必要になるので、今は`=`を使うことで、右辺の値を左辺の名前($job)で利用できるようにすると覚えておけば良い。
少し横道にそれるが、初心者にとって少しトリッキーなのが`=`と`==`の違いである。

```php
$a = 1; // これは代入
$a == 2; // これは左辺と右辺が同値であるか（$aが2であるか）の検査を行っている（結果は、違うので偽`false`という値になる）
```

なお、phpの変数は`$`で始まる任意の名前を指定できる。

### 参照
代入されたあとはその変数を利用できる。「参照する」と言ったりすることが多い。
代入の構文以外で変数が指定されたときには、変数の中の値を利用しているときと考えて問題ない。

> 変数の利用できる範囲は限られていて、その範囲のことをスコープと呼ぶ。
> スコープについては本シリーズの続きで触れるつもりだが、その範囲の把握に最初は時間がかかるかもしれない。
> とりあえず今は気にしなくてもよい。

## 一時的に値を保管するための変数

前稿で作った連続攻撃についても少し手を加えてみよう。

```php:continuous_attack.php
<?php $attack_times = $_REQUEST['times'] ?>
<?php $current = 0 ?>
<html>
  <head>
    <title>あなたの連続攻撃</title>
  </head>
  <body>
    <h1>あなたの連続攻撃</h1>
    <?php while($current < $attack_times) { ?>
      <p>あなたの攻撃！(<?php echo $current + 1?>回目)</p>
      <?php $current++ ?>
    <?php } ?>
  </body>
</html>
```

これで<http://localhost:8000/continuous_attack.php?times=3>にアクセスしてみよう。

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/152901/b629808a-8801-5d72-795f-51f21a3b4845.png)|
|:-:|

コードは大きく変わってしまったが、結果は期待通りだと思われる。
ここで`$current`というのは、先に挙げたユーザ入力でもなければコード中で何回も使いたいから、という用途ではなく、一時的に利用して何度も変わる値として利用している。


## while解説あるいは制御構文1.5
さて、前回には繰り返しとして利用していた`for`の呪文は出てこないし、何やら`while`などという新しい呪文が出てきた。
変更が多いので、ここで大きく横道にそれて一つずつ解説していこう。

```php
$current=0
```

繰り返しを行うのであれば、指折り何回目かを数えるのがコンピュータの流儀である。
その繰返し回数を一時的に覚えておくための指や「正」の字の役割として、変数が有用なのだ。
今回は最初に0を入れて、その値がいくつになるまでという形で数える様にしている。

```php
while($current < $attack_times)
```

`while`とは`()`内の条件が満たされている間、`{}`内の処理を繰り返し続けるための制御構文である。
今回は`$current`の値が`$attack_times`よりも小さい間ずっと繰り返す、という意味になっている。
この条件を表している`[値] < [値]`という書き方は、**[比較演算子](http://php.net/manual/ja/language.operators.comparison.php)**と呼ばれ、期待したとおり（表記の数式通り）であれば`true`、そうでなければ`false`として扱われる。
言い換えると`while`は条件式が`true`の間繰り返し続けることになる。

```php
$current+1
```

最初の代入で`$current=0`としたことで0回目始まりとなってしまうため、表示上は+1するようにしている。その方が表現として自然だからだ。
では、最初に`$current=1`としておけば良かったわけだが、プログラムの中では0始まりの数え方が多いので、ここは是非その文化に触れていただきたい。

```php
$current++
```

`++`はインクリメントと呼ばれる特殊な処理で、その値自体に+1する。
なお完全に余談だがQiitaを運営している[Increments](https://increments.co.jp/)の[ロゴ](https://qiita.com/organizations/increments)にも現れている。
前進する、という意味合いでIT関係者は好意的に用いることの多い言葉である。

### 全体

これらの要素を組み合わせることで、

```php
$counter = 0;
while($counter < $max){ // 条件を満たしている間（条件がtrueの間）繰り返す

// 何らかの処理

$counter++; // while条件の要素を更新。更新されなければ、ずっと条件がtrueのままで繰り返し続けてしまう（無限ループ）
}
```
として指定回数のループが作られている。

### forとの関連性

では、今回はなぜ`for`ではなく`while`を利用したのか。
この記事で変数の使い方をわかりやすく解説するためということもあるが、`for`自体が`while`を簡易化したもの[^1]であり、まずは`while`を理解することが`for`理解の近道になるためである。

もう一度whileのサンプルを見てみよう。

```php
$counter=0;
while($counter < 10){
  // do something
  $counter++;
}
```

この繰り返しは`for`で次のように書ける。

```php
for($counter=0; $counter < 10; $counter++){
  // do something
}
```

この関係性は以下の図のようになっている

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/152901/7588d291-b3cd-a145-56ed-30ac45783554.png)|
|:-:|

インクリメントし忘れて無限ループになったり、他で必要となる変数を変更する危険性を回避することができるので、`for`が好まれる傾向にあるだろう。

もう一度`for`の使い方を知っていただこう。

```php
for(初期状態; 繰り返し条件; 繰り返し処理毎に実行すること){ 繰り返したい処理 }
```
という構文である。


# まとめ

## 変数とは
プログラム上で値を直接扱わないですむようにするためのギミックである[^2]。
直接値を扱うと変更に弱くなったり、動作の融通が利かなくなるため、利用されるケースが多い。

### 変数の主な用途（暫定）
- ユーザ行動を取得する
- 繰り返し利用するときに名前をつけて、コードの変更をしやすくする
- 処理の結果を一時的に保管する

# 次回

[次回](https://qiita.com/sho0211/items/7243b9baf03688e127a8)は関数を使ってみよう。

# 脚注
[^1]: このように「同じ処理を別の書き方で簡単に使えるようにする」ことがある。これを**シンタックスシュガー(syntax sugar)**とか**構文糖**、**糖衣構文**などと呼ぶが、最近はあまり聞かない。意図としては、苦い薬を飲みやすくするためにシロップに混ぜたり、砂糖でくるむ錠剤（糖衣錠）にする行為をもじって、使いやすくするための書き下し文のことをそう読んでいる。構文糖にいたっては直訳で古い時代を想起させ、完全に死語ではないだろうか。
[^2]: チュートリアルなどでは「箱」と比喩されたりすることも多いが、変数の本質からすると適切ではないのでここでは避けている。