'2017/11/16'에 해당되는 글 2건

728x90

<?php
// 절차지향 방식
$sql = "SELECT * FROM table WHERE field1 = $field1 AND field2 = '$field2' ORDER BY id";
$stmt = mysqli_query($db,$sql);

// PDO (정석대로)
$sql = "SELECT * FROM table WHERE field1 = ? AND field2 = ? ORDER BY id";
$stmt = $db->prepare($sql);
$stmt->bindParam(1, $field1, PDO::PARAM_INT);
$stmt->bindParam(2, $field2, PDO::PARAM_STR);
$stmt->execute();

// PDO (그나마 좀 간소화시킨 문법)
$sql = "SELECT * FROM table WHERE field1 = ? AND field2 = ? ORDER BY id";
$stmt = $db->prepare($sql);
$stmt->execute(array($field1, $field2));
?>

 

PDO(PHP Data Object) 방식 함수를 사용하여 만든 MemberClass 예제다.

<?php
class MemberClass {
    // 회원 정보 신규 입력
    public function storeUser($userID$userNM$email$password$telNO$mobileNO) {
        global $db;
 
        $hash = $this->hashSSHA($password);
        $encrypted_password = $hash['encrypted']; // encrypted password
        $salt = $hash['salt']; // salt
 
        try{
            $db->beginTransaction();
            $sql = "INSERT INTO members(userID, userNM, email, passwd, salt, telNO,mobileNO,created_at) VALUES(:userID,:userNM,:email,:passwd,:salt,:telNO,:mobileNO,:created_at)";
            $stmt = $db->prepare($sql);
            $stmt->bindValue(':userID',$userID,PDO::PARAM_STR);
            $stmt->bindValue(':userNM',$userNM,PDO::PARAM_STR);
            $stmt->bindValue(':email',$email,PDO::PARAM_STR);
            $stmt->bindValue(':passwd',$encrypted_password,PDO::PARAM_STR);
            $stmt->bindValue(':salt',$salt,PDO::PARAM_STR);
            $stmt->bindValue(':telNO',$telNO,PDO::PARAM_STR);
            $stmt->bindValue(':mobileNO',$mobileNO,PDO::PARAM_STR);
            $stmt->bindValue(':created_at',date("YmdHis"));
            $result = $stmt->execute();
            $db->commit();
        } catch (PDOException $pex) {
            $db->rollBack();
            echo "에러 : ".$pex->getMessage();
        }
        // check for successful store
        if ($result) {
            $stmt = $db->prepare("SELECT * FROM members WHERE userID = :userID");
            $stmt->bindValue(':userID'$userID, PDO::PARAM_STR);
            $stmt->execute();
            $user = $stmt->fetch(PDO::FETCH_ASSOC);
 
            return $user;
        } else {
            return false;
        }
    }
 
    // 로그인 체크
    public function getUser($userID$password) {
        global $db;
        $sql = "SELECT * FROM members WHERE userID=:userID";
        $stmt = $db->prepare($sql);
        $stmt->bindValue(':userID'$userID);
        $stmt->execute();
 
        if ($user=$stmt->fetch()) {
            // verifying user password
            $salt = $user['salt'];
            $encrypted_password = $user['passwd'];
            $hash = $this->checkhashSSHA($salt$password);
            if ($encrypted_password == $hash) {
                // user authentication details are correct
                return $user;
            }
        } else {
            return NULL;
        }
    }
 
