【Php】フォームからDBへデータ保存(1)

# 初めに
phpでフォームの入力内容をDBに保存する方法について学習した内容のoutput用記事です。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。
※こちらの記事はあくまでも個人で学習した内容のoutputとしての記事になります。

前回の記事:
https://qiita.com/redrabbit1104/items/a6e57aa1fd1771ef90ff
https://qiita.com/redrabbit1104/items/a3eaf2bba51fac0b3c51
https://qiita.com/redrabbit1104/items/6e9c85c7503ed9043f38
https://qiita.com/redrabbit1104/items/c9b7bb7a89922521c003

# データを保存するテーブルを準備する
テーブル名はcontactsでidからcreated_atまでの８項目が用意されています。
![スクリーンショット 2021-06-20 16.53.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/ba403612-81e5-f32b-f936-5686e104a219.png)
また、データベースに接続する権限を持つ、特権ユーザーを登録します。ユーザーネームは'user'、パスワードは任意のパスワードを入れます。

# データベース接続に必要な基本情報
データベースの接続に必要な基本情報（ホスト、ユーザー名、パスワード）を変数に格納します。

```php
const DB_HOST = 'mysql:dbname=hogehoge;host=localhost:3000;charset=utf8';
const DB_USER = 'user';
const DB_PASSWORD = 'abcdefg';
```

基本情報をもとにデータベースに接続します。接続できなかった場合にはエラーメッセージを画面に表示させます。

```php
// データベースに接続
try{
    $pdo = new PDO(DB_HOST, DB_USER, DB_PASSWORD, [ 
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, 
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,
    ]);
}catch(PDOException $e){
    echo $e -> getMessage() . "\n";
    exit();
}
```

# データを用意する
フォームからの入力データーを保存する前にテストとして任意のデータを用意します。変数の名前は$paramsとし、キーとバリューで構成される連想配列を用意します。

```php
$params = [
    'id' => null,
    'your_name' => '田中',
    'email' => 'test@test.com',
    'url' => 'http://www.abc.com',
    'gender' => '1',
    'age' => '2',
    'contact' => 'いい',
    'created_at' => null
];
``` 
この\$paramsの値をキーのみとバリューのみが入るようにそれぞれ\$columnsと\$valuesという変数に格納します。そうするためにforeach()メソッドを使います。array_keys()メソッドを使い、連想配列の中からキーの値だけを取り出し\$columnsに格納します。また、バリューはキーに:を付ければ取得できますので、\$valuesに':'.$keyに繋げます。

```php
foreach(array_keys($params) as $key){
    if($count++>0){
        $columns .= ',';
        $values .= ',';
    }
    $columns .= $key;
    $values .= ':'.$key;
}
```
\$columnsと\$valuesの値をvar_dumpを使って確認してみると次のようになります。

```php
var_dump($columns);
//string(52) "id,your_name,email,url,gender,age,contact,created_at" 
var_dump($values);
//string(60) ":id,:your_name,:email,:url,:gender,:age,:contact,:created_at"
```
$columnsはキー名とキー名が「,」区切りになっていて、\$valuesは「:」キー名で,「,」区切りに繋がっていることがわかります。
トランザクションをスタートします。これで予期せぬことによるDBの誤作動リスクを防げます。

```php
$pdo->beginTransaction();
```

そしてsql文をtry文の中に記述します。データの保存なので、insert文を使います。また、キーの値は

```php
    $sql = 'insert into contacts ('. $columns .')values('. $values .')';
```
var_dumpで$sqlを確認してみると次のようになります。これでキーの値とそれに対するバリューの値がsql文として保存されます。

```php
 var_dump($sql);  
    //string(143) "insert into contacts (id,your_name,email,url,gender,age,contact,created_at)values(:id,:your_name,:email,:url,:gender,:age,:contact,:created_at)"
```

他は普通のトランザクションの処理を書いていきます。

```php
try {
    //sql処理

    $sql = 'insert into contacts ('. $columns .')values('. $values .')';
    var_dump($sql);  
    //string(143) "insert into contacts (id,your_name,email,url,gender,age,contact,created_at)values(:id,:your_name,:email,:url,:gender,:age,:contact,:created_at)"
    $stmt = $pdo->prepare($sql);     //sql文を実行する準備を行う。戻り値はPDOStatement
    $stmt->execute($params); //実行

    $pdo->commit();
    $result = $stmt->fetchall();
    var_dump($result);
} catch (PDOException $e) {
    $pdo->rollback();    //処理のキャンセル
    echo $e;
}
```
ページを読み込むと以下のようにテーブルにデータが保存されていることが分かります。
![スクリーンショット 2021-06-20 17.27.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/b4efeeb9-eb0f-fb63-8a24-8bd661c2f1d5.png)

# 参考サイト
https://www.php.net/manual/ja/function.array-keys.php