Класс ПДО в MySQL


Пожалуйста, дайте мне какие-либо комментарии по поводу этих кодов. Это достаточно, чтобы предотвратить SQL-инъекции? Что я должен сделать, чтобы сделать код лучше?

<?php

    /**
     * Description of MySql
     * @name MySQL PDO
     * @version 1.0
     * @author Yauri
     * 
     */
    class MySql {

        private $mPDO;

        public function __construct($dbHost,$dbName,$dbUser,$dbPass) {

            try {
                $this->mPDO = new PDO("mysql:host=$dbHost;dbname=$dbName", "$dbUser", "$dbPass");

                //$this->mPDO->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
                $this->mPDO->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);

            }
            catch(PDOException $e){
                die($e->getMessage());
            }
        }

        /**
         * Method for executing query
         * @param string $query 
         * @data array Used on queryUpdate method
         * @return array Result of query
         */
        public function query($query){

            $exec = $this->mPDO->prepare($query);
            if($data) $exec->execute($data);
            else $exec->execute();
            $result = $exec->fetchAll();
            return $result;
        }

        /**
         * Method for selecting data
         * @param $table string 
         * @param $column array
         * @return array Result of query
         */
        public function querySelect($table, $column, $where=NULL, $limit=NULL){

            if($column!="*"){
                $column = $this->buildColumn($column);
            }

            if(isset($where)){
                $condition = $this->BuildWhere($where);
                $query = "SELECT {$column} FROM {$table} {$condition}";
            }
            else {
                $query = "SELECT {$column} FROM {$table}";
            }

            if(isset($limit)){
                $query .= " LIMIT {$limit}";
            }

            $exec = $this->mPDO->prepare($query);

            if(isset($where)){
                $exec->execute(array_values($where));
            }
            else{
                $exec->execute();
            }

            return $exec->fetchAll();
        }

        /**
         * Method for insert
         * @param string $tableName
         * @param array $data  Specify array keys as database column name 
         * @return boolean
         */
        public function queryInsert($tableName, $data) {

            $dataString = $this->buildInsert($data);
            $query = "INSERT INTO {$tableName} {$dataString}";

            $exec = $this->mPDO->prepare($query);

            if($exec->execute(array_values($data))){
                return true;
            }
            else{
                return false;
            }
        }

        /**
         * Method for update
         * @param string $tableName
         * @param array $data  Specify array keys as database column name 
         * @param array $where  Specify array keys as database column name 
         */
        public function queryUpdate($tableName, $data, $where) {

            $update = $this->buildUpdate($data);
            $condition = $this->buildWhere($where);

            $query = "UPDATE ".$tableName." SET {$update} {$condition}";
            $exec = $this->mPDO->prepare($query);
            $paramVal = array_merge(array_values($data),array_values($where));
            $exec->execute($paramVal);
            if($exec->rowCount()){
                return true;
            }
            else {
                return false;
            }

        }

        /**
         * Method for delete
         * @param string $tableName
         * @param array $where You must specify the key as column name 
         */
        public function queryDelete($tableName, $where) {

            $condition = $this->buildWhere($where);
            $query = "DELETE FROM {$tableName} {$condition}";

            $exec = $this->mPDO->prepare($query);
            $paramVal = array_values($where);
            $exec->execute($paramVal);
            $count = $exec->rowCount();
            if($exec->rowCount()){
                return true;
            }
            else {
                return false;
            }

        }

        /**
         * Method for build a string for insert query
         * @param array $data You must specify the key as column name
         */
        private function buildInsert($data) {
            $length = count($data);
            $column = " (";
            $values = " VALUES (";
            foreach($data as $key => $val) {
                if($length != 1){
                    $column .= $key.", ";
                    $values .= "?, ";
                }
                else {
                    $column .= $key;
                    $values .= "?";
                }
                $length--;
            }
            $column .= ")";
            $values .= ")";
            return $column.$values;
        }

        /**
         * Method for build a string for update query
         * @param array $data You must specify the key as column name
         */
        private function buildUpdate($data){
            $length = count($data);
            $updateData = "";
            foreach($data as $key => $val){
                if($length!=1) {
                    $updateData .= $key." = ? , ";
                }
                else{
                    $updateData .= $key." = ?";
                }
                $length--;
            }
            return $updateData;
        }

        /**
         * Method for build a string for selected column
         * @param array $column
         * @return string 
         */
        private function buildColumn($column){
            $length = count($column);
            $selectedColumn = "";
            foreach($column as $val){
                if($length!=1) {
                    $selectedColumn .= $val.", ";
                }
                else{
                    $selectedColumn .= $val;
                }
                $length--;
            }
            return $selectedColumn;
        }

        /**
         * Method for build a string for query which using condition
         * @param array $where You must specify the key as column name 
         * @return string
         */
        private function buildWhere($where) {
            $length = count($where);
            $condition = " WHERE ";
            foreach($where as $key => $val){
                if($length!=1) {
                    $condition .= $key." = ? AND ";
                }
                else {
                    $condition .= $key." = ?";
                }
                $length--;
            }
            return $condition;
        }

    }

    ?>


758
2
задан 9 октября 2011 в 07:10 Источник Поделиться
Комментарии
1 ответ


  • Ваш BuildInsert-метод является единственным, который использует использования mysql_real_escape_string. Почему? Почему бы просто не использовать параметризованные запросы, как в вашем "выборе", "обновить" и "удалить" случаях?

  • Ваш запрос метод использует переменную $данных , который не определен. Вероятно, отсутствующий параметр.

  • if($exec->execute()){
    return "Insert into database succeed.";
    }
    else{
    return "Insert into database failed.";
    }

    Это плохо, не возвращать строку, когда боол будет достаточно. Что, если вы хотите перевести приложение?


  • Иногда вы используете метод имена, начинающиеся со строчной, как queryInsert и в других случаях вы начинаете с заглавной, как QueryUpdate. Будьте последовательны.

  • $mQuery - это может быть заменена на локальную переменную. Разве вы хотите расширить ваш класс, так что вы можете принести в последнем запросе. В противном случае: это кидалово.

  • $mDbHost - не используется, это кидалово.

Обновление


  • Это:

    if($exec->execute(array_values($data))){
    return true;
    }
    else{
    return false;
    }

    может быть записан как:

    return $exec->execute(array_values($data));

  • Есть также специальный чехол для Update и delete, которые могут вернуть количество затронутых строк. Я бы решить это так:

    if($exec->execute($paramVal)){
    return $exec->rowCount();
    }
    else {
    return false;
    }

    Таким образом, вы можете проверить, если запрос не удалось с помощью !== или ===-операторов, например:

    $rowsDeleted = $yourpdo->queryDelete("posts", array("PostID" => 5));
    // $rowsDeleted might be 0 if the post with id "5" does not exist so
    // check with ===
    if($rowsDeleted === false) {
    echo "There was an error";
    } else {
    echo "{$rowsDeleted} rows affected";
    }

    Формулировки для вашей документации будет возвращает количество затронутых строк или false в случае ошибки.


2
ответ дан 9 октября 2011 в 09:10 Источник Поделиться