    // 안드로이드/아이폰 로그인 체크
    public function LoginUserChk($userID,$password,$deviceID){
        global $db;
        if(empty($userID|| empty($password)){
            return 0;
        } else {
            $user = $this->getUser($userID$password);
            if($user['idx']>0){
                // 장치 일련번호 체크
                if($user['phoneSE'== NULL){
                    // 신규 장치번호 입력(최초 로그인)
                    $this->LoginUserEquipInput($userID,$deviceID);
                    return $user['idx'];
                } else {
                    if($user['phoneSE'=== $deviceID){
                        return 1// 일련번호 일치
                    } else {
                        return -1//일련번호 불일치
                    }
                }
            } else {
                return 0//계정오류
            }
        }
 
    }
 
    // 장치번호 업데이트
    public function LoginUserEquipInput($userID,$deviceID){
        global $db;
        if(strlen($deviceID)>0 && is_numeric($deviceID)){ // 안드로이드폰
            $ostype = 2;
        } else if(strlen($deviceID)>30){ // 아이폰
            $ostype = 1;
        } else { // 기타
            $ostype = 0;
        }
 
        try{
            $db->beginTransaction();
            $sql='update members set phoneSE=:phoneSE, OStype=:OStype where userID=:userID';
            $stmt = $db->prepare($sql);
            $stmt->bindValue(':phoneSE',$deviceID,PDO::PARAM_STR);
            $stmt->bindValue(':OStype',$ostype,PDO::PARAM_INT);
            $stmt->bindValue(':userID',$userID,PDO::PARAM_STR);
            $status = $stmt->execute();
            $db->commit();
            if($status == true){
                return 1;
            } else {
                return 0;
            }
        }catch (PDOException $pex) {
            $db->rollBack();
            echo "에러 : ".$pex->getMessage();
        }
    }//end
 
    // 장치번호 초기화
    public function EquipReset($userID){
        global $db;
        try{
            $db->beginTransaction();
            $ostype = 0;
            $sql='update members set phoneSE=NULL,OStype=:OStype where userID=:userID';
            $stmt = $db->prepare($sql);
            $stmt->bindValue(':OStype',$ostype,PDO::PARAM_INT);
            $stmt->bindValue(':userID',$userID,PDO::PARAM_STR);
            $status = $stmt->execute();
            $db->commit();
            if($status == true){
                return 1;
            } else {
                return 0;
            }
        } catch (PDOException $pex) {
            $db->rollBack();
            echo "에러 : ".$pex->getMessage();
        }
    }//end
 
    // 회원 가입 여부 체크
    public function isUserExisted($userID) {
        global $db;
        $stmt = $db->prepare("SELECT userID from members WHERE userID=:userID");
        $stmt->bindValue(':userID',$userID,PDO::PARAM_STR);
        $stmt->execute();
        if ($stmt->rowCount() > 0) {
            return true;
        } else {
            return false;
        }
    }
 
    // 회원 정보 삭제
    public function deleteUser($userID){
        global $db;
        try{
            $db->beginTransaction();
            $stmt = $db->prepare("delete FROM members WHERE userID=:userID");
            $stmt->bindValue(':userID',$userID,PDO::PARAM_STR);
            $stmt->execute();
            $db->commit();
        }catch (PDOException $pex) {
            $db->rollBack();
            echo "에러 : ".$pex->getMessage();
        }
    }
 
    public function hashSSHA($password) {
        $salt = sha1(rand());
        $salt = substr($salt010);
        $encrypted = base64_encode(sha1($password . $salttrue) . $salt);
        $hash = array("salt" => $salt"encrypted" => $encrypted);
        return $hash;
    }
 
    public function checkhashSSHA($salt$password) {
        $hash = base64_encode(sha1($password . $salttrue) . $salt);
        return $hash;
    }
}
?>

 

 

안드로이드와 연동하는 login.php, register.php 파일 예제는 첨부파일을 참조하면 된다.

pdo.zip
다운로드

 

조만간에 부트스트랩 registerForm.php 와 loginForm.php 파일을 간단하게 만들고, 관련 처리 기능을 만들 예정이다.

 

 

PHP 7.0 에서 mysql 기존방식은 지원을 아예 안하고 mysqli  및 pdo를 지원하므로 PDO 방식으로 코딩하는 방법을 계속 연습해두고 기능을 하나 하나 익혀두는게 나을거 같아서 정리를 해보는 중이다.

 

수정사항(2017.11.30)

회원정보 삭제 테스트를 하다보니 원하는 결과가 나오지 않아서 로직을 수정 보완했다.

// 회원 가입 여부 체크
public function isUserExisted($userID) {
    $stmt = $this -> db -> prepare("SELECT count(userID) from members WHERE userID=:userID");
    $stmt -> bindValue(':userID', $userID, PDO::PARAM_STR);
    $stmt -> execute();
    if ($row = $stmt -> fetch()) {
        return $row[0];
        // 미가입이면 0 반환, 가입이면 1 반환
    } else {
        return -1;
    }
}

// 회원 정보 삭제 : Move
public function deleteUser($userID) {
    if ($this -> isUserExisted($userID) > 0) {
        try {
            $this -> db -> beginTransaction();
            $stmt = $this -> db -> prepare("delete FROM members WHERE userID=:userID");
            $stmt -> bindValue(':userID', $userID, PDO::PARAM_STR);
            $stmt -> execute(); // 삭제할 데이터의 존재 유무에 상관없이 실행한다.
            $this -> db -> commit();
        } catch (PDOException $pex) {
            $this -> db -> rollBack();
            echo "에러 : " . $pex -> getMessage();
        }
        return 1; // 삭제 성공
    } else {
        return 0; // 삭제할 데이터가 없음
    }
}

 

블로그 이미지

Link2Me

,
728x90

PDO(PHP Data Object) 방식으로 DB을 연결하는 방법이다.

- PDO는 여러가지 DBMS를 제어하는 방법을 표준화시켜 다양한 DB(Oracle, PostgrSQL, MySQL 등)를 동일한 방법으로 제어할 수 있다.

- PHP 7.0 에서는 MySQL API 지원 중단, MySQLi 절차식 API 및 객체 API 제공, PDO 객체 API 제공


사용법

require_once 'DBController.php';
require_once 'loginClass.php';
$c=new LoginClass;

LoginClass 만 객체 생성해주면 부모클래스인 DBController 클래스는 자동으로 인식된다.


<?php
//****************
// DB 정보 입력
// define('상수명', '값', true);
//****************
define('_DBHOST','localhost');
define('_DBUSER','address_root'); // DB 사용자
define('_DBPASS', 'autoset'); // DB 패스워드
define('_DBNAME','address'); // DB 명
define('_DBTYPE','mysql'); // 데이터베이스 종류
define('_DSN',_DBTYPE.':host='._DBHOST.';dbname='._DBNAME.';charset=utf8');
?>

 <?php
class DBController {
    protected $db;

    public function __construct() {
        $this->db = $this -> dbConnect();
        // construct 메소드는 객체가 생성(인스턴스화)될 때 자동으로 실행되는 특수한 메소드다.
    }

    private function dbConnect() {
        require_once 'config.php';
        try { // MySQL PDO 객체 생성
            $conn = new PDO(_DSN, _DBUSER, _DBPASS);
            $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
        } catch(PDOException $ex) {
            die("오류 : " . $ex -> getMessage());
        }
        return $conn;
    }
?>

 <?php
class LoginClass extends DBController {
    // 회원 정보 신규 입력
    public function storeUser($userID, $userNM, $password, $mobileNO) {
        $hash = $this -> hashSSHA($password);
        $encrypted_password = $hash['encrypted']; // encrypted password
        $salt = $hash['salt']; // salt
        $regdate = date("YmdHis");

        $key = "userID, userNM, passwd, salt, regdate";
        $val = "$userID,$userNM,$encrypted_password,$salt,$regdate";
        $result = $this -> getDbInsert('members', $key, $val); //
DBController에서 별도 생성 함수
        // check for successful store
        if ($result) {
            $user = $this -> getUser($userID, $password);
            $rs = $this -> storeUserDetail($user['idx'], $userNM, $userID, $mobileNO);
            if ($rs == 1) {
                return $user;
            } else {
                return -1;
            }
        } else {
            return -1; // 0
        }
    }

    // 회원 세부 정보 입력
    public function storeUserDetail($relatedidx, $userNM, $email, $mobileNO) {
        $regdate = date("YmdHis");
        $key = 'relatedidx,name,email,mobileNO,modifydate'; // 칼럼 정확한지 체크
        $val = "$relatedidx,$userNM,$email,$mobileNO,$regdate";
        $this -> getDbInsert('member_data', $key, $val);
    }

    // 회원정보 반환
    public function getUser($userID, $password) {
        $sql = "SELECT * FROM members WHERE userID=:userID";
        $stmt = $this -> db -> prepare($sql);
        $stmt -> bindValue(':userID', $userID);
        $stmt -> execute();

        if ($user = $stmt -> fetch()) {
            // verifying user password
            $salt = $user['salt'];
            $encrypted_password = $user['passwd'];
            $hash = $this -> checkhashSSHA($salt, $password);
            if ($encrypted_password == $hash) {
                // user authentication details are correct
                return $user;
            }
        } else {
            return NULL;
        }
    }

    // 회원 가입 여부 체크
    public function isUserExisted($userID) {
        $stmt = $this -> db -> prepare("SELECT count(userID) from members WHERE userID=:userID");
        $stmt -> bindValue(':userID', $userID, PDO::PARAM_STR);
        $stmt -> execute();
        if ($row = $stmt -> fetch()) {
            return $row[0];
            // 미가입이면 0 반환, 가입이면 1 반환
        } else {
            return -1;
        }
    }

    // 회원정보 수정
    public function updateUser($idx, $userNM, $mobileNO) {
        if(isset($idx) && !empty($idx)){
            $this->getDbUpdate('members', "userNM=?", array($userNM), "idx=".$idx);
            $set = "name=?,mobileNO=?";
            $params = array($userNM,$mobileNO);
            $this->getDbUpdate('member_data', $set, $params, 'relatedidx='.$idx);
            return 1;
        } else {
            return 0;
        }
    }

    // 회원 정보 삭제 : Move
    public function deleteUser($userID) {
        if ($this -> isUserExisted($userID) > 0) {
            try {
                $this -> db -> beginTransaction();
                $stmt = $this -> db -> prepare("delete FROM members WHERE userID=:userID");
                $stmt -> bindValue(':userID', $userID, PDO::PARAM_STR);
                $stmt -> execute(); // 삭제할 데이터의 존재 유무에 상관없이 실행한다.
                $this -> db -> commit();
            } catch (PDOException $pex) {
                $this -> db -> rollBack();
                echo "에러 : " . $pex -> getMessage();
            }
            return 1; // 삭제 성공
        } else {
            return 0; // 삭제할 데이터가 없음
        }
    }

    // 안드로이드/아이폰 로그인 체크
    public function LoginUserChk($userID, $password, $deviceID) {
        if (empty($userID) || empty($password)) {
            return 0;
        } else {
            $user = $this -> getUser($userID, $password);
            if ($user['idx'] > 0) {
                // 장치 일련번호 체크
                if ($user['phoneSE'] == NULL) {
                    // 신규 장비번호 입력(최초 로그인)
                    $this -> LoginUserEquipInput($userID, $deviceID);
                    return $user['idx'];
                } else {
                    if ($user['phoneSE'] === $deviceID) {
                        return 1;
                        // 일련번호 일치
                    } else {
                        return -1;
                        //일련번호 불일치
                    }
                }
            } else {
                return 0;
                //계정오류
            }
        }

    }

    // 장치번호 업데이트
    public function LoginUserEquipInput($userID, $deviceID) {
        if (strlen($deviceID) > 0 && is_numeric($deviceID)) {// 안드로이드폰
            $ostype = 2;
        } else if (strlen($deviceID) > 30) {// 아이폰
            $ostype = 1;
        } else {// 기타
            $ostype = 0;
        }

        try {
            $this -> db -> beginTransaction();
            $sql = 'update members set phoneSE=:phoneSE, OStype=:OStype where userID=:userID';
            $stmt = $this -> db -> prepare($sql);
            $stmt -> bindValue(':phoneSE', $deviceID, PDO::PARAM_STR);
            $stmt -> bindValue(':OStype', $ostype, PDO::PARAM_INT);
            $stmt -> bindValue(':userID', $userID, PDO::PARAM_STR);
            $status = $stmt -> execute();
            if ($status == true) {
                $this -> db -> commit();
                return 1;
            } else {
                return 0;
            }
        } catch (PDOException $pex) {
            $this -> db -> rollBack();
            echo "에러 : " . $pex -> getMessage();
        }
    }//end

}
?>


추가 (2018.04.09)

검색하다보니 https://gist.github.com/kijin/5947026 에 ezPDO 라는 Class 파일을 만든 고수분이 있네.


블로그 이미지

Link2Me

,