[LIFF] PHPとAjaxとMySQLを使った会員証アプリをつくる

社内でLIFFを使ったミニアプリを開発することに（なりそう）なので、ひとまず会員バーコードの表示機能を試作しました。以下備忘録。

# 全体図
![全体図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1552742/16438d7b-79dc-be21-0ba9-b7387835db2c.jpeg)
こんな感じでLINEのuserIdと紐づけた会員データベースの会員NoをAjax経由で取ってきて
その会員Noを１次元バーコードに生成する。


# LIFFにてuserIdを取得する

- LINE Developersページへログインして、Messaging APIでログイン用チャネルを作成してLIFFのIDを発行（中略）

- 表示するページをエンドポイントに設定

- 表示するページにてLIFFのIDを指定すればgetProfile()にてuserIdが取得できる


```html:index.html
    <script charset="utf-8" src="https://static.line-scdn.net/liff/edge/2/sdk.js"></script>
    <script>        
        const liffId = '****'
        liff.init({
            liffId: liffId,
            withLoginOnExternalBrowser: true,
        }).then(() => {
            getProfile()
        }).catch((err) => {
            alert(err)
        })

        function getProfile(){
            liff.getProfile()
            .then((profile) => {
                post_Ajax({"userId": profile.userId},"ajax_get.php");
            })
            .catch((err) => {
                alert(err)
            });
        }
    </script>      
```



# Ajaxの準備

上記で取得できたuserIdをJSON形式でセットし、phpへ送る

```html:index.html
    <script> 
        /* 中略 */
        post_Ajax({"userId": profile.userId},"ajax_get.php");
        /* 中略 */

        function post_Ajax(data,url){
            var json = JSON.stringify(data);
            var xhr = new XMLHttpRequest();
            xhr.open("POST", url);
            xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded;charset=UTF-8");
            xhr.send(json);
            xhr.onreadystatechange = function() {
                try {
                    if ((xhr.readyState == 4)&&(xhr.status == 200)) {
                        /* 通信が成功すればここに返り値が入ってくる */
                    }
                } catch (e) {
                    alert("内部エラーが発生し実行できませんでした。\n\n" + e.message)
                }
            };
        }
    </script>  
```

データが送られてきたphpではmySQLと接続しuserIdを混ぜ込んで情報を取得＆返す

```php:ajax_get.php
<?php
    header('Content-Type: text/html; charset=UTF-8');

    $cn252 = new mysqli("db_adress", "db_id", "db_password", "db_nm");
    if ($cn252->connect_error) {
        echo $cn252->connect_error;
        exit();
    }
    $cn252->set_charset("utf8");

    $request = json_decode(file_get_contents("php://input"), true);
    $userId = $request['userId'];
    $cnt = 0;

    $sql = "-------";
    $rs = $cn252->query($sql);

    while ($item = $rs->fetch_array()) {
      $bc = $item['card_no'];
      ++$cnt;
    }
    
    $result = array(
      "bc" => $bc,      
      "cnt" => $cnt
    );

    header("Content-Type: application/json; charset=UTF-8");
    echo json_encode($result);
?>
```

# 返ってきた値をバーコード表示させる

バーコードを表示させるために以下のプラグインをダウンロード
https://barcode-coder.com/en/barcode-jquery-plugin-201.html

下記では`id=barcode`のdivにバーコードを表示させる

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <script type="text/javascript" src="./jquery-barcode.js"></script>
</head>
<body>       
    <div id="barcode"></div> 
    /* 中略 */
    <script> 
        function post_Ajax(data,url){
            var json = JSON.stringify(data);
            var xhr = new XMLHttpRequest();
            xhr.open("POST", url);
            xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded;charset=UTF-8");
            xhr.send(json);
            xhr.onreadystatechange = function() {
                try {
                    if ((xhr.readyState == 4)&&(xhr.status == 200)) {
                        var result = JSON.parse(xhr.response);
                        $("#barcode").barcode(result.bc, "code128",{barWidth:3, barHeight:100});
                    }
                } catch (e) {
                    alert("内部エラーが発生し実行できませんでした。\n\n" + e.message)
                }
            };
        }
    </script>  
```

# 適当に画面を作ってみる

あくまで試作なので適当に。（デザインの勉強せねば。）

![IMG_0208.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1552742/4295b745-83ef-83e3-60c7-8e0dbf2b44ec.png)


# まとめ
非常に簡単な関数でLINEのユーザー情報が取って来ることが可能。
scanCodeV2()など他の関数を使って様々な応用が出来るかと思います。