PHP 本格入門 ㊤

現場で本格的にPHPを書くことになったので、書籍をザッと読んで気になった箇所をまとめることにした。

![No Image](https://images-na.ssl-images-amazon.com/images/I/41zPn5lFAgL._SX394_BO1,204,203,200_.jpg)

#chapter 1　はじめてのPHP
+ WEBの基本的な仕組み
+ WEBクライアントとWEBサーバーの関係性
+ PHPの環境構築

などが記載されている。詳細は割愛。

#chapter 2　PHPの基本構文
####2-1-2　変数の命名規則
+ 変数名はスネークケース(アンダースコア）もしくは**キャメルケース**
  + 例） \$total_price, \$totalPrice
  + 近年一般的なのは後者のキャメルケース

####2-1-3　変数の値を出力する ー echo命令、print命令
+ 変数の値の出力は以下の通り

```php:
<?php echo  $変数名; ?>
<?php print $変数名; ?>
<?= echo $変数名 ?>
```
+ 連結させて出力する時
  + print命令の場合：変数と値をドット（.）でつなぐ
  + echo命令と<?= $変数名 ?>の場合：ドットを使えるほか、カンマ（,）で列挙することも可
  + ドットのほうが値の連結コストがかかるため、カンマより若干スピードが落ちる

```php:
<?php
  $total = 100;
  echo '結果：' , $total , '円';  // 結果：100円
  print '結果：' . $total . '円';  // 結果：100円
?>
```

####2-2-5　文字列データの扱い（4） - 改行コードをPHP_EOLで切り替える
+ PHPの実行環境によっていCRLFとLFを切り替えたい時は**PHP_EOL**を使用する

| OS            | 改行コード     | PHP_EOLが表すシーケンス |
|:--------------|:------------|:---------------------|
| Windows       | CRLF        | \r\n                 |
| Mac（OS X以降）  | LF          | \n                   |
| UNIX/Linux    | LF          | \n                   |

+ クォートの外に書き、ドット記号（.）で連結して書く

```php:
<?php
  $mailBody  = "お問い合わせを受け付けました。" . PHP_EOL;
  $mailBody .= "お問い合わせ内容：" . PHP_EOL;
  $mailBody .= "\t商品番号「abc123」について、サイズを教えてください";
  echo $mailBody

/* 実行結果
お問い合わせを受け付けました。
お問い合わせ内容：
	商品番号「abc123」について、サイズを教えてください
*/
?>
```

####2-2-10　PHPにとっては配列も連想配列も同じ
+ キーを与えずに配列を定義した時は、自動的に0から始まる連番がデフォルトキーとなる

```php:
<?php
  $participants = [];
  $participants[0] = '小林';
  $participants[1] = '田中';
  $participants[2] = '鈴木';
  $participants['event'] = '大井町開催 ワイン会';
  $participants['event-date'] = '2021.2.8';
  var_dump($participants);

/* 実行結果
array(5) {
  [0]=> string(6) "小林"
  [1]=> string(6) "田中"
  [2]=> string(6) "鈴木"
  ["event"]=> string(28) "大井町開催 ワイン会"
  ["event-date"]=> string(8) "2021.2.8"
}
*/
?>
```

####2-2-13　配列の各要素をスカラー変数に割り当てる - list（）
+ 配列の各要素を意味の分かるようにスカラー変数に割り当てることができる
+ CSVファイルを取り扱う時などに有効

```php:
<?php
  $userData = [12345, 'Yosuke Murakami', 'Tokyo', 32];
  list($id, $name, $prefecture, $age) = $userData;
  var_dump($id);
  var_dump($name);
  var_dump($prefecture);
  var_dump($age);

/* 実行結果
int(12345)
string(15) "Yosuke Murakami"
string(5) "Tokyo"
int(32)
*/
?>
```

####2-3-1　四則演算などの計算をする - 代入演算子、加算子／減算子
+ 加算子と減算子のインクリメント／デクリメント

| 演算子 | 呼び名    | 意味 |
|:------|:---------|:----------------------|
| ++$a  | 前置加算子 | \$aに1を加えた後で\$aを返す |
| $a++  | 後置加算子 | \$aを返した後で\$aに1を加える|
| --$a  | 前置減算子 | \$aから1を引いた後で\$aを返す|
| $a--  | 後置減算子 | \$aを返した後で\$aから1を引く |

```php:
<?php
  $num1 = 1;
  $added1 = ++$num1;
  echo '前置インクリメントの時のnum1：' , $num1;
  echo '前置インクリメントの時のadded1：' , $added1;

  $num2 = 1;
  $added2 = $num2++;
  echo '後置インクリメントの時のnum2：' , $num2;
  echo '後置インクリメントの時のadded2：' , $added2;

/* 実行結果
前置インクリメントの時のnum1：2
前置インクリメントの時のadded1：2
後置インクリメントの時のnum2：2
後置インクリメントの時のadded2：1　←　ここ注目
*/
?>
```

####2-3-3　浮動小数点数の計算 - 丸め誤差への対応
+ 以下の計算式で結果を切り捨て（floor関数を使用）すると、8が期待されると思うが結果は7になる

```php:
<?php
  echo floor((0.1 + 0.7) * 10); // 結果：7 

  // あくまで8の近似値であることが分かる
  echo sprintf('%.50f', (0.1 + 0.7) * 10); // 結果：7.999999999999999111821...
?>
```
+ この浮動小数点問題に対策
  + BCMath関数を使って計算する
  + 切り捨て処理前の計算結果を、文字列型にキャストする

```php:
<?php
  /* (0.1 + 0.7) * 10を切り捨てします */

  // 文字列型にキャストする
  $result1 = floor((string)(0.1 + 0.7) * 10); // 結果：8

  // BCMath関数を使用する
  $result2 = floor((int)bcmul(bcadd(0.1, 0.7, 2), 10, 2)); // 結果：8

  echo '$result1:' , $result1;
  echo '$result2:' , $result2;
?>
```

####2-3-4　丸め誤差が起こる原因は10進数→2進数の対応づけが正確にできないことにある
+ 本質的な原因は、小数が持つ小数部（3.14の場合、14が小数部）を2進数に正確にマッピングできていない
+ **固定小数点数型**の場合、扱える桁数が浮動小数点数型と比べて小さいが正確な計算結果が出せる性質を持っている
+ 残念ながら、PHPに固定小数点数型はない

####2-3-6　2つの変数で1つの値を共有する - リファレンス渡し
+ 以下のように、&（アンパサンド）を付けて代入することで値を共有できる

```php:
<?php
  $greeting1 = 'Hello';
  $greeting2 = &$greeting1;
  // 書き換えてみる。　$greeting2を書き換えても結果は同じ
  $greeting1 = 'World';

  // 両方の値が変わっている。つまり値が共有されている
  echo '$greeting1:' , $greeting1; // $greeting1:World
  echo '$greeting2:' , $greeting2; // $greeting2:World
?>
```

+ Go言語などにあるポインタの概念とは別物。
+ メモリ上のアドレスではなく、PHPが持つ変数テーブル上の位置
+ リファレンスに対して、 インクリメント／デクリメントはできない？？

...途中