PHP学習まとめ〜FW学習前はこれだけ知ってほしい〜

## まずはじめに

#### PHPでできること・作れるもの：Web開発
PHPはもともとC言語で書かれていたプログラムで、動的なWebサイトを作成するためのツールでした。そのため動きのあるWebサイトの作成が得意な言語です。
CakePHPやLaravelといったフレームワークを使って、大規模なWebアプリケーションを作ることもできます。

#### ・PHPインストール
下記の参考URLをもとに環境構築を行う
https://tech.amefure.com/php-homebrew


#### ・ビルドインサーバーで確認方法

```
//index.phpの内容が上記質問に記載されているソースコードとする。
$ ls
index.php
```

```
# Webサーバーを起動する。
$ php -S localhost:8080
```

下記URLでアクセス
localhost:8080/ディレクトリ名/index.php

#### ・コメント方法
```php
// コメント
or
# コメント

/* 複数行コメント
複数行コメント */
```

#### ・改行
__“\n”__
PHPで変数を出力（echo）した際に、改行コードも記述して見やすくする
改行コードを""（ダブルコーテーション）で囲ってやると改行が反映される。

```php
$text = 'あいうえお'."\n".'かきくけこ';
echo $text;

//出力結果
あいうえお
かきくけこ
```

__“\<br>タグ”__
ソースコード中にhtmlの改行文字を入れる

```php
<?php
  echo 'こんにちは';
  echo '<br>';
  echo 'さようなら';

//実行結果
こんにちは
さようなら
```

__"\<pre>タグ"__
preタグは要素内の改行や半角スペースをそのまま表示
htmlのpreタグを使ってprint_rを出力すると改行がそのまま表示されます。

```php
<pre>
<?php
  $text = 'こんにちは
  さようなら';

  print_r ($text);
?>
</pre>

//実行結果
こんにちは
さようなら
```

ただこのpreタグは改行があれば改行してくれますが、改行がない場合は改行がされません。
preタグで囲まれた文字列は改行ない限り、折り返されずに出力されてしまいます。
そのため、実際に画面に表示するために使うのではなく、デバッグするときには役立つ。

```php
//例：
<?php
 echo "<pre/>";
 var_dump($array);
 ?>
```

##PHPの基本

__・文末に;(セミコロン)を使用して文を区切ります。__
__・文字列を出力する場合、' '(シングルクォーテション) or " "(ダブルクォーテション)で囲みます。__


```php
<?php
  echo 'Hello, World!';
  // Hello, Worldを表示
?>
```

__・echoの短縮系__

```php
<?= 'HELLO WORLD'; ?>
```

__・処理の中で計算を行う事もできます。__

```php
<?php
  echo 10 + 10; # 結果 20を表示
  echo 10 - 9;    # 結果 1を表示
  echo 10 / 2;   # 結果 5を表示
  echo 10 * 3;  # 結果30を表示
?>
```

## 変数

```php
<?php
//変数に値をセットする。
$name = yamada;

//変数を出力する。
echo $name;
?>
```

#### ・変数の命名について

```
悪い例)
$namae → ローマ字なのでNG
$1name → 数字から始まってるのでNG
$名前 → 日本語なのでNG

良い例)
$name 
$user_name
$UserName

※score, score1など、連番での変数命名はコードの可読性、
デバッグ効率を下げる事になりかねないので、意味ある命名をしましょう。
```

#### ・変数の上書き

```php
<?php
//変数numに5を代入
$num = 5;
echo $num; # 結果 5

//変数numに10を代入
$num = 10;
echo $num; # 結果10
?>
```

#### ・変数に変数を代入

```php
<?php
//変数numに5を代入
$num = 5;
echo $num; # 結果 5

//変数numに5を代入し、10を足す
$num = $num + 10;
echo $num; # 結果 15

# 省略形で定義する事も可能
$num += 10; # $num = $num + 10と同定義
echo $num; # 結果 25
?>
```

__・値を1のみ追加する時のみ定義可能__

```php
<?php
$num++; # $num+= 1と同定義
echo $num; # 結果 1
?>


++を使った場合のテクニック
<?php
$num++;

//変数の前後に++をつける事で動作が異なります。
//変数の前の場合、出力する前に代入します。
echo ++$num; # 結果 2

//変数の後の場合、出力した後に代入します。
echo $num++; # 結果 1
echo $num; # 結果 2
?>
```

後置インクリメント(デクリメント)は、インクリメント(デクリメント)する前に元の値を返す。

```php
後置インクリメント
<?php
$var = 1;
echo '$var++は、' . $var++; #インクリメントする前に元の$var = 1を返す
echo '$varは、' . $var;     #インクリメントした後の新しい値を返す
#$var++は、1
#$varは、2
```

前置インクリメント(デクリメント)は、インクリメント(デクリメント)した後で新しい値を返す。

```php
前置インクリメント
<?php
$var = 1;
echo '++$varは、' . ++$var; #インクリメントした後の$var = 2を返す
echo '$varは、' . $var;     #既にインクリメントされているので$var = 2
#++$varは、2
#$varは、2
```

#### ・文字列の連結
文字列、変数を連結するには「.」、「.=」を使用します。
ドットを利用して文字列を結合する場合は、
’文字列’.’文字列’ や ’変数’.’変数’　’文字列’.’変数’　として文字列や変数を「.」で結合します。

```php
<?php
echo 'PHP' . 'カリキュラム';       # 結果　PHPカリキュラム
?>
```

ドットイコールを利用して文字列を結合する場合
右側の文字列や変数を左側の変数の末尾に追加していきます。

```php
<?php
$a = 'PHP';
$a .= 'カリキュラム';
$a .= '勉強中'
echo $a;   # 結果　PHPカリキュラム勉強中
?>
```

#### ・文字列内での変数展開
文字列はダブルクォーテーション「"」かシングルクォーテーション「'」の
どちらを使うかによって変数の扱い方が違います。

```php
<?php
$lang = 'PHP';

# ①ダブルクォーテーションで括ると変数が展開される。
# ②$lang前後の半角スペースがないとエラー。
echo "私は $lang を勉強しています。";    # 結果　私は PHP を勉強しています。

# 文字列と文字列の間にスペースを入れたくない場合は{}を使用
echo "私は{$lang}を勉強しています。";    # 結果　私はPHPを勉強しています。

# シングルクォーテーションで括ると変数は展開されない
echo ’私は $lang を勉強しています。’;    # 結果　私は $lang を勉強しています。

# 文字列の中に「"」や「'」を使用したい場合「\」を使用してエスケープする
echo '私は\'PHP\'を勉強しています。';        # 結果　私は'PHP'を勉強しています。
?>

※ダブルクォーテーションで囲った場合は、””のみエスケープする。
//右の文字列を出力。こんにちは！ " '今' 私は’PHP’を勉強しています”
echo "こんにちは！\" '今' 私は'PHP'を勉強しています\" ";
```

PHPの変数には2つの種類があり、__ローカル変数、グローバル変数__と呼ばれています。
その他、静的変数と呼ばれるものもあります。これは関数内で宣言されたローカル変数の値を保持し続けるものです。そのため変数の機能の一つといった方が適切です。

__ローカル変数：ローカル変数は決められた範囲内(スコープといいます)でしか使用できない性質があります。__
ローカル変数とは以下のような形で作成される変数です。

後述する関数内などで宣言されている場合は、その関数内でのみ使用することができます。
例えば、以下のようなコードではローカル変数を使用できません。

```php
<?php
function hoge() {
    $name = "大泉";
}

echo $name;
# ターミナルに何も表示されない
?>
```

__グローバル変数：どこからでも参照することができる変数のことです。__
例えば、以下のように関数内でも$nameを使用することができます。

```php
<?php
$name = "大泉";

function func() {
    global $name;  //globalと記載する。
    echo $name;
}
echo $name;
# ターミナルに大泉と表示される

func();
# ターミナルに大泉と表示される
?>
```
注意したいのが、グローバル変数を関数内で使用するには、global $nameのように使用するグローバル変数を宣言する必要があることです。

## if文

