APIとDB接続処理の作成をする。PHPでSNSを作成してみる#13

今回は、APIとDBの接続処理を記します。

前回の章では、会員登録のコントローラ、サービスの紐付けとモデルにデータを入れるところまで行いました。

処理の流れ

apiとsqlの処理作成
今回は、上の画像の色のついた部分の処理を作成します。

必要なファイル

今回作成するファイルのみ記しています。
※下記のみだと正常に実行されないのでシリーズの過去記事をご覧ください

sns_training
      ├── api
      │       ├── api.php
      │       └── connection.php
      └── app    
               └── config
                          └── .env

apiに記述するsqlについては、過去の章で作成した会員登録のIDを使用します。

api.php

<?php
namespace Api\Connection;
use Api\Connection\Connection;
class api{
  public function A00001($param = null){
    $sql = null;
    $sql .= <<< 
EOM 
SELECT 
  COUNT(*) AS COUNT 
FROM 
  USERS USR 
WHERE 
  USR.USER_ID = :USER_ID;
EOM;
  $connection = new Connection();
  return $connection->con($sql, $param);
  }
}
?>

api.phpは、sql文をまとめて記述できるファイルです。
以前、サービスで作成した「REQUEST_API_NAME」のメソッドを記述していきます。
今回は、A00001という番号のAPIを作成します。

public function A00001($param = null){...}

このApi.phpでは、前述した通りSQL文をズラーっと記述していきます。
メソッド名は番号にしています。$paramは、サービスクラスでInputModelに入れたモデルです。

$sql .= <<< EOM
...
EOM;

sqlを一行で書く場合、ヒアドキュメントを用いた記述は必要ありません。
しかし、複雑な処理である場合、横に長くなってしまいます。
そのため、EOMで囲み複数行を文字列として$sqlに代入しています。

SELECT 
  COUNT(*) AS COUNT
FROM
  USERS USR 
WHERE
 USR.USER_ID = :USER_ID;

今回はリクエスト値のUSER_IDと一致するレコード数を返すAPIです。
※後の章で改修を行います。

DBにはUSERSというテーブル、
カラムには、USER_IDが存在する程で記述しています。

また、リクエスト値にプリペアドステートメントを利用することでSQLインジェクションを防ぐことが可能のため採用しています。

$connection = new Connection();
return $connection->con($sql, $param);

後述しますconnectionクラスをインスタンス化します。
このインスタンスのconメソッド対してsqlとリクエスト値を投げます。
戻り値としてsqlの結果が返却されるため、APIメソッドの戻り値としています。

この戻り値がserviceの子クラスoutputメソッドの引数に格納されるわけです。

connection.php

connection.phpは、かなり参考にならないかと思います。。。
なるべくDBの処理を共通化したいあまりにパターンを網羅している途中の段階です。
ただ、このシリーズについての内部処理は重要ではないのでコピペで可です。

<?php
namespace Api\Connection;
use App\Config\config;
use \PDO;
use \PDOException;

class Connection{
    private static $dbh;
    public static function pdo(){
        $dsn = 'mysql:dbname='.Config::getEnv('DB_NAME').';host='.Config::getEnv('DB_HOST');
        $user = Config::getEnv('DB_USER');
        $password = Config::getEnv('DB_PASSWORD');
        self::$dbh = new PDO($dsn, $user, $password);
    }
    public function con($sql,$param = null){
        self::pdo();
        try {
            $sth = self::$dbh->prepare("$sql");
            if($param != null){
                  foreach($param as $key => $val){   
                    if((preg_match("/_WILDCARD$/",$key) == 1) && $val != null){
                        $k = explode("_",$key)[0];
                        $sth->bindValue(':'.$k,$val, PDO::PARAM_STR);
                    }else if(($key == 'ROW_NUM' || $key == 'FROM_NUM' ) && $val != null){
                        $sth->bindValue( ':'.$key, (int)$val, PDO::PARAM_INT );
                    } else if($val != null){
                        $sth->bindValue(':'.$key,$val);
                    }else{
                        $sth->bindValue(':'.$key, null, PDO::PARAM_NULL);
                    }
                }
            }
            $flag = $sth->execute();
            
            if(trim(mb_strstr( $sql, ' ', true),"\n") != 'SELECT'){
                $result = $flag;
            }else{
                $result = $sth->fetchAll(PDO::FETCH_ASSOC);
            }
            return $result;
        } catch(PDOException $e){
            exit;
        }
    }
}
?>

 

$dsn = 'mysql:dbname='.Config::getEnv('DB_NAME').';host='.Config::getEnv('DB_HOST'); 
$user = Config::getEnv('DB_USER');
$password = Config::getEnv('DB_PASSWORD'); 
self::$dbh = new PDO($dsn, $user, $password);

ここでは、DBの接続情報を.envファイルより取得しています。
それらを引数としてPDO(DB接続クラス)をインスタンス化します。

 if((preg_match("/_WILDCARD$/",$key) == 1) && $val != null){...}

オレオレすぎて申し訳ないですが、
SQL文のLIKE(あいまい検索)するために必要な記述です。
このLIKE句で使用する検索文字列は「???_WILDCARD」というプロパティに格納してあげます。

if(($key == 'ROW_NUM' || $key == 'FROM_NUM' ) && $val != null){...}

LIKE句検索と同様、ROW_NUM及びFROM_NUMのプロパティに値を格納した場合、値の扱いが変わります。
これらは、LIMIT句、OFFSET句で使用します。

例えば、検索結果を複数ページで表示させる時に使用します。

if(trim(mb_strstr( $sql, ' ', true),"\n") != 'SELECT'){...}

ここでは、SQLがSELECT文か、それ以外かを判定しています。
DMLの基本文法のみサポートしています。
SELECTの場合はレコードを返します。DBに対して変更を加えると実行結果を返します。
戻り値が異なるため分岐をしています。

.env

SUB_DIRECTORY=/sns_training
DB_NAME=sns_training
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=root

ここでは、接続情報を追記しました。
今回はホストの[localhost]に[sns_training]というdbを作成して、ユーザ[root]でリクエストをしています。

おわりに

今回はAPIとDB接続処理の作成をいたしました。
次回は、会員登録クラスを使用して実際にAPIで問い合わせをしたいと思います。

転職ならリクナビNEXT

リクナビNEXTとはリクルートが運営する転職サイトです。
効率的に転職活動が行える管理やメール、レジュメ機能の他、
ミスマッチを減らすための診断サービス。
また、選択肢が広がるスカウト登録が可能です。

いずれ転職活動をしたい。本職が合っているか今一度考えたい。という方はぜひ登録してみてください。診断サービスのグッドポイント診断は、登録後ご利用いただけますのでぜひやってみてくださいね。

グッドポイント診断をする

 

以上、ありがとうございました。

コメント

スポンサーリンク
スポンサーリンク
タイトルとURLをコピーしました