복붙노트

PDO를 사용하여 헬퍼 함수 삽입 / 업데이트

PHP

PDO를 사용하여 헬퍼 함수 삽입 / 업데이트

나는 전통적인 일반 mysql 드라이버 사용법을위한 SET 문을 생성하는 매우 간단한 도우미 함수를 가지고있다 :

function dbSet($fields) {
  $set='';
  foreach ($fields as $field) {
    if (isset($_POST[$field])) {
      $set.="`$field`='".mysql_real_escape_string($_POST[$field])."', ";
    }
  }
  return substr($set, 0, -2); 
}

이런 식으로 사용했습니다.

$id = intval($_POST['id']);
$fields = explode(" ","name surname lastname address zip fax phone");
$_POST['date'] = $_POST['y']."-".$_POST['m']."-".$_POST['d'];
$query  = "UPDATE $table SET ".dbSet($fields)." stamp=NOW() WHERE id=$id";

그것은 코드를 매우 건조하고 쉽지만 동시에 유연하게 만듭니다.

비슷한 기능을 공유하고자하는 사람이 누구인지 물어볼 필요가 있습니다.

나는 아직도 그것을 의심 할 여지가있다. PDO 준비 문을 사용하여 데이터를 삽입하는 간단하고 간단한 방법이 있습니까? 어떤 형태이어야 하는가? 쿼리 빌더 도우미? 또는 쿼리 도우미를 삽입 하시겠습니까? 어떤 매개 변수를 취해야합니까?

여기에 대한 답변으로 사용하기에 충분히 쉬울 수 있기를 바랍니다. 모든 주제에서 준비된 문장 사용 권장 사항을 볼 수 있기 때문에 좋은 예제는 하나도 없습니다. 실생활 예. bind_param ()을 20 회 입력하는 것은 좋은 프로그래밍 스타일이 아닙니다. 심지어 20 개의 물음표도 있습니다.

