🔰【メモ】初学者がPHPの基礎まとめていく

# はじめに
１週間ほど前から、PHPの学習を始めたので理解した基礎部分をアウトプットしていく。
※未経験です。間違い等あれば指摘頂けましたら幸いです。

# PHPとは
動的にWebサービスを生成することができるサーバーサイドのスクリプト言語。
#### メリット
- シンプルな構文
- インターネット上に情報が多い
- 学習コストが低い
- 需要が高く案件が豊富
- 強力なフレームワークがある（Laravel）
#### デメリット
- Webアプリ以外の開発に不向き
- セキュリティが甘め
- 自由度が高すぎる

#### PHP公式サイト
[PHP](https://www.php.net/)


# PHPの基礎文法
## PHPの開始タグ・終了タグ
開始タグ`<?php`
終了（閉じ）タグ`?>`
PHPのファイルはHTMLも書けるが、PHPのコードしか書かない場合閉じタグを書くべきでないというルールになっている。
## メッセージの表示
メッセージは`echo`という命名を使用し、文字列は`''(シングルクォーテーション)`か`""(ダブルクォーテーション)`をで囲む
```PHP:main.php
<?php
echo 'Hello taro';
```
※上記したとおり、PHPのコードのみなので閉じタグは書いていません。
```:ターミナル
~ $ php main.php
Hello taro
```
続けてこんにちは！を追加。
```PHP:main.php
<?php
echo 'Hello taro';
echo 'こんにちは！ taro';
```
```:ターミナル
~ $ php main.php
Hello taroこんにちは! taro
```
すると上記のように表示されるが、読みにくいので改行を加える。
改行を加える方法はいくつかあるが、`PHP_EOL`を使用する。加えて文字列のあとにつなげるには`.`が必要になる。
```PHP:main.php
<?php
echo 'Hello taro' . PHP_EOL;
echo 'こんにちは！ taro' . PHP_EOL;
```
```:ターミナル
~ $ php main.php
Hello taro
こんにちは！ taro
```
コメントにする方法
macだったら`Command　+ /`windowsだったら`Control + /`

## 変数
phpで変数を使うときは`$`マークを使用する。
```PHP:main.php
<?php

$name = 'taro';

echo 'Hello ' . $name . PHP_EOL;
echo 'こんにちは！ ' . $name . PHP_EOL;
```
```:ターミナル
~ $ php main.php

Hello taro
こんにちは！ taro
```
上記の`$name`部分を**変数**、`=`を**代入演算子**、`'taro'`を**値**と言う。
続いてシングルクォーテーションを文字列内で使用する例を見ていく。
```PHP:main.php
<?php

$name = 'taro';

echo "It's \"Hello\" .\t $name" . PHP_EOL;
```
```:ターミナル
~ $ php main.php
It's "Hello" .   taro
```
上記のように文字列内に`'`がある場合、`''`で囲ってしまうと区切り文字として勘違いされるので`""`を使用する。また、`\バックスラッシュ`を使用することで、区切り文字ではなく`""`として認識される。
加えて`""`を使うことで上記のように変数を直接埋め込むことができる。

### ヒアドキュメント
`<<<EOT`、`EOT;`とするとここに記述したテキストの改行や字下げは保持したまま、変数に代入される。
```PHP:main.php
<?php

$name = 'taro';

  $text = <<<EOT
    hello! $name
      $name
    text!
  EOT;

echo $text;
```
```:ターミナル
~ $ php main.php
  hello! taro
    taro
  text!
```

## 簡単な数値の計算
```PHP:main.php
<?php

echo 10 + 3 . PHP_EOL;
echo 10 - 3 . PHP_EOL;
echo 10 * 3 . PHP_EOL;
echo 10 / 3 . PHP_EOL;
echo 10 % 3 . PHP_EOL;
```
```:ターミナル
~ $ php main.php
13 // 和
7  // 差
30 // 積
3.3333333333333 // 商
1 // 余り
```

## 変数を使った計算
変数に数字を代入した計算をする。
```PHP:main.php
<?php

$price = 500;

$price += 100;
$price *= 100;

echo $price . PHP_EOL;
```
```:ターミナル
~ $ php main.php
60000
```
上記の計算の流れを見ると
1.`$price = 500;`で$priceに500を代入
2.`$price += 100;`で500に + 100 = 600
3.`$price` *= 100;`で600 * 100 = 60000
という流れで60000が出力される。
※補足
1だけ足したい。1だけ引きたいといった場合は、`$変数++`や`$変数--`といった記号も使用される。
例
```
$price = 500;
$price++; //501
```

## 定数
変数は値を変更できるが、定数は後から変更されたくない値に使用する。
定数の書き方は以下の2通り。
```
define('NAME', 'taro');
const NAME = 'taro';
```
慣習的に**大文字**になるのと、変数とは違い`$`がつかない。
```PHP:main.php
<?php
const NAME = 'taro';
echo NAME . PHP_EOL;
```
```:ターミナル
~ $ php main.php
taro
```

## 主なデータ型
| データ型 | 説明 | 使用例 |
|:-:|:-:|:-:|
| 文字列(staring)  | 文字列  | 'hello', "こんにちは"  |
| 整数(int)  | 数値  | 100, -15  |
| 浮動小数点(float)  | 小数点を含む数値  | 3.2, -1.2  |
| null  | 何もないという意味  | null  |
| 真偽値(bool)  | 真か偽か | true, folse  |
| 配列(array)  | 複数の値をまとめる  | [1, 5, 9]  |
| オブジェクト(object)  | より複雑なデータ構造を表現  | new Object()  |

### 変数の型を調べる
変数の型を調べるには`var_dump`という命名を使用する。
```PHP:main.php
<?php

$a = 'hello';
$b = 10;
$c = -1.3;
$d = null;
$e = true;

var_dump($a);
var_dump($b);
var_dump($c);
var_dump($d);
var_dump($e);
```
```:ターミナル
~ $ php main.php
string(5) "hello"
int(10)
float(-1.3)
NULL
bool(true)
```
上記のように型を確認できる。なんらかの理由で型を変換したい場合は、キャストという方法を使用する。
方法としては、値の前に`()`をつける。
```PHP:main.php
<?php

$a = (float)10;
$b = (string)1.3;

var_dump($a);
var_dump($b);
```
```:ターミナル
~ $ php main.php
float(10)
string(3) "1.3"
```
## 条件分岐
ifを使用した条件分岐を記述する。
例:もし◯◯であれば△△を出力して、□□であれば✗✗を出力する。
```PHP:main.php
<?php

$score = 40;

if ($score >= 80) {
  echo 'Great!' . PHP_EOL;
} elseif ($score >= 60) {
  echo 'Good' . PHP_EOL;
} else {
  echo 'OK' . PHP_EOL;
}
```
```:ターミナル
~ $ php main.php
OK
```
上記の場合であれば、$scoreに代入されている値が40なので`$score >= 80(80以上)`と`$score >= 60(60以上)`には当てはまらずOKと出力されている。
$scoreに代入されている値が60以上80未満であればGoodが出力され、80以上であればGreat!が出力される。
`elseif`は条件分岐を続ける記述で、`else`はifの後に書いた条件式とelseifの後に書いた条件式のどちらにも当てはまらない場合に出力される。

### 比較演算子
| 比較演算子 | 意味 |
|:-:|:-:|
| >=  | ~以上  |
| <=  | ~以下 |
| >  | ~より大きい  |
| <  | ~より小さい  |
| ===  | ~と等しい  |
| !==  | ~と等しくない  |

### 論理演算子
| 論理演算子 | 意味 |
|:-:|:-:|
| &&  | and.なおかつ  |
| \|\|  | or.もしくは  |
| !  | ~ではない  |

比較演算子と論理演算子の使用例
```PHP:main.php
<?php

$score = 100;
$name = 'taro';

if ($score >= 50 && $name === 'taro') {
  echo 'Good job!' . PHP_EOL;
}
```
```:ターミナル
~ $ php main.php
Good job!
```

### switchで条件分岐をする
条件式に`===`が多く並ぶ場合switchを使用するとスッキリ記述できる。
例えばif文で以下のような記述がある。
```PHP:main.php
<?php
#signal = 'blue';

if ($signal === 'red') {
  echo 'Stop' . PHP_EOL;
} elseif ($signal === 'yellow') {
  echo 'Caution' . PHP_EOL;
} elseif ($signal === 'blue') {
  echo 'Go' . PHP_EOL;
}
```
switch文で以下のように記述できる。
```PHP:main.php
<?php

$signal = 'blue';

switch ($signal) {
  case 'red':
    echo 'Stop!' . PHP_EOL;
    break;
  case 'yellow':
    echo 'Caution!' . PHP_EOL;
    break;
  case 'blue':
    echo 'Go!' . PHP_EOL;
    break;
}
```
上記のif文とswitch文は全く同じ意味。
swith分のポイントとしてはcase条件の後に`:`を使用しているところと、`break`を使用しているというところ。
breakを記述しなければbreakが記述される部分まで結果が表示される。
例えば`case 'red':`の2行下の`break;`の記述を無くし、$signalに代入される値がredの場合、breakがある部分まで処理が実行されるため、Stopに加えてCautionも表示される。
また、複数の条件を実行したい場合は、caseに続けてcaseを記述する。
```PHP:main.php
~略~
case 'blue':
case 'green':
  echo 'Go!' . PHP_EOL;
  break;
```
どれにも当てはまらない場合に何らかの処理をしたい場合は`default`を使用する。
```PHP:main.php
~略~
case 'blue':
case 'green':
  echo 'Go!' . PHP_EOL;
  break;
default:
  echo 'Wrong signal!' . PHP_EOL;
  break;
```

## forを使ったループ処理
処理を繰り返し実行する方法を記述する。記述方法はいくつかあるがfor文を使用する。
```PHP:main.php
<?php

for ($i = 1; $i <=10; $i++) {
  echo 'Hello' .PHP_EOL;
}
```
上記を説明すると、`iが1から10の間、1ずつ増やしながらHelloを表示するという記述になっている。
```:ターミナル
~ $ php main.php
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
```
カウンターの変数には慣習的に`i`が使用され、数値の後には`;`を記述する。
カウンター数も表示したい場合は以下のように変数を出力すれば良い。
```PHP:main.php
<?php

for ($i = 1; $i <=10; $i++) {
  echo "$i Hello" . PHP_EOL;
}
```
```:ターミナル
~ $ php main.php
1 Hello
2 Hello
3 Hello
4 Hello
5 Hello
6 Hello
7 Hello
8 Hello
9 Hello
10 Hello
```
## whileを使ったループ処理
引き続きループ処理を記述する。今記述方法はいくつかあるがwhile文を使用する。
while文はある条件が満たされている間、特定の処理を繰り返す。
```PHP:main.php
<?php

$hp = 100;

while($hp > 0){
  echo "HP:$hp" . PHP_EOL;
  $hp -= 10;
}
echo "HP:0" . PHP_EOL;
```
```:ターミナル
$ php main.php
HP:100
HP:90
HP:80
HP:70
HP:60
HP:50
HP:40
HP:30
HP:20
HP:10
HP:0
```
1度も条件を満たしていない場合は何も処理されないため、とりあえず１回は実行して、条件次第ではまた実行して欲しい場合、`do-while`を使用する。
```PHP:main.php
<?php

$hp = -50;

do {
  echo "HP: $hp" .PHP_EOL;
  $hp -= 15;
} while ($hp > 0);
echo "HP:0" . PHP_EOL;
```
```:ターミナル
~ $ php main.php
HP: -50
HP:0
```

### forやwhileで特定の回だけ処理をスキップ
処理をスキップするには`continue`や`break`を使用する。
まずはcontinueの使用方法
```PHP:main.php
<?php

for ($i = 1; $i <= 10; $i++) {
  if ($i === 3) {
    continue;
  }
  echo $i . PHP_EOL;
}
```
```:ターミナル
~ $ php main.php
1
2
4
5
6
7
8
9
10
```
continueを使用することで`$i`が3の場合スキップするという記述になる。
そのため上記ターミナルでは3がスキップされている。
応用として($i % 3 ===0)と記述すると3の倍数のときだけスキップするなども可能。

続いてbreakの使用方法
```PHP:main.php
<?php

for ($i = 1; $i <= 10; $i++) {
  if ($i === 5) {
    break;
  }
  echo $i . PHP_EOL;
}

```
```:ターミナル
~ $ php main.php
1
2
3
4
```
上記のようにbreakを使用することでそれ移行の処理が実行されないことが分かる。

## 関数
```PHP:main.php
<?php
echo '----------'. PHP_EOL;
echo '--- 広告 ---'. PHP_EOL;
echo '----------'. PHP_EOL;
echo 'taro is great!' . PHP_EOL;
echo 'ziro is great!' . PHP_EOL;
echo '----------'. PHP_EOL;
echo '--- 広告 ---'. PHP_EOL;
echo '----------'. PHP_EOL;
echo 'saburo is great!' . PHP_EOL;
echo 'siro is great!' . PHP_EOL;
echo '----------'. PHP_EOL;
echo '--- 広告 ---'. PHP_EOL;
echo '----------'. PHP_EOL;
```
上記の記述を見ると、同じ記述が複数あることが分かります。あとで広告の表現を変えたくなった場合、１つずつ訂正していくのは面倒なので、こういった場合に関数を使用する。
関数を使用した記述
```PHP:main.php
<?php
function showAd() 
{
  echo '----------'. PHP_EOL;
  echo '--- 広告 ---'. PHP_EOL;
  echo '----------'. PHP_EOL;
}
showAd();
echo 'taro is great!' . PHP_EOL;
echo 'ziro is great!' . PHP_EOL;
showAd();
echo 'saburo is great!' . PHP_EOL;
echo 'siro is great!' . PHP_EOL;
showAd();
```
今回は関数をshowAdとしている。
場所によって広告の名前を変更したい場合などがる。そのような場合は、`仮引数`と`実引数`を使用する。
```PHP:main.php
<?php
function showAd($message) //仮引数 
{
  echo '----------'. PHP_EOL;
  echo '---' . $message . '---'. PHP_EOL;
  echo '----------'. PHP_EOL;
}
showAd('広告A'); //実引数
echo 'taro is great!' . PHP_EOL;
echo 'ziro is great!' . PHP_EOL;
showAd('広告B'); //実引数
echo 'saburo is great!' . PHP_EOL;
echo 'siro is great!' . PHP_EOL;
showAd('広告C'); //実引数
```
```:ターミナル
~ $ php main.php
----------
---広告A---
----------
taro is great!
ziro is great!
----------
---広告B---
----------
saburo is great!
siro is great!
----------
---広告C---
----------
```

### returnで値を返す
echoとreturnの違い
- echoはディスプレイへの出力
- returnは呼び出し元への返却
```PHP:main.php
<?php

function sum($a, $b, $c)
{
  return $a + $b + $c;
}

echo sum (1100, 300, 900) + sum(400, 800, 500) . PHP_EOL;
```
```:ターミナル
~ $ php main.php
4000
```
関数内でreturnを使用すると、その時点で値が戻されてそれ以降の処理は無視される。
例えばreturnの１行下にechoで何かしらの文字列を記入しても表示されない。


### スコープ
関数には**関数の外で定義された変数は使うことができない**`スコープ`というルールがあり、関数内で関数外の変数を使用したい場合は関数内で`global $変数名;`のように記述すれば使用できるようになる。

### 無名関数
関数は変数の値として代入することができ、以下のように記述する。
```PHP:main.php
<?php
$sum = function ($a, $b, $c) { //無名関数もしくはクロージャーと呼ぶ
  return $a + $b + $c;
};

echo $sum(300, 400, 500) . PHP_EOL; //1200
```
ポイントは`{`が改行されていないことと、`}`の後に`;`をつけること。
無名関数を使えると、関数自体を別の関数の引数にわたすことができたりする。

### 条件演算子
```PHP:main.php
<?php

function sum($a, $b, $c) 
{
  $total =  $a + $b + $c;
  return $total < 0 ? 0 : $total;
}

echo sum(40, 30, 500) . PHP_EOL;
echo sum(200, 3003, -5300) . PHP_EOL;
```
```:ターミナル
~ $ php main.php
570
0
```
上記のポイントは`return $total < 0 ? 0 : $total;`の部分で、`条件 ? 値A :　値B`という意味である。
条件がtrueであれば値A、falseであれば値Bとなる。
```
if ($total < 0) {
  return 0;
} else {
  return $total;
}
```
と
```
return $total < 0 ? 0 : $total;
```
は同じ意味であり、短く書くことには成功しているが、読みにくいという欠点がある。

### 引数の型を指定
引数に型を指定することで予期しない値を弾く事ができる。
```PHP:main.php
<?php

declare(strict_types=1);

function showInfo(string $name, int $score): void
{
  echo $name . ': ' . $score . PHP_EOL;
}

showInfo('taro', 'hello');
```
例えば上記の場合、引数にstring(文字列)とint(整数)を指定しているため。showInfo('taro', 'hello');の`hello`がint(整数)ではないのでエラーが発生する。
返値の値の型も指定することができて:のあとに記述するが、返値がない場合は`void`を指定する。
また、'hello'を'2'(←''内なので文字列)に変換しても2として実行されれてしまう。そういった場合は、上記のように`declare(strict_types=1);`を使用することで、厳密に型をチェックすることができる。
※補足
型の前に?をつけることができ、`?int`と出力した場合は、`int`か`null`かという意味になる。

## 配列
`[];`を使用することで配列を使用することができる。
```PHP:main.php
<?php

$scores = [ 
  10,
  20,
  100,
];

$scores[1] = 50;
echo $scores[1] . PHP_EOL;
```
```:ターミナル
~ $ php main.php
50
```
まず、`$scores`という変数を用い、複数の値を配列でまとめている。
配列内の値は上記の場合$`scores[数字]`で呼び足すことができ、インデックスは0から始まるので、10を呼び出したかったら`$scores[0]`、20なら`$scores[1]`、100なら`$scores[2]`となる。
次に`$scores[1] = 50;`の記述で20の部分に新たに50が代入されている。
それを最後の行で出力しているため、50が表示される。

### 配列のキーを指定する
配列にキーを指定するには、`=>`という記号を用いる。`=>`の左の記述をキー(key)、右側の記述をバリュー(value)という。
また、配列内の記述を詳しく表示する方法として`var_dump()`と`print_r()`という命名を使用すると便利。

var_dump()の場合
```PHP:main.php
<?php

$scores = [
  'first'  => 20,
  'second' => 30,
  'third'  => 100,
];

var_dump($scores);
// print_r($scores);

echo $scores['third'] . PHP_EOL;
```
```:ターミナル
~ $ php main.php
array(3) {
  ["first"]=>
  int(20)
  ["second"]=>
  int(30)
  ["third"]=>
  int(100)
}
100
```

print_r()の場合
```PHP:main.php
<?php

$scores = [
  'first'  => 20,
  'second' => 30,
  'third'  => 100,
];

// var_dump($scores);
print_r($scores);

echo $scores['third'] . PHP_EOL;
```
```:ターミナル
~ $ php main.php
Array
(
    [first] => 20
    [second] => 30
    [third] => 100
)
100
```

### foreachで配列を操作する
配列の全ての値に何らかの処理をする方法はいくつかあるが今回はforeachを使用する。
`foreach($変数の複数形 as $変数(value))`で受け取った値にそれぞれ処理を加える。また、`foreach($変数の複数形 as $キー(key) => $変数(value))`とすることでキーも表示することができる。

`foreach($変数の複数形 as $変数(value))`の例
```PHP:main.php
<?php

$scores = [
  'first'  => 20, 
  'second' => 30, 
  'third'  => 100,
];

foreach ($scores as $score) {  
  echo $score . PHP_EOL;
}
```
```:ターミナル
~ $ php main.php
20
30
100
```
`foreach($変数の複数形 as $キー(key) => $変数(value))`の例
```PHP:main.php
<?php

$scores = [
  'first'  => 20, 
  'second' => 30, 
  'third'  => 100,
];

foreach ($scores as $key => $score) {  
  echo $key . ' - ' . $score . PHP_EOL;
}
```
```:ターミナル
~ $ php main.php
first - 20
second - 30
third - 100
```

### 配列の要素を展開する
別の配列の値を配列に埋め込みたい場合は以下のように`...$変数名`のように記述する。`...`がないと配列の中に配列ができる。
```PHP:main.php
<?php

$moreScores = [
  50,
  32,
  [20, 25, 78],
];

$scores = [
  10,
  20,
  ...$moreScores,
  100,
];

print_r($scores);

echo $scores[4][2] .PHP_EOL;
```
```:ターミナル
~ $ php main.php
Array
(
    [0] => 10
    [1] => 20
    [2] => 50
    [3] => 32
    [4] => Array
        (
            [0] => 20
            [1] => 25
            [2] => 78
        )

    [5] => 100
)
78
```

### 可変長引数
引数が何個きても合計が出せるようにするには、`...$変数`のように記述する。
```PHP:main.php
<?php

function sum(...$numbers) 
{

  $total = 0;
  foreach ($numbers as $number) {
    $total += $number;
  }
  return $total;
}

echo sum(200, 400, 100) .PHP_EOL;
echo sum(20, 10, 500, 300) .PHP_EOL;
```
```:ターミナル
~ $ php main.php
700
830
```
`(...$numbers)`のような引数を可変長引数という。 

### 複数の返り値を受け取る
複数の数値を引数で受け取り、その合計と平均を出力する。
```PHP:main.php
<?php
function getStatus(...$numbers)
{
  $total = 0;
  foreach ($numbers as $number) {
    $total += $number;
  }
  return [$total, $total / count($numbers)]; //合計と平均の返り値
}

[$num, $average] = getStatus(4, 12, 8);　//[]でなく、list($num, $average)などでも良い

echo $num . PHP_EOL;
echo $average . PHP_EOL;
```
```:ターミナル
~ $ php main.php
24
8
```