if 文
if、else、elseifは条件によって処理を振り分けるための制御文です。
条件によって異なった処理を行う場合に利用します。
簡単に言うと「(if)もしも○○であるなら××しなさい、(else)それ以外であれば△△しなさい」を実現することができます。

```
①
if  (条件式) {
    条件式が真(true)の処理;
}

②
if  (条件式) {
    条件式が真(true)の処理;
} else {
     条件式が偽(false)の処理;
}

③
if  (条件式1) {
    条件式が真(true)の処理;
} else if (条件式2) {
     条件式1が偽(false)、条件式2が真(true)の処理;
}

※入れ子(ネスト)することもできます。
if  (条件式1) {
　 条件式1が真(false)の処理
     if (条件式2) {
         条件式1が真(true)、条件式2も真(true)の処理;
     }
}
```


#### ・比較演算子

if文の条件式には「◯◯と等しい」「◯◯より大きい」などを記述することになります。
この条件式で使用するのが比較演算子です。
PHPの比較演算子は以下になります。
演算子

記述例

```
a == b
aとbの値が等しい

a === b
aとbの値が等しく型も等しい

a != b
aとbの値が等しくない

a <> b
aとbの値が等しくない

a !== b
aとbの値または型が等しくない

a > b
aがbより大きい

a >= b
aがbより大きいか等しい（aがb以上）

a < b
aがbより小さい

a <= b
aがbより小さいか等しい（aがb以下）
```

サンプルコード

```php
<?php
$num = 10;
$flg = true;

# 真(true)となる
if  ($num == 10) {
    echo '変数numは10と等しい';　# 実行される
}

# 真(true)となる
if  ($num == '10') {
    echo '変数numは'10'と等しい'; 　# 実行される
}

# 偽(false)となる
if  ($num === '10') {
    echo '変数numは'10'と等しい';    # 実行されない
}

# bool型の判定
if ($flg === true) {
    echo '真！';    # 実行される
}

# このように変数のみ条件式に指定しても上と同義
if ($flg) {
    echo 'trueなら実行されるよ';    # 実行される
}
?>
```

-ポイント-
「==」演算子の場合は値が等しいかどうかをだけを判別するため数値と文字列の比較であっても等しいとされる場合があります。
なので型も含めた確実な比較を行うには「===」演算子を使用します。

#### ・論理演算子

単独の条件式だけでなく、「◯◯かつ△△」「◯◯または△△」といった複数の条件式を記述したい場合があります。
このような場合に記述するのが論理演算子です。
PHPの論理演算子は以下になります。

```php
&& または and
a && b
aとbが共に真の場合に真(かつ)

|| または or
a || b
aかbの少なくとも1つが真の場合に真(または)

!a
aが真の時に偽、偽の時に真
```

サンプルコード

```php
<?php

$age = 25;
$pref = '東京';
$job = 'エンジニア';

# AND条件
if ($age > 20 && $age < 30) {
    echo '20代です。';
}

# OR条件
if  ($age >= 20 || $pref === '愛知') {
    echo '愛知出身か20歳以上です。';
}

# エンジニアかデザイナーで20歳以上を真としたい時

# ダメな例
# 演算子の優先度で、エンジニア　または　20歳以上のデザイナー　という条件になってしまう。
if ($job === 'エンジニア' || $job === 'デザイナー' && $age >= 20) {
}

# いい例
# カッコで囲む
if ( ($job === 'エンジニア' || $job === 'デザイナー') && $age >= 20) {
}
?>
```
-ポイント-
演算子には優先順位があります。
AND　＞　OR
なので、適宜、OR条件式をカッコで括る必要があります。

#### ・switch文

-ポイント-
break;を書き忘れるとdefaultの処理に必ず入ってしまうので注意が必要です。
if文でelse if が複数に連なる場合にswitch文を使うと便利です。

```php
<?php
$num = 3;

# if文の場合
if ($num === 1) {
    echo 'ONE';
} else if ($num === 2){
    echo 'TWO';    
} else {
    echo '1〜2以外';  
}

# switch文の場合 (上と同義）
switch ($num) {
    case 1:
        echo 'ONE';
        break;
    
    case 2:
        echo 'TWO';
        break;
        
    default:
        echo '1~2以外';
        break;
}
?>
```

#### ・三項演算子
基礎構文：条件式 ? 真の式 : 偽の式

if、elseを１文で表すことができます。
コードがスッキリするので意外と使用します。

```php
<?php
$age = 20;

# if ($age >= 20) {
#     $res = '成人';
# } else {
#     $res = '未成年';
# }
# 上記を三項演算子で記述すると
# １行で済みます。

$res = $age >= 20  ? '成人' : '未成年';
 
echo $res;   # 結果　成人
?>
```