해결법

  1. ==============================

    1.나는 보통 PDO를 확장하는 수업을 가지고 있지만 수업은 꽤 습관적입니다. 만약 내가 그것을 정리하고 시험 해보면 나는 나중에 그것을 게시 할 것이다. 그러나 여기에 시스템에 대한 해결책이 있습니다.

    나는 보통 PDO를 확장하는 수업을 가지고 있지만 수업은 꽤 습관적입니다. 만약 내가 그것을 정리하고 시험 해보면 나는 나중에 그것을 게시 할 것이다. 그러나 여기에 시스템에 대한 해결책이 있습니다.

    function dbSet($fields, &$values) {
        $set = '';
        $values = array();
    
        foreach ($fields as $field) {
            if (isset($_POST[$field])) {
                $set .= "`$field` = ?,";
                $values[] = $_POST[$field];
            }
        }
    
        return rtrim($set, ',');
    }
    
    $fields = explode(" ","name surname lastname address zip fax phone date");
    $_POST['date'] = $_POST['y']."-".$_POST['m']."-"$_POST['d'];
    
    $query  = "UPDATE $table SET ".dbSet($fields, $values).", stamp=NOW() WHERE id=?";
    $values[] = $id;
    
    $dbh->prepare($query);
    $dbh->execute($values);  
    

    이것은 완벽하지 않을 수 있으며 조정할 수 있습니다. $ dbh가 PDO 연결로 설정된다는 점을 고려합니다. 내가 만든 모든 사소한 구문 문제가 보류 중입니다.

    편집하다

    실제로, 나는 Doctrine ORM (또는 다른 ORM)으로 갈 것이라고 생각한다. 모델을 설정하고 거기에 모든 유효성 검사를 추가하면 다음과 같이 간단합니다.

    $table = new Table();
    $table->fromArray($_POST);
    $table->save();
    

    그 내용을 쉽게 채워야합니다. 물론 Doctrine과 같은 ORM이 있습니다.

    업데이트 됨

    isset을 다시 넣고 substr에 rtrim을 사용하는 것과 같이 첫 번째 코드를 약간 수정했습니다. PDO Extension 클래스의 모의를 제공하기 위해 작업을 진행하기 만하면됩니다. PDO Extension 클래스는 작동 방식을 레이아웃하고 일부 유닛 테스트를 수행하여 작동하는지 확인해야합니다.

  2. ==============================

    2.모두에게 감사 드려요. 모든 대답이 도움이되었고 나는 현상금을 나눌 수 있었으면 좋겠다.

    모두에게 감사 드려요. 모든 대답이 도움이되었고 나는 현상금을 나눌 수 있었으면 좋겠다.

    마지막으로, 놀랍게도, 나는 그것을 받아 들일 수있는 대답에 기초하여 이전과 같은 방식으로 만들 수있었습니다.

    $fields = array("login","password");
    $_POST['password'] = MD5($_POST['login'].$_POST['password']);
    $stmt = $dbh->prepare("UPDATE users SET ".pdoSet($fields,$values)." WHERE id = :id");
    $values["id"] = $_POST['id'];
    $stmt->execute($values);
    

    도우미 함수로 래핑 될 수 있지만 필요성은 의심 스럽습니다. 코드를 단 한 줄로 줄입니다.

    pdoSet 코드 :

    function pdoSet($fields, &$values, $source = array()) {
      $set = '';
      $values = array();
      if (!$source) $source = &$_POST;
      foreach ($fields as $field) {
        if (isset($source[$field])) {
          $set.="`$field`=:$field, ";
          $values[$field] = $source[$field];
        }
      }
      return substr($set, 0, -2); 
    }
    
  3. ==============================

    3.코어 PDO 클래스와 메소드를 다음과 같이 확장합니다.

    코어 PDO 클래스와 메소드를 다음과 같이 확장합니다.

    class Database extends PDO
    {
        public function QueryFromPost($Query,$items)
        {
            $params = array();
            $Query .= ' WHERE ';
    
            foreach($items as $key => $default)
            {
                 $Query .= ' :' . $key. ' = ' . $key;
                 if(isset($_POST[$key]))
                 {
                      $params[':' . $key] = $_POST[$key];
                 }else
                 {
                     $params[':' . $key] = $default;
                 }
            }
            $s = $this->prepare($Query);
            return $s->execute($params);
        }
    }
    

    그렇게 사용하십시오.

    $db = new Database(/*..Default PDO Params*/);
    $statement = $db->QueryFromPost('SELECT * FROM employees',array('type' => 'plc'));
    foreach($preparedStatement->fetchAll() as $row)
    {
        //...
    }
    

    그러나 당신이하려는 일에 매우 지쳐 있어야한다고 이미 말했듯이, 당신은 당신의 데이터를 검증 할 필요가 있습니다. 그것은 위생 ​​처리되었지만 당신은 검증되지 않았습니다.

  4. ==============================

    4.매개 변수 바인딩 사례를 반복적으로 생각하는 것에 대해 나는 사소한 것을 패치 해왔다. http://fossil.include-once.org/hybrid7/wiki/db

    매개 변수 바인딩 사례를 반복적으로 생각하는 것에 대해 나는 사소한 것을 패치 해왔다. http://fossil.include-once.org/hybrid7/wiki/db

    어쨌든; 다른 준비된 명령문 자리 표시자를 제공합니다. 귀하의 본보기는 다음과 같이 단축 될 수 있습니다 :

    db("UPDATE table SET :, WHERE id=:id", $columns[], $where[]);
    

    이 경우는 명명 된 매개 변수에서만 작동하므로 $ set은 array ( "name"=> ..) 및 $ where = array ( "id"=> 123)입니다. :는 전달한 첫 번째 배열에서 확장됩니다. 쉼표로 구분 된 이름 = : 이름 쌍으로 바뀝니다 (니모닉이 : 인 이유입니다).

    몇 가지 더 많은 자리 표시자가 있습니다 :, : & : and :? 다른 사용 사례의 경우 오직 ?? 정말 다소 표준입니다. 따라서 익숙해 져야하지만 준비된 문과 배열 바인딩 (PDO는 기본적으로 수행하지 않음)을 상당히 단순화합니다.

  5. ==============================

    5.다음은 일반적인 데이터베이스 추상화 클래스입니다. autoExecute () 함수를 살펴보십시오. 그것은 당신이 달성하기를 원하는 것이 무엇이든간에 융통성을 제공합니다. 나는 이것이 PHP 5.3을 위해 작성되었으며, PostgreSQL을 위해 약간 조정되었다는 것을 경고해야한다.

    다음은 일반적인 데이터베이스 추상화 클래스입니다. autoExecute () 함수를 살펴보십시오. 그것은 당신이 달성하기를 원하는 것이 무엇이든간에 융통성을 제공합니다. 나는 이것이 PHP 5.3을 위해 작성되었으며, PostgreSQL을 위해 약간 조정되었다는 것을 경고해야한다.

    <?php
    /**
     * Database abstraction and query result classes
     * Requires PHP 5.3
     *
     * Events:
     *  - on_commit - Dispatched when the transaction is successfully committed to the DB
     *  - on_rollback - Dispatched when the transaction is rolled back in the DB
     *
     * @author Kenaniah Cerny <kenaniah@gmail.com>
     * @version 1.1.2
     * @license http://creativecommons.org/licenses/by/3.0/us/
     * @copyright Copyright (c) 2009, Kenaniah Cerny
     */
    class Database extends PDO {
    
        private $stmt;
        private $good_trans = null;
        private $nested_transactions = 0; //Keeps track of virtual transaction nesting level
        private $callbacks = array();
    
        private static $connections = array(); //Keeps track of opened connections
    
        /**
         * Returns a database instance using lazy instantiation
         * @param string $name a database connection name
         * @param array $config database config details for a new connection
         */
        static function getInstance($name = 'main', $config=array()){
    
            //Attempt to return an existing connection
            if(array_key_exists($name, self::$connections)):
                return self::$connections[$name];
            endif;
    
            //Attempt to create a new connection
            $host = in_array($config['host'], array('localhost', '127.0.0.1')) ? "" : ";host=" . $config['host'];
            $db = new Database($config['driver'].":dbname=".$config['name'].$host, $config['user'], $config['pass']);
    
            //Save to connection pool
            self::$connections[$name] = $db;
    
            return $db;
    
        }
    
        /**
         * Registers a callback to be run when the given event is invoked
         * @param string $event Event name
         * @param callable $callable
         */
        public function register_listener($event, $callable){
    
            if(!array_key_exists($event, $this->callbacks)):
                $this->callbacks[$event] = array($callable);
            else:
                $this->callbacks[$event][] = $callable;
            endif;
    
        }
    
        /**
         * Invokes callbacks for the given event type
         * @param string $event Event name
         * @param boolean $stop_on_false Stops bubbling this event if one of the handlers returns false
         */
        protected function dispatch_event($event, $stop_on_false = true){
    
            if(!array_key_exists($event, $this->callbacks)) return;
    
            foreach($this->callbacks[$event] as $callable):
    
                $res = call_user_func($callable, $this, $event);
                if($stop_on_false && $res === false) return false;
    
            endforeach;
    
            return true;
    
        }
    
        /**
         * PDO Constructor
         * @param $dsn
         * @param $username
         * @param $password
         */
        function __construct($dsn, $username, $password) {
            parent::__construct($dsn, $username, $password);
        }
    
        /**
         * Prepares an SQL statement
         * @param string $sql
         */
        function prepare($sql) {
            $stmt = parent::prepare($sql, array(PDO::ATTR_STATEMENT_CLASS => array(__NAMESPACE__.'\DatabaseStatement')));
            $stmt->setFetchMode(PDO::FETCH_ASSOC);
            return $stmt;
        }
    
        /**
         * Prepares an executes an SQL statement with the parameters provided
         * @param string $sql
         * @param array $params
         */
        function execute($sql, $params = array()) {
    
            if($this->debug):
                var_dump("Statement:\n".$sql."\nParams: ".$this->fmt($params));
            endif;
    
            try {
                $stmt = $this->prepare($sql);
                $val = $stmt->execute((array) $params);
                if($stmt->errorCode() != '00000') error_log($this->errormsg());
                if($this->debug && $stmt->errorCode() != '00000'){
                    var_dump($stmt->errorInfo());
                    Errors::add("Database error: ".$this->errormsg(), E_USER_ERROR);
                }
                if(!$val) return false;
            } catch (PDOException $e){
                if($this->debug) var_dump($stmt->errorInfo());
                error_log($this->errormsg());
                Errors::add("Database error: ".$this->errormsg(), E_USER_ERROR);
                if($this->nested_transactions) $this->failTrans();
                else throw $e;
            }
    
            $this->stmt = $stmt;
    
            return $stmt;
    
        }    
    
        /**
         * Returns the value of the first column of the first row
         * of the database result.
         * @param $sql
         * @param $params
         */
        function getOne($sql, $params = array()){
            $stmt = $this->execute($sql, $params);
            return $stmt ? $stmt->getOne() : false;
        }
    
        /**
         * Fetches a single column (the first column) of a result set
         * @param $sql
         * @param $params
         */
        function getCol($sql, $params = array()){
            $stmt = $this->execute($sql, $params);
            return $stmt ? $stmt->getCol() : false;
        }
    
        /**
         * Fetches rows in associative array format
         * @param $sql
         * @param $params
         */
        function getAssoc($sql, $params = array()){
            $stmt = $this->execute($sql, $params);
            return $stmt ? $stmt->getAssoc() : false;
        }
    
        /**
         * Fetches rows in array format with columns
         * indexed by ordinal position
         * @param $sql
         * @param $params
         */
        function getArray($sql, $params = array()){
            $stmt = $this->execute($sql, $params);
            return $stmt ? $stmt->getArray() : false;
        }
    
        /**
         * Fetches all rows in associative array format
         * @param $sql
         * @param $params
         */
        function getAll($sql, $params = array()){
            return $this->getAssoc($sql, $params);
        }
    
        /**
         * Fetches rows in array format where the first column
         * is the key name and all other columns are values
         * @param $sql
         * @param $params
         */
        function getKeyPair($sql, $params = array()){
            $stmt = $this->execute($sql, $params);
            return $stmt ? $stmt->getKeyPair() : false;
        }
    
        /**
         * Fetches rows in multi-dimensional format where the first
         * column is the key name and all other colums are grouped
         * into associative arrays for each row
         * @param $sql
         * @param $params
         */
        function getGroup($sql, $params = array()){
            $stmt = $this->execute($sql, $params);
            return $stmt ? $stmt->getGroup() : false;
        }
    
        /**
         * Fetches only the first row and returns it as an
         * associative array
         * @param $sql
         * @param $params
         */
        function getRow($sql, $params = array()){
            $stmt = $this->execute($sql, $params);
            return $stmt ? $stmt->getRow() : false;
        }
    
        /**
         * Internal function used for formatting parameters in debug output
         * @param unknown_type $params
         */
        private function fmt($params){
            $arr = array();
            foreach((array) $params as $k=>$v){
                if(is_null($v)) $v = "NULL";
                elseif(is_bool($v)) $v = $v ? "TRUE" : "FALSE";
                $arr[] = "[".$k."] => ".$v;
            }
            return "Array(".join(", ", $arr).")";
        }
    
        /**
         * Returns the number of affected rows from an executed statement
         */
        function affected_rows(){
            return $this->stmt ? $this->stmt->rowcount() : false;
        }
    
        /**
         * Automated statement processing
         *
         * Params array takes the following fields:
         *
         *  - table         The name of the table to run the query on
         *
         *  - data          A key-value paired array of table data
         *
         *  - mode          INSERT, UPDATE, REPLACE, or NEW
         *
         *  - where         Can be a string or key-value set. Not used on INSERTs
         *                  If key-value set and numerically indexed, uses values from data
         *                  If key-value and keys are named, uses its own values
         *
         *  - params        An array of param values for the where clause
         *
         *  - returning     Optional string defining what to return from query.
         *                  Uses PostgreSQL's RETURNING construct
         *
         *  This method will return either a boolean indicating success, an array
         *  containing the data requested by returning, or a boolean FALSE indicating
         *  a failed query.
         *
         */
        function autoExecute($table, $params, $data){
    
            $fields = array(); //Temp array for field names
            $values = array(); //Temp array for field values
            $set = array(); //Temp array for update sets
            $ins = array(); //Insert value arguments
    
            $params['table'] = $table;
            $params['data'] = $data;
    
            $params['params'] = (array) $params['params'];
    
            //Parse the data set and prepare it for different query types
            foreach((array) $params['data'] as $field => $val):
    
                $fields[] = $field;
                $values[] = $val;
                $ins[] = "?";
                $set[] = $field . " = ?";
    
            endforeach;
    
            //Check for and convert the array/object version of the where clause param
            if(is_object($params['where']) || is_array($params['where'])):
    
                $clause = array();
                $params['params'] = array(); //Reset the parameters list
    
                foreach($params['where'] as $key => $val):
    
                    if(is_numeric($key)):
                        //Numerically indexed elements use their values as field names
                        //and values from the data array as param values
                        $field = $val;
                        $params['params'][] = $params['data'][$val];
                    else:
                        //Named elements use their own names and values
                        $field = $key;
                        $params['params'][] = $val;
                    endif;
    
                    $clause[] = $field . " = ?";
    
                endforeach;
    
                $params['where'] = join(" AND ", $clause);
    
            endif;
    
            //Figure out what type of query we want to run
            $mode = strtoupper($params['mode']);
            switch($mode):
                case 'NEW':
                case 'INSERT':
    
                    //Build the insert query
                    if(count($fields)):
                        $sql =  "INSERT INTO " . $params['table']
                                . " (" . join(", ", $fields) . ")"
                                . " SELECT " . join(", ", $ins);
                    else:
                        $sql =  "INSERT INTO " . $params['table']
                                . " DEFAULT VALUES";
                    endif;
    
                    //Do we need to add a conditional check?
                    if($mode == "NEW" && count($fields)):
                        $sql .= " WHERE NOT EXISTS ("
                                . " SELECT 1 FROM " . $params['table']
                                . " WHERE " . $params['where']
                                . " )";
                        //Add in where clause params
                        $values = array_merge($values, $params['params']);
                    endif;
    
                    //Do we need to add a returning clause?
                    if($params['returning']):
                        $sql .= " RETURNING " . $params['returning'];
                    endif;
    
                    //Execute our query
                    $result = $this->getRow($sql, $values);
    
                    //Return our result
                    if($params['returning']):
                        return $result;
                    else:
                        return $result !== false;
                    endif;
    
                    break;
                case 'UPDATE':
    
                    if(!count($fields)) return false;
    
                    //Build the update query
                    $sql =  "UPDATE " . $params['table']
                            . " SET " . join(", ", $set)
                            . " WHERE " . $params['where'];
    
                    //Do we need to add a returning clause?
                    if($params['returning']):
                        $sql .= " RETURNING " . $params['returning'];
                    endif;
    
                    //Add in where clause params
                    $values = array_merge($values, $params['params']);
    
                    //Execute our query
                    $result = $this->getRow($sql, $values);
    
                    //Return our result
                    if($params['returning']):
                        return $result;
                    else:
                        return $result !== false;
                    endif;
    
                    break;
                case 'REPLACE': //UPDATE or INSERT
    
                    //Attempt an UPDATE
                    $params['mode'] = "UPDATE";
                    $result = $this->autoExecute($params['table'], $params, $params['data']);
    
                    //Attempt an INSERT if UPDATE didn't match anything
                    if($this->affected_rows() === 0):
                        $params['mode'] = "INSERT";
                        $result = $this->autoExecute($params['table'], $params, $params['data']);
                    endif;
    
                    return $result;
    
                    break;
                case 'DELETE':
    
                    //Don't run if we don't have a where clause
                    if(!$params['where']) return false;
    
                    //Build the delete query
                    $sql =  "DELETE FROM " . $params['table']
                            . " WHERE " . $params['where'];
    
                    //Do we need to add a returning clause?
                    if($params['returning']):
                        $sql .= " RETURNING " . $params['returning'];
                    endif;
    
                    //Execute our query
                    $result = $this->getRow($sql, $params['params']);
    
                    //Return our result
                    if($params['returning']):
                        return $result;
                    else:
                        return $result !== false;
                    endif;
    
                    break;
                default:
                    user_error('AutoExecute called incorrectly', E_USER_ERROR);
                    break;
            endswitch;
    
        }
    
        /**
         * @see $this->startTrans()
         */
        function beginTransaction(){
            $this->startTrans();
        }
    
        /**
         * Starts a smart transaction handler. Transaction nesting is emulated
         * by this class.
         */
        function startTrans(){
    
            $this->nested_transactions++;
            if($this->debug) var_dump("Starting transaction. Nesting level: " . $this->nested_transactions);
    
            //Do we need to begin an actual transaction?
            if($this->nested_transactions === 1):
                parent::beginTransaction();
                $this->good_trans = true;
                $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            endif;
    
        }
    
        /**
         * Returns TRUE if the transaction will attempt to commit, and
         * FALSE if the transaction will be rolled back upon completion.
         */
        function isGoodTrans(){
            return $this->good_trans;
        }
    
        /**
         * Marks a transaction as a failure. Transaction will be rolled back
         * upon completion.
         */
        function failTrans(){
            if($this->nested_transactions) $this->good_trans = false;
            if($this->debug):
                Errors::add("Database transaction failed: ".$this->errorMsg());
            endif;
            $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
        }
    
        /**
         * @see $this->rollbackTrans()
         */
        function rollback(){
            $this->rollbackTrans();
        }
    
        /**
         * Rolls back the entire transaction and completes the current nested
         * transaction. If there are no more nested transactions, an actual
         * rollback is issued to the database.
         */
        function rollbackTrans(){
            if($this->nested_transactions):
                $this->nested_transactions--;
                if($this->debug) var_dump("Rollback requested. New nesting level: " . $this->nested_transactions);
                $this->good_trans = false;
                if($this->nested_transactions === 0):
                    $this->good_trans = null;
                    $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
                    if($this->debug) var_dump("Transaction rolled back.");
                    parent::rollback();
                    $this->dispatch_event('on_rollback');
                endif;
            endif;
        }
    
        /**
         * Clears the nested transactions stack and issues a rollback to the database.
         */
        function fullRollback(){
            while($this->nested_transactions) $this->rollbackTrans();
        }
    
        /**
         * Returns the number of nested transactions:
         * 0 - There is no transaction in progress
         * 1 - There is one transaction pending
         * >1 - There are nested transactions in progress
         */
        function pending_trans(){
            return $this->nested_transactions;
        }
    
        /**
         * @see $this->completeTrans()
         */
        function commit($fail_on_user_errors = false){
            return $this->completeTrans($fail_on_user_errors);
        }
    
        /**
         * Completes the current transaction and issues a commit or rollback to the database
         * if there are no more nested transactions. If $fail_on_user_errors is set, the
         * transaction will automatically fail if any errors are queued in the Errors class.
         * @param boolean $fail_on_user_errors
         */
        function completeTrans($fail_on_user_errors = false){
    
            if(!$this->nested_transactions) return;
    
            //Fail the transaction if we have user errors in the queue
            if($fail_on_user_errors && Errors::exist()) $this->good_trans = false;
    
            //Do we actually need to attempt to commit the transaction?
            if($this->nested_transactions === 1):
    
                if(!$this->good_trans || !parent::commit()){
                    if($this->debug) var_dump("Transaction failed: " . $this->errormsg());
                    $this->rollbackTrans();
                    return false;
                }
    
                //Transaction was good
                $this->nested_transactions--;
                $this->good_trans = null;
                $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
                if($this->debug) var_dump("Transaction committed.");
                $this->dispatch_event('on_commit', false);
                return true;
            else:
                //Don't take action just yet as we are still nested
                $this->nested_transactions--;
                if($this->debug) var_dump("Virtual commit. New nesting level: " . $this->nested_transactions);
            endif;
    
            return $this->good_trans;
    
        }
    
        /**
         * Returns the text of the most recently encountered error
         */
        function errormsg(){
            $msg = $this->errorInfo();
            return $msg[2];
        }
    
    }
    
    class DatabaseStatement extends \PDOStatement implements \Countable {
    
        /**
         * Binds passed parameters according to their PHP type and executes
         * the prepared statement
         */
        function execute($params = array()) {
            $i = 1;
            foreach($params as $k => $v):
                $mode = PDO::PARAM_STR;
                if(is_null($v)) $mode = PDO::PARAM_NULL;
                elseif(is_bool($v)) $mode = PDO::PARAM_BOOL;
                elseif(is_resource($v)) $mode = PDO::PARAM_LOB;
                $this->bindParam($i, $params[$k], $mode);
                $i++;
            endforeach;
            $ok = parent::execute();
            return $ok ? $this : false;
        }
    
        /**
         * Returns the value of the first column of the first row
         */
        function getOne() {
            return $this->fetchColumn(0);
        }
    
        /**
         * Returns an array of values of the column found at $index
         * position.
         * @param $index
         */
        function getCol($index=0) {
            return $this->fetchAll(PDO::FETCH_COLUMN, $index);
        }
    
        /**
         * Returns all rows in numeric array format
         */
        function getArray(){
            return $this->fetchAll(PDO::FETCH_NUM);
        }
    
        /*
         * Returns all rows in associative array format
         */
        function getAll(){
            return $this->fetchAll(PDO::FETCH_ASSOC);
        }
    
        /**
         * Returns all rows in associative array format
         */
        function getAssoc() {
            return $this->fetchAll(PDO::FETCH_ASSOC);
        }
    
        /**
         * Returns rows in multi-dimensional format where the first
         * column is the key name and all other colums are grouped
         * into associative arrays for each row
         */
        function getGroup() {
            return $this->fetchAll(PDO::FETCH_GROUP);
        }
    
        /**
         * Returns a single row in associative format
         */
        function getRow(){
            return $this->fetch(PDO::FETCH_ASSOC);
        }
    
        /**
         * Fetches rows in array format where the first column
         * is the key name and all other columns are values
         */
        function getKeyPair(){
            //Emulate it
            $tmp = $this->fetchAll(PDO::FETCH_ASSOC);
            $arr = array();
            for($i = 0; $i < count($tmp); $i++){
                $arr[array_shift($tmp[$i])] = count($tmp[$i]) > 1 ? $tmp[$i] : array_shift($tmp[$i]);
            }
            return $arr;
        }
    
        /**
         * Returns the number of rows returned by this statement
         */
        function recordCount(){
    
            return $this->rowCount();
    
        }
    
        /**
         * Returns the number of rows returned by this statement
         */
        function count(){
    
            return $this->rowCount();
    
        }
    }
    
  6. ==============================

    6.비록 나의 DB 클래스가 prepared statement를 사용하지 않더라도, 나는 여기서 그것을 언급하고자한다. 준비된 진술로 모든 것을 구현할 이유가 전혀 없습니다. 나는 준비된 문장이 더 빠르다는 것을 알고 있지만, 여러 번 사용했을 때만 그렇다. 쿼리를 한 번만 실행하면 (그리고이 쿼리가 일반적으로 사용해야하는 유일한 유형의 쿼리입니다) 느려집니다. 따라서 어디서나 준비된 문장을 사용하는 것은 비생산적입니다.

    비록 나의 DB 클래스가 prepared statement를 사용하지 않더라도, 나는 여기서 그것을 언급하고자한다. 준비된 진술로 모든 것을 구현할 이유가 전혀 없습니다. 나는 준비된 문장이 더 빠르다는 것을 알고 있지만, 여러 번 사용했을 때만 그렇다. 쿼리를 한 번만 실행하면 (그리고이 쿼리가 일반적으로 사용해야하는 유일한 유형의 쿼리입니다) 느려집니다. 따라서 어디서나 준비된 문장을 사용하는 것은 비생산적입니다.

    클래스의 적절한 설명은 stackoverflow에 다른 곳에서 찾을 수 있습니다. 그러나 여기에 좋은 것들이 있습니다 :

    하지만 전체 정보는 위에 링크 된 stackoverflow 게시물을 참조하십시오.)

    추신 : 레고에있는 README는이 클래스에 적용되지 않습니다. 일반적인 DB.php를위한 것이지 DB_intelligent.php를위한 것이 아닙니다. 조달청 :이 클래스는 PHP 5.3 용으로 작성되었습니다. PHP 5.2에서 사용하려면 DB_forPHP52.php에서 DB_intelligent.php로 모든 PDO 메소드를 복사하고 __callStatic 메소드를 제거하십시오.

  7. ==============================

    7.그냥 다른 답변에 추가 : 열 이름의 적절한 따옴표에 대한 방법 :

    그냥 다른 답변에 추가 : 열 이름의 적절한 따옴표에 대한 방법 :

    /**
     * Escape identifier (database/table/column name) - ie. if you're using MySQL:
     * db_name.tbl_name.col_name -> `db_name`.`tbl_name`.`col_name`
     **/
    protected function quoteIdentifier($identifier) {
        static $escapeChars = array(
            'mysql'  => '``',
            'oracle' => '""',
            'mssql'  => '[]',
            //...
        );
    
        $escape = $escapeChars[$this->getAttribute(self::ATTR_DRIVER_NAME)];
        $identifier = (array) explode('.', $identifier);
        $identifier = array_map(function($segment) use($escape) {
            return $escape[0] . $segment . $escape[1];
        }, $identifier);
    
        return implode('.', $identifier);
    }
    
  8. ==============================

    8.다음과 같이 PDO를 확장 할 수 있습니다.

    다음과 같이 PDO를 확장 할 수 있습니다.

    class CustomPDO extends PDO {
    
        public function updateTable($sTable, array $aValues = array()){
    
            if (!empty($aValues) && !empty($sTable)){
    
                # validation of table / columns name
                $sTable = mysql_real_escape_string($sTable);
    
                $aColumns = array_map('mysql_real_escape_string',array_keys($aValues));
    
                $aElements = array();
    
                foreach ($aColumns as $sColumn){
    
                    $aElements[] = "`$sColumn`= :$sColumn";
    
                } // foreach
    
                $sStatement = "UPDATE $sTable SET " . implode(',', $aElements);
    
                $oPDOStatement = $this->prepare($sStatement);
    
                if ($oPDOStatement){
    
                    return $oPDOStatement->execute($aValues);
    
                } // if
    
            } // if
    
            return false;
    
        } // updateTable
    
    }
    
    # usage :
    # $oDb->updateTable('tbl_name',$_POST);
    
    
    # test
    
    error_reporting (E_ALL);
    ini_Set('display_errors',1);
    
    $oDb = new CustomPDO('sqlite::memory:');
    
    $oDb->exec('CREATE TABLE t1(c1 TEXT, c2 INTEGER)');
    
    $oDb->exec("INSERT INTO t1(c1, c2) VALUES ('X1',1)");
    
    var_dump($oDb->query('SELECT * FROM t1')->fetchAll(PDO::FETCH_ASSOC));
    
    $oDb->updateTable('t1', array('c1'=>'f1','c2**2'=>2));
    
    var_dump($oDb->query('SELECT * FROM t1')->fetchAll(PDO::FETCH_ASSOC));
    
  9. ==============================

    9.다른 사람들과 마찬가지로 필자는 자신의 필요에 맞게 표준 PDO 클래스를 확장했습니다. 이것의 라인을 따라 뭔가가 당신에게 어울릴 수 있습니다 :

    다른 사람들과 마찬가지로 필자는 자신의 필요에 맞게 표준 PDO 클래스를 확장했습니다. 이것의 라인을 따라 뭔가가 당신에게 어울릴 수 있습니다 :

    Class ExtendedPDO extends PDO
    {
    
        public function prepareArray($sql, array $data)
        {
            // Call the standard prepare method
            $statement = parent::prepare($sql);
    
            foreach ($data as $field=>$value) {
                $statement->bindValue(':' . $field, $value);
            }
    
            return $statement;
        }
    
    }
    

    그럼 당신은 아주 간단하게 그것을 사용할 수 있습니다 :

    // Include connection variables
    include '../includes/config/database.php';
    
    // The data to use in the query
    $data = array(
        'title' => 'New value',
        'id'    => 1,
    );
    
    // The query you want to run
    $sql = '
        UPDATE
            test
        SET
            title = :title
        WHERE
            id = :id
    ';
    
    try {
        // Connect to the database
        $dbh = new ExtendedPDO(PDO_DSN, PDO_USERNAME, PDO_PASSWORD);
    
        // Attach the data to your query
        $stmt = $dbh->prepareArray($sql, $data);
    
        // Run it
        $stmt->execute();
    } catch (PDO Exception $e) {
        echo $e->getMessage();
    }
    
  10. ==============================

    10.삽입 쿼리에는 종종 많은 자리 표시자가 필요합니다. 물음표 스타일은 읽기가 어렵고 명명 된 매개 변수는 반복적이어서 타이핑 오류가 발생하기 쉽습니다. 그래서 전체 삽입 쿼리를위한 함수를 만들었습니다 :

    삽입 쿼리에는 종종 많은 자리 표시자가 필요합니다. 물음표 스타일은 읽기가 어렵고 명명 된 매개 변수는 반복적이어서 타이핑 오류가 발생하기 쉽습니다. 그래서 전체 삽입 쿼리를위한 함수를 만들었습니다 :

    function insert($table, $col_val){
        global $db;
        $table = preg_replace('/[^\da-z_]/i', '', $table);
        $smt = $db->prepare("DESCRIBE `$table`");
        $smt->execute();
        $columns = $smt->fetchAll(PDO::FETCH_COLUMN);
        $sets = array();
        $exec = array();
        foreach($col_val as $col => $val){
            if(!in_array($col, $columns))
                return false;
            $sets[] .= "`$col`=?";
            $exec[] = $val;
        }
        $set = implode(',', $sets);
        $smt = $db->prepare("INSERT INTO `$table` SET $set");
        $smt->execute($exec);
        return $db->lastInsertId();
    }
    

    사용법은 간단합니다.

    insert('table_name', array(
        'msg'   =>  'New message',
        'added' =>  date('Y-m-d H:i:s'),
    ));
    

    lastInsertId ()가 필요한 경우 :

    $new_id = insert(...
    
  11. ==============================

    11.참고 자료 : PHP에서 SQL 주입을 방지하려면 어떻게해야합니까?

    참고 자료 : PHP에서 SQL 주입을 방지하려면 어떻게해야합니까?

    $preparedStatement = $db->prepare('SELECT * FROM employees WHERE name = :name');
    $preparedStatement->execute(array(':name' => $name));
    $rows = $preparedStatement->fetchAll();
    
  12. from https://stackoverflow.com/questions/3773406/insert-update-helper-function-using-pdo by cc-by-sa and MIT license