## 配列 
これまで、変数でデータを1つずつ管理していましたが、
複数のデータをまとめて管理したい場合に配列を使用します。
簡単にいうと、複数の変数をくっつけたものが配列で、
キー(添字）と値のペアからなる要素を複数管理することができます。

#### ・配列の使い方
配列の記述方法は、array関数を使用する方法と、
[ ]を使用する方法の二つがあります。
※数値でも、配列は「” “ , ‘ ’」で囲むこと。；　も忘れずに！

サンプルコード
__・配列の初期化__

```php
<?php

# 空の配列で初期化
$array = array();
$array = [];

# 値を代入して初期化（配列）
$array = array('20', 'エンジニア');
$array = ['20', 'エンジニア'];

# 値を代入して初期化（連想配列）
$array = array('age' => '20', 'job' => 'エンジニア');
$array = ['age' => '20', 'job' => 'エンジニア'];
?>
```


#### ・配列へ値を格納

```php
<?php
# []を使用した配列への格納 (添字０から自動付与される）
$array[] = '20';
$array[] = 'エンジニア';

# array関数を使用した配列への格納 (添字０から自動設定される）
array_push($array, '20');
array_push($array, 'エンジニア');
?>
```

__・連想配列へ値を格納__

```php
<?php
# []を使用した連想配列への格納
$array['age'] = '20';
$array['job'] = 'エンジニア';
$array['pref'] = '東京';

# array関数を使用した連想配列への格納
$array += array('age' => '20');
$array += array('job' => 'エンジニア');
$array += array('pref' => '東京');
?>
```

__配列の注意点__

```php
<?php
//これは単純に上書きしていくだけ。
$array[a] = 1;
$array[a] = 2;

var_dump($array); //[ a => 2]

//配列に追加していく方法は、例えば次のようにします。
$array1 = [];
$array1[] = 1;
$array1[] = 3;
$array1[] = 5;
var_dump($array1); // [1, 3, 5]

$array2 = [
    'key' => [],
];
$array2['key'][] = 'a';
$array2['key'][] = 'b';
$array2['key'][] = 'c';
var_dump($array2); // ['key' => ['a', 'b', 'c']]

※追加するなら [ ] をつけること！
```

#### ・array_column()関数

引数に渡した配列の中から、単一のカラムを取り出すための関数です。
この関数は、主にDBから取得した値を、「カラム名　=>　値」の形で保管する、多次元の連想配列を対象に使用する関数です。
 
__array_columnを使う方法__
array_column ( $配列 , $取り出すカラム名 [, $インデックスに指定するカラム名] )

第一引数には、取り出すカラム名とデータを含む配列を渡します。
第二引数には、取り出すカラム名の文字列を渡します。
第三引数には、オプションで、取り出したカラム名のキー名となるカラム名を文字列で渡せます。デフォルトでは、null値を渡しています。

これらの引数を渡した結果、第一引数で渡した配列の中から第二引数に渡したカラム名の文字列を探し出します。そのカラム名に対する値のみを抽出し、__'配列'__として返却します。

```php
<?php
$rows = [
    0 => [ 'id' => 40, 'title' => 'dave', 'comment' => 'Hello, world!'],
    1 => [ 'id' => 10, 'title' => 'alice', 'comment' => '你好，世界！'],
    2 => [ 'id' => 30, 'title' => 'charlie', 'comment' => 'こんにちは、世界！' ],
];

var_export(array_column($rows, 'id'));
/* =>
 array (
   0 => 40,
   1 => 10,
   2 => 30,
 )*/

//第3引数を指定にすると、その要素を結果の連想配列のキーにできる。
$rows = [
    0 => [ 'id' => 40, 'title' => 'dave', 'comment' => 'Hello, world!'],
    1 => [ 'id' => 10, 'title' => 'alice', 'comment' => '你好，世界！'],
    2 => [ 'id' => 30, 'title' => 'charlie', 'comment' => 'こんにちは、世界！' ],
    3 => [ 'id' => 20, 'title' => 'bob', 'comment' => 'Salve , per omnia saecula !' ],
];

var_export(array_column($rows, 'title', 'id'));
/* =>
 array (
   40 => 'dave',
   10 => 'alice',
   30 => 'charlie',
   20 => 'bob',
 )*/
```
 
#### ・配列の値参照
$配列名[添字]で参照することができる
添字＝インデックス番号
※インデックス番号は0から始まる

```php
<?php
$array = ['20', 'エンジニア', '東京'];

$age = $array[0];    # $age = '20'
$job = $array[1];    # $job = 'エンジニア'
$pref = $array[2];   # $pref = '東京'
?>
```

__・連想配列の値参照__
$配列名[キー]で参照することができる

```php
<?php
$array = ['age' => '20', 'job' => 'エンジニア', 'pref' => '東京'];

$age = $array['age'];    # $age = '20'
$job = $array['job'];    # $job = 'エンジニア'
$pref = $array['pref'];  # $pref = '東京'
?>
```

#### ・多次元配列
配列の値に配列を格納することもできます。
配列が入っている配列を多次元配列いいます。

サンプルコード
多次元配列の作成

```php
<?php
# []で作成
$array = [
  '山田' => [
    'age' => '20', 
    'job' => 'エンジニア',
    'pref' => '東京'
  ],
  '田中' => [
     'age' => '25', 
     'job' => 'デザイナー',
     'pref' => '埼玉'
  ];

# array関数で作成
$array = array(
  '山田' => array(
    'age' => '20', 
    'job' => 'エンジニア',
    'pref' => '東京'
  ),
  '田中' => array(
    'age' => '25', 
    'job' => 'デザイナー',
    'pref' => '埼玉'
  );

# １人ずつ配列を作成してそれを配列に格納していく
# できる配列は上と同じ
$yamada = ['age' => '20', 'job' => 'エンジニア', 'pref' => '東京'];
$tanaka = ['age' => '25', 'job' => 'デザイナー', 'pref' => '埼玉'];

$array ['山田'] = $yamada;
$array['田中'] = $tanaka;
?>
```

__・多次元配列の参照__
$配列名[キー][中の配列のキー]

```php
<?php
$yamada_age = $array['山田']['age'];    # 山田の年齢（２０）
$tanaka_job = $array['田中']['job'];    # 佐藤の職業（デザイナー）
?>
```

#### ・var_dump

変数の情報を表示する関数です。

var_dumpの書き方
var_dump(情報を出力する変数)

>配列に関する関数一覧
https://www.php.net/manual/ja/ref.array.php

## 繰り返し処理
ある条件まで処理を繰り返し（ループ）実行する際は
__①while、②for、③foreach__
を使用します。

#### ①while
while文は指定した条件がtrueの間、処理が繰り返し実行されます。
条件がfalseにならないとループを抜けない為、whileの中で条件式が変化するような処理にしないと無限ループとなってしまうので注意が必要です。

```
while文の書式
while (条件式) {
　繰り返し処理
}
```

サンプルコード

```php
<?php

# 1~10を順に表示する
# 処理の流れは①=>②=>③=>①=>②=>③……
$num = 1;
while ($num < 11) {    # ①$numが11より小さいか判定
    echo $num;         # ②$numの値を表示
    $num++;            # ③$numの値を加算
}

# 無限ループ
$num = 1;
while($num > 0) {   # ループ処理中に$numが0より下になることはない
    echo $num;
    $num++;
}
?>
```

#### ②for

```
for文の書式
for (初期値; 条件式; 変化式) {   ※エラー　区切るときは　；　を使うこと！
　繰り返し処理
}
```

サンプルコード

```php
<?php
# 1~10を順に表示する
# 処理の流れは①=>②=>③=>④=>②=>③=>④=>②=>③=>④……
for ($num = 1; $num < 11; $num++) { #①$num = 1(初期化処理)②$num < 11(条件式)④$num++(変化式)
    echo $num;    # ③$numの値を表示
}
?>
```
※エラー①
$i=01 など 頭が0から始まる数値はエラーとなる。
先ほどの1~10を表示する処理など、値を同じように変化させていき
条件式で判定する処理には、for文を使うことで簡潔に記述することができます。

※エラー②

```php
for ($i = 1; $i < 10; $i++) {
   for ($a = 1; $a < 10; $a++)
       echo " $i * $a =" .  $i * $a;
}

/*実行結果
1*1=1
・・・
1*9=9
2*1=2
・・・
2*9=18
・・・
↑の場合は、ネストした$aから順に増えていく。一巡し終わったら、
$iがプラス１ずつ増えていく。*/
```

#### break、continue
breakはswitch文でも使用していましたが、任意のタイミングで繰り返し処理を「抜ける」ことができます。
continueは繰り返しブロックの内でそれ以降の処理を「スキップ」することができます。

サンプルコード
__・break__

```php
<?php
# 1~10までを表示するときに5で抜ける
for ($i = 1; $i <= 10; $i++) {
  if ($i === 5){
    echo '抜ける';
    break;
  }
  echo $i;
}
# 結果　1234抜ける
?>
```

__・continue__

```php
<?php
# 1~10までを表示するときに5だけスキップせる
for ($i = 1; $i <= 10; $i++) {
  if ($i === 5){
    echo 'スキップ';
    continue;
  }
  echo $i;
}
# 結果　1234スキップ678910
?>
```

#### ③foreach
エラー
foreachは配列に含まれる各要素を取り出したい場合に使用します。

```
foreachの書式
foreach (配列変数 as 変数) {
    繰り返し処理
}
```

サンプルコード

```php
<?php
$emp_list = ['田中', '山田', '佐藤'];

foreach ($emp_list as $emp) {   # 配列の値順番に$empに入れる
  echo $emp. ','; 
}
# 結果　田中,山田,佐藤,
?>
```

foreachは配列のキーも取り出すことができます。
foreach (配列変数 as キー変数 => 値変数){
    繰り返し処理
}

```php
<?php
$fruits = ['りんご' => 'Apple', 'ぶどう' => 'Grape' , 'もも' => 'Peach'];
 foreach ($fruits as $key => $val) {   # 配列のキーを$key、値を$valに順番入れる）
  echo $key. '=>'. $val;
}
# 結果　りんご=>Appleぶどう=>Grapeもも=>Peach


//以下の配列から名前、年齢、出身を表示
$emp = [
   '山田' => ['age' => '20', 'pref' => '東京'],
   '田中' => ['age' => '23', 'pref' => '神奈川'],
   '佐藤' => ['age' => '24', 'pref' => '埼玉'],
   '鈴木' => ['age' => '25', 'pref' => '千葉']
];

foreach ($emp as $key => $val) {
   echo "name:" . $key;
   echo "age:" . $val["age"];  //キーを入力で取得できる。
   echo "pref:" . $val["pref"]; //キーを入力で取得できる。
}
?>
```

#### HTMLに埋め込む
繰り返し文「{」の代わりに「:」、「}」の代わりに「endforeach」と記述し、その間に処理を書いていきます。この処理部分にはHTMLのタグを書くことができるので便利です。
HTMLにforeach文を埋め込むときは右図のようにしましょう。

```php
<html>
・・・
<?php if($num < 10) : ?>
<p><?php echo “１０以下です。?”></p>
<?php endif ?>
・・・
</html>
```

#### 参考：strstr関数
strstr関数は対象の文字列から検索したい文字列を検索する関数です。
strstr関数は単純に文字列が存在するかどうかを確かめたい時に使います。

__構文：strstr(対象の文字列, 検索したい文字列)__

例えば、strstr(“abcdefg”, “cde”) と実行すると、abcdefgの中からcdeを検索します。検索して該当する文字列があった場合、「対象の文字列」が、ない場合はFALSEが戻り値となります。
大文字小文字を区別しないで検索したい場合は「stristr関数」を使うことで実現できます。

__・数値を文字列に型変換する方法__
文字列 = (string) 数値;

変換した数値に対して文字列の型であるstringでキャストすることで数値を文字列に変換することができます。
 
またキャストを使う方法以外では__strval関数__を使う方法があります。
__strval関数:引数で設定した数値を文字列に変換可能です。__

__・構文：文字列 = strval(数値);__

サンプルコード

```php
<?php
//応用
//1~50までの3が付く数字と3の倍数だけの配列を作成し、その後出力。
$array = [];

for ($i = 1; $i < 51; $i++) {
    $num = strval($i);
    if (strstr($num, "3") || ($i % 3 === 0)) {
        $array[] = $i;
    }
}

foreach ($array as $value) {
    echo "<pre/>";
    echo $value;
}
?>
```

## 関数とは
関数とは、あるまとまった処理を行い、値を返すものです。
ここで、()の中に与える値を「引数」といいます。

自作の関数を宣言して、呼び出すやり方を覚えていきましょう。
サンプルコード
基本の記述方法

```php
<?php
# 関数の宣言
function greeting($name) {
    $msg = 'こんにちは！' . $name . 'さん';
    return $msg; # メッセージを返却 
}

# 関数の呼び出し
$msg = greeting('田中');
echo $msg;
//実行結果
//こんにちわ！田中さん
?>
```

__※注意点__
関数内での変数はローカルスコープ（関数内でのみ参照可能）である点。
greeting関数の中の\$msgと呼び出した結果を格納している\$msgは別変数です。

#### global宣言
__スコープ外の変数を関数内に引き継ぎ__使いたい時には、
関数内で使用するグローバル変数を__あらかじめ宣言__しておく必要があります。
それには __global__ という命令を使います。


```php
function func() {
    global $num;
    $num = 10;
}
```

このようにglobalで\$numを宣言しておくと、この変数はローカル変数では無くグローバル変数の\$numである、ということになります。

この結果、以下のように実行すると、10と表示されます。

```php
<?php
$num = 5;

function func() {
    global $num; //上記の$numを使えるようにする。
    $num = 10;
}

func();
echo $num; // 10
?>
```

#### 引数を複数にする

```php
<?php
# 関数の宣言
function greeting($str, $name) {
    $msg = $str . $name . 'さん';
    return $msg; # メッセージを返却 
}

# 関数の呼び出し
$msg = greeting('こんにちは！','田中');
echo $msg; //こんにちわ！田中さん
?>
```

#### 返り値のない関数

```php
<?php
# 関数の宣言
function greeting($name) {
    echo 'こんにちは！' . $name . 'さん';
}

# 関数の呼び出し
greeting('田中');
?>
```

#### 配列を返却する
複数の値を返却する場合は配列を返却し、list()で受け取ります。

```php
<?php
# 関数の宣言
function getNameList() {
    return ['田中', '山田', '佐藤'];
}

# 配列のまま受け取り
$name_list = getNameList();

# 変数に分割して受け取り
list($tanaka, $yamada, $sato) = getNameList();
echo $tanaka . $yamada . $sato;
?>
```

#### 引数にデフォルト値をセットする
引数にデフォルト値をセットしておくことができます。
引数が渡ってこなくてもエラーにならない処理を作る時などに有効です。

```
function sample($fuga=null) {
・・・
}
```

```php
<?php
# 関数の宣言
function greeting($name = '名無し') {
    $msg = 'こんにちは！' . $name . 'さん';
    return $msg; # メッセージを返却 
}

# 関数の呼び出し
$msg = greeting();   # 引数を渡さない
echo $msg;           # 結果　こんにちは！名無しさん
?>
```

※エラー①：関数の初期値
→バグ防止のために関数の引数には初期値を定義しておきましょう。
→大体はnullや空文字を入れるのが一般的ですね。

※エラー②
関数はreturnの場合、echoをつける。
返り値がない場合(関数内にechoの記述がある場合)は、そのまま記述。

#### 型をコメントに書く
何を渡して何を返すのかわからなくなるので、明記して置くのがいいです。

```php
<?php
/**
 * @param string $name 名前
 * @return string　文字列
 */
function greeting($name) {
    $msg = 'こんにちは！' . $name . 'さん';
    return $msg; # メッセージを返却 
}
?>
```

#### PHPDocの書き方（実例：クラス・メソッド）
クラスやメソッドの説明を記述する場合は「引数」「返り値」の情報を記述します。
オブジェクトのプロパティ情報といった場合は「変数」の情報を記述します。
これらの情報もタグ形式で記述します。
@var [型] 説明
@param [型] 変数名 説明
@return [型] 説明
１．@var は変数、オブジェクトのプロパティ情報
２．@param が引数の情報
３．@return が返り値の情報
なお、クラスやメソッドの説明ではこれらのタグは必須になります。

以下、実例です。

```
/**
*  マスアサインメントの保護を外す
*   
* @var array プロパティ
*/
protected $fillable = [ 'name', 'email', 'password', ];
：

/**
* エリアチェック
*
* @param string $area_code 地域コード(入力値)
* @return array 地域コード、地域名
*/
private function check_area($area_code)
{
：
```
int ・・・1や100などの整数型。
float／double・・・浮動小数点数です。ざっくり言うと少数です。
string・・・りんご、ばなな、などの文字列です
boolean・・・trueかfalseのどちらかです。

#### 参考まとめ
>型の説明
https://www.php.net/manual/ja/language.types.declarations.php#language.types.declarations.mixed

>数値チェック関数一覧
https://www.flatflag.nir87.com/is_numeric-682

>isset関数とempty関数の使い分け
https://gray-code.com/php/check-variables-exists-and-not-empty/
※エラー　isset(\$text1, \$text2)で複数指定可能。

## GET、POSTについて
__Webページの仕組み__
ブラウザからサーバに「このファイルを見せてください」と要求（リクエスト）をすると、
サーバはリクエストに応じてWebページの情報を返してきます(レスポンス)
このリクエストとレスポンスの繰り返しでWebページを閲覧しています。

__リクエストの方法（メソッド）でよく使用するのがGET、POSTです。__
GETやPOSTを利用すると、リクエストすると同時にデータ（フォームで入力したデータなど）をサーバに渡すことができます。
__GETとPOSTはそれぞれデータの受け取り方に特徴があります。__

#### GET
・サーバから情報を取得してくる時に使用する
・見られたくない情報は、GETでは送らない
・送信できるデータ量に制限がある
・ブックマークに保存するページ
以下のようにURLの?よりあとに「名前=値」という形式でデータを付加してリクエストします。

この ? よりあとの文字をクエリストリングといいます。
https://example.com/index.php/?lang=PHP&name=yamada

__このように送信するデータがURLで丸見えになってしまうので、見られたくない情報はGETで送らないようにします。__

__※GETは取得する際に使う__

__・PHP側での受け取り方__

```
$_GET['名前']で受け取ります。
```
データがある場合のみ処理をするため、isset()を使用しましょう。

先ほどのURLでリクエストした場合の例

```php
<?php
# データがある場合のみ処理
if (isset($_GET[‘lang’])){
   echo $_GET['lang'];  # PHP
   echo $_GET['name'];  # yamada
}
?>
```

#### POST
・サーバへ情報を登録する時に使用する（データベースへの格納など）
・データ量が多い場合
・他の人に見られたくない情報を送る場合（パスワードなど）

__・PHP側での受け取り方__
GETをPOSTに変えるだけです。
__※POSTは送信する際に使う__

```
$_POST['名前']で受け取ります。
```

```php
<?php
# データがある場合のみ処理
if (isset($_POST[‘lang’])){
   echo $_POST['lang'];  # PHP
   echo $_POST['name'];  # yamada
}
?>
```
エラー
※GETならGETで、POSTならPOSTで受け取ること！

サンプルコード

```html:html.index
<!DOCTYPE html>
<html lang=“ja”>

<head>
    <meta charset=“UTF-8”>
    <title>GET・POST練習</title>
</head>

<body>
    <h1>データの送信</h1>
    <!-- action=送信先 method=postで送る -->
    <form action="index.php" method="post">
        <label>名前</label><input type="text" name="name"><br />
        <label>年齢</label><input type="number" name="age"><br />
        <input type="submit" value="送信">
    </form>

    <h1>データ送信2</h1>
    <!-- action=送信先 method=postで送る -->
    <form action="index.php" method="post">
        <label>ID</label><input type="number" name="id"><br />
        <label>PASSWORD</label><input type="password" name="password"><br />
        <input type="submit" value="送信">
    </form>

</body>

</html>
```

```php:index.php
<?php
/*フォームからデータを受け取り、「XXさんはXX歳です」と表示
また、年齢が120歳以上ならエラーを表示*/

if (isset($_POST["name"])) {
    if ($_POST["age"] < 120) {
        echo $_POST["name"] . "さんは" . $_POST["age"] . "歳です";
    } else {
        echo "エラー";
    }
}

/*フォームから送信されたID、パスワードを会員リスト(ID,パスワード,名前)と比較して
ID、パスワードが一致したら名前を、それ以外はエラーメッセージを表示してください。*/

//会員リスト
$list = [
    "member1" => ["ID" => "1", "PASSWORD" => "a"],
    "member2" => ["ID" => "2", "PASSWORD" => "b"],
    "member3" => ["ID" => "3", "PASSWORD" => "c"]
];

$message = "一致しません";

if (isset($_POST["id"]) && isset($_POST["password"])) {
    foreach ($list as $key => $val) {
        if ($val["ID"] === $_POST["id"] && $val["PASSWORD"] === $_POST["password"]) {
            $message = $key;
        }
    }
}

echo $message;
```

#### $_REQUEST

・現在の\$_GET、 \$_POST、\$_COOKIE 等のスーパーグローバル変数の内容を纏めたもの。

__ユーザー入力や、サーバーによりスクリプトへ渡される全ての値の変数です。__

・\$_REQUESTは、連想配列で使用します。
・\$_REQUESTは、スーパーグローバル変数なので、スクリプトのコード中どこからでも使用することが出来る変数です。関数やメソッドの内部で使用する場合にも global \$_REQUEST; とする必要はありません。
・PHPのREQUESTの値は、デフォルトでは cookie > POST > GETの順で優先されます。

__※GET,POSTでも$_REQUESTで受け取れる。__

## require
「外部ファイルを読み込み、実行したい」ときに使われる文です。プログラムを単一のファイルで書いていくと膨大な行数になり、コードが書きづらくなったりバグを発見しづらくなったりします。

require文の書き方

```php
<?php
require "phpファイル";
//もしくは
require("ｐｈｐファイル");
?>
```
実行するphpファイルと同じディレクトリにある場合は単純にファイル名を指定します。
異なるディレクトリ、例えば
__/home/user/test.php__
を実行するとして
__/home/user/lib/test2.php__
を呼び出したいときには
__require "lib/test2.php";__

※一度しか読み込まなくていいものは__\_once__をつける。
__require_once(‘test.php’)など__

#### include文とrequire文の違い
__「ファイル読み込み失敗したときにエラーで終了するか警告で継続するか」という点です。__

どちらも対象ファイルを読み込みますが、この時ファイルが存在しない、関数で構文エラーなどが起こった場合、それぞれ以下のような挙動となります。
__require：致命的なエラー（Fatal）となり処理を停止
include：警告（Warning）となり処理は継続
includeとrequireどちらのが良いか__

以下に使い分けの例を挙げてみます。

__・require：コア部分や後の処理に影響する場合は（内部）__
バッチ処理など致命傷なエラーにより後続処理の影響が発生する場合には、処理を中断させたいのでrequireを使用します。

__・include：画面処理などの場合（外部）__
画面表示などで表示処理のための計算処理でエラーとなるような場合は、requireだと画面が全く表示されなくなるのを避けるためにincludeを使用するなどの使い分けが考えられます。

```php:header.php
<header>
  <nav> ~ </nav>
</header>
```

```php:index.php
<?php include('header.php'); ?>
<body> ~ </body>
```

※ディレクトリ構造により記述変える
include('menu/sidemenu.php');
  // menu/sidemenu.php　を読み込む


## JSONとは？
JSONは、JavaScript Object Notationの略です。
直訳すると、「JavaScriptのオブジェクトの表記法」となります。

JavaScript：プログラミング言語の1つ。JSとも言う
Object：オブジェクト。
Notation：表記法

```
JSONの例
{
  "productId": 1,
  "productName": "backlog",
  "price": 100,
  "tags": [ "PHP", "Ruby" ]
}
```

#### JSONの特徴
・世で広く使われているデータの表記法
・人間にとって読みやすい（平易なテキストデータである）
・軽量（XMLと違ってデータ量が軽い）
・XML：XMLもJSONのようなデータの記述法であり、重め
・プログラムに容易に組み込める（形式がJSのオブジェクトと全く同じ形式）
・ほとんどのプログラミング言語でJSONをサポートしている（異なる言語でもJSONでやり取りできる）
・JSONファイルの拡張子は.json

#### JSONの記述ルール
__・{}（波括弧）で囲む
・それぞれのデータは、キー（key）と値（value）のペアにする必要がある
・keyとvalueは:（コロン）で区切る
・それぞれのデータを,（カンマ）で区切る
・keyは文字列、valueは様々なデータ型で記述可能
・文字列は必ず""（ダブルクオーテーション）で囲む__

連想配列に当てはめると考えやすいですね。

#### 利用可能なデータの種類
利用可能なデータの種類は6つあります。

__①文字列__

__文字列は、必ず""（ダブルクオーテーション）で囲みます。__
ただし、'（シングルクオーテーション）による代用は不可。

```
例
"これはPHPです。", "https:\/\/hogehuga.com"
```

__②数値__
「整数」または「実数」をそのまま表現可能です。

```
例
1001, 3.14
```

__③真偽値__
真偽値はBooleanとも言います。true, falseのいずれかの値を取ります。

__④配列__
__配列は必ず[]（角括弧）で囲みます。__
配列内のデータは必ず,（カンマ）で区切り、データはどんな型（文字列、数値、真偽値、配列、オブジェクト、Null値）のものでも入れることができます。

```
例
["PHP", "Ruby", "JS"], [PHP言語, "Ruby言語", true, "JS言語"]
```

__⑤オブジェクト__
__オブジェクトは、{}で囲みます。また、キー（key）と値（value）のペアにする必要があり、それぞれのデータは,（カンマ）で区切ります。__
JSON自体がオブジェクト（JavaScript Object Notation）であり、JSONの記述方法と同様のルールで表現します。

```
例
{ "productId": 1, "productName": "A green door", "price": 12.50, "tags": [ "home", "green" ] }
```

__⑥Null値__
Null値は、何もない（空データ）を表します。小文字のnullで表記します。

## PHPでJSONを使うには
JSON読み込みには、以下の関数を使用します。
使い方は自分で調べてみてください。

__・file_get_contents__
>公式
https://www.php.net/manual/ja/function.file-get-contents.php

__・json_decode__
>公式
https://www.php.net/manual/ja/function.json-decode.php

#### josnの読み込み手順
①\$file="sample.json"; //読み込みたいファイルを変数に入れる
②\$json=file_get_contents(\$file);　//指定したファイルの要素をすべて取得する
③\$arr=json_decode(\$json,true);　//json形式のデータを連想配列の形式にする(デコードする)

__・file_get_contents()関数に$urlを変数を入れる。__
file_get_contents()は、ファイルなどを組み込む際に使う。

__その後、json_decode()により__
json形式のファイルから元の形式に変換する。

__また、第二引数のtrueは、__
・falseにするとオブジェクトを返し、
・trueにすると連想配列形式のオブジェクトを返します。

>
エンコード：「データを他の形式へ変換すること」です。
デコード：エンコードされたデータを元の形式へ戻すこと。

サンプルコード

```json:sample.json
[{
        "01": {
        "id": "01",
        "name": "北海道",
        "short": "北海道",
        "kana": "ホッカイドウ",
        "en": "hokkaido",
        "city":[
            {"citycode":"0010001","city":"札幌市中央区"},
            ・・・
            ・・・
        "47": {
        "id": "47",
        "name": "沖縄県",
        "short": "沖縄",
        "kana": "オキナワケン",
        "en": "okinawa",
        "city":[
            {"citycode":"0470001","city":"那覇市"},
            ・・・  
        ]
    }
}]
```

```php:index.php
<?php
//jsonファイルを読み込んで各都道府県名（キー名：name）を表示させる
$json_file = file_get_contents("sample.json");
$json = json_decode($json_file, true);

foreach ($json[0] as $key => $val) {
    echo "<pre>";
    echo "name:" . $val["name"];
}

/*
指定の形式に配列にセットして表示させる
[
    "都道府県名A" => [市町村名1, 市町村名2...],
    "都道府県名B" => [市町村名3, 市町村名4...],
    ...
  ]
*/
$array = [];
foreach ($json[0] as $key => $val) {
    $city = array_column($val["city"], "city");
    $array[] = $val["name"];
    $array[$val["name"]] = $city;
}

echo "<pre>/";
var_dump($array);
```

##XSS(クロスサイトスクリプティング)
JavaScriptを実行するコードを制作者の意図していない場所に埋め込む手法であって、PHPを使って実際にプログラミングをしていくうえで真っ先に考えなければいけないのがこの攻撃に対する対策

__・対策方法__
__< > を 実体参照 に置換してしまえば、それだけでJavaScriptコードの実行をだいたい防ぐことが出来ます。この処理を、HTML特殊文字を 「エスケープする」 といいます。__
一口にエスケープするといっても様々なエスケープがあり、何のためにエスケープするのかが重要です。
>実体参照とは：ある文字を別の書き方で書き表す方法です

PHPではこの処理を行うための __"htmlspecialchars" という関数__が標準で用意されています。
しかしこの関数は関数名が長い上に、パラメータも実質3つは必須となっており、そのままでは非常に使い勝手が悪いです。

そこでそれを使いやすく包み込んだ __"ラッパー関数"__ を作成します。
>ラッパー関数のラッパーはwrap【包む】から来ています。もともとある関数を包む関数、それがラッパー関数です


__・htmlspecialchars関数__
http://php.net/manual/ja/function.htmlspecialchars.php

htmlspecialchars ( $変換される文字列 ,  $flags(リファレンス参照) , 
文字を変換するときに使うエンコーディング , bool $double_encode = true )
 : string(変換後に文字列で返す)

```
function h($str) {
    return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
```

・$str で引数を1つ受け取り、それを htmlspecialchars 関数に渡しています。
この関数はデフォルトでは以下の変換を行います。
\< → \&lt;
\> → \&gt;
\& → \&amp;
" → \&quot;

・第2引数に ENT_QUOTES を指定すると、下記の変換も行うようになります。
' → \&apos;

・第3引数では文字コードを指定します。ここでの詳しい説明は割愛しますが、互換性の面から UTF-8 と省略せずに指定しておくことをオススメします。

```php
<?php
echo h('<a href="test.php?a=b&amp;c=d">Test</a>');

//実行結果
//&lt;a href=&quot;test.php?a=b&amp;amp;c=d&quot;&gt;Test&lt;/a&gt;
```

__・「だいたい」な理由__
このようにHTML特殊文字のエスケープを行っても防げないケースがあるからです。

```php
<a href="<?php echo h("javascript:alert('Test')"); ?>">Test</a>

//実行結果
//<a href="javascript:alert('Test')">Test</a>
```

完全に防ぐには、(チェックを行わないまま)属性値にユーザー入力を展開してはいけないという制約を設ける必要があります。

>ポイント
h 関数は最後の echo と同時に
<div><?php echo h($var); ?></div>

__エスケープを実行するのは最後に echo して値を表示すると同時にしてください。__
(例外もありますが)あらかじめエスケープしておいて変数に保存するのは可能な限りやめてください。なぜなら 「この変数ってエスケープ済みだっけ・・・？」 という余分なことを考える必要が発生してしまうからです。

#### cookie（クッキー）
あなたが見ているWebサイトからあなたのスマホやPCの中に保存される情報のことだ。そこにはサイトを訪れた日時や、訪問回数など、さまざまな内容が記録されている。

[クッキーについて](https://time-space.kddi.com/ict-keywords/20180726/2392#:~:text=%E3%82%B7%E3%83%A7%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0%E3%82%B5%E3%82%A4%E3%83%88%E3%81%AA%E3%81%A9%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9,%E3%82%8B%E6%83%85%E5%A0%B1%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A0%E3%80%82)

#### コールバック関数
他の関数に引数として渡される関数で、外側の関数で何らかの処理やアクションを実行します。
（関数に引数として渡される関数）

コールバック関数の活用サンプル
下記に簡単な使い方の例を記載します。

```php
function greeting(string $str,callable $method) {
//goodmorning()、goodnight()を呼び出し 
//$strのように引数も設定可能 

echo $method($str); 
}

 function goodmorning(string $str) { 
echo "Good morning " . $str . "<br>";
 }

 function goodnight(string $str) { 
echo "Good night " . $str . "<br>";
 } 

/*View ---------------------------*/
 //第2引数にコールバック関数名を文字列でそれぞれ設定 
greeting("ネコ", "goodmorning"); 
greeting("ネコ", "goodnight"); 

/*@output --------------------------- 
Good morning ネコ 
Good night ネコ */
```

#### array_map関数
__PHPの配列のすべての要素に対して同じ処理を一括で適用したい時に活用できるのがです。__
対象の配列の全要素に対して、指定した関数を適用させる際に使用します。

引数で渡したコールバック関数の中で処理を適用させ、配列として返すものです。

array_map関数のコードは以下のように記述します。

```
array_map( コールバック関数名 , $配列1 [, $配列2, $… ] )
```

__第一引数:コールバック関数名を渡します。__
__第二引数:コールバック関数を適用する配列を渡し、カンマ(,)で区切ることで複数の配列を引数で渡すことが可能です。__
array_map()関数を使用した際の返り値は、__配列__になります。
 
#### array_mapを使う方法
array_map()関数を使用する例を見ていきましょう。

```php
<?php
// 配列の要素を二乗するコールバック関数
function square($value) {
    return $value * $value;
}

$number = array(1, 2, 3, 4, 5);
// 配列にコールバック関数squareを適用する
$result = array_map('square', $number);
print_r($result);

/*実行結果
Array
(
   [0] => 1
   [1] => 4
   [2] => 9
   [3] => 16
   [4] => 25
)*/
```
上記の例では、array_map()関数に、コールバック関数名’square’と配列\$numberを渡しました。
\$numberの中の要素一つ一つに対して、コールバック関数squareを2乗する処理が適用されて、配列となって返却されていることが確認できるでしょう。


__例２：配列ごと変換できるようにする__
「h($str);」で簡単に変換できるようにはなりましたが、変換対象が多い配列などでは、毎回の変換が大変です。そこで、配列でも同じ方法で変換できるように書き換えます。

```php
function h($str){
    if(is_array($str)){
        return array_map("h",$str);
    }else{
        return htmlspecialchars($str,ENT_QUOTES,"UTF-8");
    }
}
```

## データベース
データベースとは「複数で共有、利用すること」と「検索、加工すること」を目的に整理されたデータの集まりのことです。

__基礎知識__
本来はターミナルからコマンドラインで作業を行いますが、ツールを用いる事で使いやすくなります。
今回はデータベース、テーブル、値は作成してますので、カリキュラムを進める上で作成する必要はありませんが、参考に読んでおいてください。

Mysqlコマンドはツールのクエリから実施する事が出来ます。

>SQL構文の文法をマスターしよう
https://26gram.com/mysql-grammar

>MySQLで利用することができるデータ型と利用方法
https://www.dbonline.jp/mysql/type/

>整数型(TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT)
 浮動小数点数型(FLOAT, DOUBLE)
 固定小数点数型(DECIMAL, NUMERIC)
 BIT型
 日付型と時刻型(DATE, TIME, DATETIME, TIMESTAMP, YEAR)
 CHAR型とVARCHAR型
 BINARY型とVARBINARY型
 BLOB型とTEXT型
 ENUM型
 SET型



#### データベースの作成

https://www.dbonline.jp/mysql/database/
>データベースを作成する(CREATE DATABASE文)
データベースの一覧とデータベースに関する情報を取得する
使用するデータベースを選択する(USE文)
データベースを削除する(DROP DATABASE文)
データベース属性(文字セットと照合順序)を変更する(ALTER DATABASE文)


#### テーブルの作成
https://www.dbonline.jp/mysql/table/

>テーブルを作成する(CREATE TABLE文)
テーブルの一覧とテーブルに関する情報を取得する
カラムに関する情報を取得する
テーブルを削除する(DROP TABLE文)
NOT NULL制約(カラムにNULLの格納を許可するかどうか)
DEFAULT制約(カラムにデフォルト値を設定する)
AUTO_INCREMENTを設定する(連続した数値を自動でカラムに格納する)
テーブルおよびカラム毎にコメントを追加する
PRIMARY KEY制約(主キー/プライマリキーを設定する)
UNIQUE制約(ユニーク制約を設定する)
テーブル作成時にインデックスを作成する(INDEX)
FOREIGN KEY制約(外部キー制約を設定する)
ストレージエンジンの設定 (ENGINE)
テーブルを複製して新しいテーブルを作成する(CREATE TABLE LIKE文、CREATE TABLE SELECT文)
テーブル構造を変更する(ALTER TABLE文)

#### データの取得
https://www.dbonline.jp/mysql/select/

>データを取得する(SELECT文)
カラムに別名を付ける(AS句)
データを取得する条件を設定する(WHERE句)
指定した値の範囲と比較する(BETWEEN演算子)
指定した値のリストと比較する(IN演算子)
パターンマッチングを行う(LIKE演算子)
正規表現を使ったパターンマッチングを行う(REGEXP演算子)
データをグループ化する(GROUP BY句)
グループ化したデータを取得する条件を設定する(HAVING句)
取得するデータをソートする(ORDER BY句)
取得するデータの行数の上限を設定する(LIMIT句)
重複したデータを除外してデータを取得する(DISTINCT)
サブクエリを使った検索条件の設定


#### PHPからMysqlへの接続
PHPからMysqlへ接続し、情報を取り出すには、__PDO__を使用します。

__PDOとは、PHP Data Objectsの略称で、一言で言い表すならば、PHPからデータベースのアクセスを抽象的にしてくれるものです。__

__MySQLへ接続__
>参考１MySQL版
https://www.javadrive.jp/php/pdo/index3.html

>参考２prepare版
http://html2php.starrypages.net/php/pdo

>参考３PDOでprepare版でINSERTやSELECT
https://blog.codecamp.jp/programming-php-pdo-mysql-1

>参考４query、prepare、executeはどう使い分け　[違い]
https://blog.senseshare.jp/query-prepare.html#index3

__ポイント__
・queryは固定値：静的データを表示する際に用いる。
・prepareは動的値：動的データを表示する際に用いる。
→処理速度やセキュリティ面を見ればprepareを使うのが最近ではprepareとexecuteセットが主流かなと思います。

\$dsn = 'mysql:dbname=uriage;host=localhost';
\$user = 'testuser';
\$password = 'testuser';

>※エラー
Docker使用時
.envに記載しているのがDBの環境変数になるのでDBの情報を読み込むのは.envのdbnameに。
→これはセキュリティ観点でもありますが、PHPファイル内にDBのパスワードやユーザ名をハードコーディングするのはよろしくないので、別ファイルから読ませているという事ですね。

```php
try{
    $dbh = new PDO($dsn, $user, $password);
}catch (PDOException $e){
    print('Error:'.$e->getMessage());
    die();
}
```

>※die , exit()はプログラム終了する
https://www.sejuku.net/blog/23857

#### Exceptionとは
プログラムの実行中に発生するエラーを例外といいます。PHPでは、この例外をExceptionクラスで扱います。Exceptionクラスは例外の内容を表すメッセージやコード、プログラムのどこで例外が発生したかなどの情報を持ちます。

```php
<?php
try {
    // 例外が発生する可能性のあるコード
} catch (Exception $e) {
    // 例外が発生した場合に行う処理
}
?>
```

#### getMessageで例外メッセージを取得する
例外には例外メッセージを持たせることができます。
例外メッセージはどのようなエラーが発生したかのか示すために使われます。例外メッセージを取得するには、__ExceptionクラスのgetMessageメソッド__を使用します

```php
catch (Exception $e) {
    echo  $e->getmessage;
}
```

>例外処理について
https://www.sejuku.net/blog/24907

>MySQLで見かけるエラー原因一覧
https://proengineer.internous.co.jp/content/columnfeature/7054

>コメントアウトの書き方
https://qiita.com/ques0942/items/d89de1ff7c92b4810d10

>MySQLリファレンス
https://dev.mysql.com/doc/refman/5.6/ja/create-table.html

__※参考エラー__

__テーブル作成__
・カラムコメント　※＝は使いない
・テーブルコメント　※＝をつける
>https://note.mokuzine.net/mysql-table-column-comment/

・unsigned は NOT NULL の前に記載。
・()内の最後の文に「 , 」で区切らない。
・timestamp で指定して、defaultでcurrent_timestamp 指定。
→更新時はon update でさらに指定。

・カラム名はダブル、シングルクォート「 “ “」で指定しない。
→なしかバッククォート「\` \`」で区切る
①バッククオートはテーブル名やフィールド名
②シングルクオートは値や文字列

例

```sql
CREATE DATABASE `dbname` DEFAULT CHARACTER SET utf8
```
では、何のためにバッククォートが付加されるのでしょうか。
それは、「SELECT * FROM table」のようなSQLも実行可能にするためです。
__予約語をエスケープするためです。__

予約語とは、MySQL側で特別なキーワードだと認識される語句で、TABLE、SQL、INDEX、LOCKなどがあります。このようなキーワードは、そのままテーブル名や列名などに使うことはできません。
ただし、__MySQLでは予約語をバッククォートで囲むことで、テーブル名や列名として使用可能になります。__


・ENGINE=InnoDB ストレージエンジンを指定
>https://www.dbonline.jp/mysql/myini/index4.html

・DEFAULT CHARSET=utf8mb4　文字指定

サンプルコード

```sql
CREATE TABLE large_area (
   name varchar(255) NOT NULL COMMENT "地方名",
   prefecture_name varchar(255) NOT NULL COMMENT "県名",
   prefecture_id int(11) UNSIGNED NOT NULL PRIMARY KEY,
   create_timestamp timestamp DEFAULT CURRENT_TIMESTAMP,
   update_timestamp timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   delete_timestamp timestamp DEFAULT CURRENT_TIMESTAMP　※「, 」付けない
) ENGINE=InnoDB DEFAULT AUTO_INCREMENT=1　CHARSET=utf8mb4 COMMENT="地方テーブル"
```

※AUTO_INCREMENT=1で最初から振り直すときに１からとなる。
指定しなければ、履歴が残ってるため、途中から振られる。

MySQLのAUTO_INCREMENTの値をリセットして1から連番を振りなおす方法についてです。データを追加、削除していくうちに1,2,3…と連続しているデータが,1,4,7,9…のように歯抜けになった状態を直したいときに使います。

#### 外部キー制約について
>https://qiita.com/SLEAZOIDS/items/d6fb9c2d131c3fdd1387

・参照されるのが親テーブル、参照するのが子テーブルと呼ぶ。
・制約は子テーブルに記述　
※制約記述するときに 「 , 」で区切らない！

```sql
CREATE TABLE employees (
  employee_id int primary key,
  department_id int,
  name varchar(20),
  age int,
  CONSTRAINT fk_department_id
    FOREIGN KEY (department_id) 
    REFERENCES departments (department_id)
    ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE=INNODB　AUTO_INCREMENT=1　DEFAULT CHARSET=utf8　COMMENT='user管理テーブル';
```
⏬

```sql
CONSTRAINT fk_department_id /*制約の名前（なくても可）*/
FOREIGN KEY (department_id) /*どのカラムにキーを制約つけるのか（参照元）*/
REFERENCES departments (department_id) /*どのテーブルのどのカラムを参照するか（参照先）*/
ON DELETE RESTRICT /*参照先をdeleteするときエラーにする*/
ON UPDATE RESTRICT /*参照先をupdateするときエラーにする*/
```
__外部キーを使うためにはいくつか条件がある__
・親テーブル, 子テーブルそれぞれが InnoDB であること
・参照元, 参照先のキーの型が同じであること


#### SELECTで取得するとき
__・query()で取得するとPDOStatement オブジェクト(Traversable型)で返す。__
→Traversable型はforeachで取得できる。

__・fetchやfetchAllメソッドで取得したら、配列を取得される。__
fetchAll()：結果が複数存在する際にそれらの結果を全て取得したい時に使う。
→ユーザー情報を全件取得するときなど。

__・fetch()：取得したいカラムが単１行の場合に使用します。__
→特定ユーザーの情報を取得するときなど。

>fetchの種類について
https://kinocolog.com/pdo_select/

サンプルコード

```php
<?php
$hokkaido = $dbh->query("select count(*) from city where citycode < 20000");
$count = $hokkaido->fetch(PDO::FETCH_COLUMN); //←件数ならこれで使える。
echo "北海道の市区町村数は" . $count . "個";

//as で使用した場合：配列のキーが別名になる。
$hokkaido = $dbh->query("select count(*) as count from city where citycode < 20000");
$count = $hokkaido->fetch();
echo "北海道の市区町村数は" . $count[“count”] . "個";
```

#### INSERTでデータを追加する場合
__注意点！
PDOではvaluesはシングルクォート[ ‘ ‘ ]で囲むこと。数値はいらない。__
おそらく、PDOでの識別が「’　’」で行われている可能性あり。

```php
<?php
$large_area_sql = "insert into large_area(
       name, prefecture_name, prefecture_id
       ) values (
       '$region', '$prefecture_name', '$prefecture_id'
       )";
?>
```

## クラス～例外処理～PDOの基礎
>参考
https://qiita.com/7968/items/6f089fec8dde676abb5b

__クラスとは__
ざっくり言うと変数と関数の集まりです。
__クラス ＝ 変数 ＋ 関数__

クラスを定義する構文

```
class クラス名 {
    $変数名
    function 関数名(引数) {
    }
}
```

#### 変数と関数とクラスの違い
__クラスは、変数と関数の集まりですので、データの保持と処理が可能です。__

||データの保持|データの処理|
|:---:|:---:|:---:|
|変数|○|✖️|
|関数|✖️|○|
|クラス|○|○|

#### クラス内における変数と関数の名称
先ほど記述したクラスの構文で、クラス内にあっても変数と関数と書きましたが、実は名称が変わります。
__・クラス内に記述した変数:プロパティ__
__・クラス内に記述した関数:メソッド__

　
クラス内に記述したときの名称
__変数→プロパティ
関数→メソッド__

先ほど記述したクラスの構文を正しい名称にすると下記のようになります。

```php
class クラス名 {
    $プロパティ名 //変数名
    function メソッド名(引数) { //関数名
    }
}
```

#### アクセス修飾子とは
__アクセス修飾子とは、どこからアクセスできるのかを指定するものです。__
例えば、クラスの中にあるプロパティは、クラスの外からも使用できるのかといったアクセス権限に関する指定のことです。

クラスを定義する構文

```php
class クラス名 {
    アクセス修飾子 $プロパティ名;

    アクセス修飾子 function メソッド名（引数）
    {
        //処理を記述
    }
}
```
アクセス修飾子は、下記の3種類があります。

|種類|説明|
|:---:|:---|
|public|どこからでもアクセス可能|
|private|クラス内のみからアクセス可能|
|protected|クラス内とそのクラスを継承した子クラスからアクセス可能|

__ちなみにアクセス修飾子を指定しないと、publicの扱いになります。__
publicにする必要がない場合には、privateやprotectedを適切に指定してください。

#### アロー演算子とは
インスタンスのプロパティやメソッドにアクセスするには、
__アロー演算子と呼ばれれる 「　->　」 を使います。__

__\$インスタンスを代入した変数名->呼び出したいインスタンスのプロパティまたはメソッド名__

先ほどのコードを使い、インスタンスのdriveメソッドへアクセスしてみます。
// Carクラスを作成

```php
class Car {

    public function drive() {
        echo '走ります';
    }
}

// インスタンスを作成（インスタンス化）
$prius = new Car();

// アロー演算子でインスタンスメソッドへアクセス
$prius->drive();
```

アロー演算子を使い、$priusに代入したインスタンスにある、
driveメソッドを呼び出しています。

これを実行すると走りますと表示されるようになります。

__このアロー演算子は、インスタンスのプロパティとメソッドを呼び出すのに使います。
そうなると、インスタンス化しないとプロパティとメソッドにアクセスできなくなりますね。
単純にクラスのプロパティやメソッドにアクセスするには、スコープ定義演算子を使います。__

#### スコープ定義演算子とは
クラスのプロパティやメソッドにアクセスするには、スコープ定義演算子と呼ばれる
__「　 ::　」__ を使います。

例
__クラス名::呼び出したいクラスのプロパティまたはメソッド名__

・どれがクラスのプロパティで、どれがインスタンスのプロパティなのか区別
普通にクラス内に記述したプロパティやメソッドはインスタンスのプロパティやメソッドです。
では、クラスのプロパティとメソッドにするためにはどうすればよいのか。
__クラスのプロパティまたはメソッドにするには、staticという修飾子を付与する必要があります。__

プロパティであれば、プロパティ名の前にstaticを記述します。
メソッドであれば、functionの前にstaticを記述します。

__staticのあり・なしでクラスなのか、インスタンスなのか区別できます。__

```
class クラス名 {
    // No.1
    アクセス修飾子 static $プロパティ名;
※クラスのプロパティ

    // No.2
    アクセス修飾子 $プロパティ名;
※インスタンスのプロパティ

    // No.3
    アクセス修飾子 static function メソッド名(引数) {
        //処理を記述
    }

    // No.4
    アクセス修飾子 function メソッド名(引数) {
        //処理を記述
    }
}
```

・No.1とNo.3は、クラスのプロパティとメソッドになるため、インスタンス化しなくてもアクセスできます。
・No.2とNo.4はインスタンスのプロパティとメソッドになるため、インスタンス化しないとアクセスできないということになります。

#### staticとpublicの違いは？
PHPマニュアルの説明をみて__「publicを宣言すれば、インスタンス化しなくてもアクセスできるのにstaticを宣言する意味がないのでは？」__と疑問に思った方もいるかと思います。
もしかしたら、私だけですかね(･ω･`；)

まず、「publicを宣言すれば、インスタンス化しなくてもアクセスできる」というのは誤りです。
__publicだけ宣言しても、インスタンス化しなければアクセスできません。__
__staticを宣言することで、クラスに属したプロパティまたはメソッドになります。__

__staticを指定することで、クラスに属し、publicを指定することで、クラスの外からアクセスできるようになります。__

__publicはあくまでもアクセス修飾子であり、どこからアクセスできるかを指定するものです。__

__staticはクラスに属するかを指定するものであり、publicとは別物です。__
staticがあるプロパティを静的プロパティと呼び、staticがあるメソッドを静的メソッドと呼びます。

||プロパティ|メソッド|
|:---|:---|:--|
|staticあり|静的プロパティ※1|静的メソッド※2|
|staticなし|インスタンスプロパティ|インスタンスメソッド|

__・アロー演算子とスコープ定義演算子の使い分け__

|種類|アクセス方法|
|:---|:---|
|静的プロパティ、静的メソッド|::|
|インスタンスプロパティ、インスタンスメソッド|->|


・クラスに属している場合：スコープ定義演算子
・インスタンスに属している場合：アロー演算子