php PDO链接数据库(防止SQL注入)

class mysql_pdo
{

    var $db_connect_id;
    var $query_result;
    var $row = array();
    var $rowset = array();
    var $num_queries = 0;
    var $numRows =0;//插入,更新,删除后影响的行数
    var $lastInsID =0;//返回插入的ID;
    var $transTimes =0; //事务
    //
    // Constructor
    //
    function __construct($sqlserver, $sqluser, $sqlpassword, $database)
    {

        $this->user = $sqluser;
        $this->password = $sqlpassword;
        $this->server = $sqlserver;
        $this->dbname = $database;
          
       $dsn = "mysql:host={$this->server};dbname={$this->dbname};port=3306;charset=utf8";
       //DSN中指定charset的作用是什么? 只是告诉PDO, 本地驱动转义时使用指定的字符集(并不是设定mysql server通信字符集),设置mysql server通信字符集,还得使用set names <charset>指令
        try
        {
            
            $this->db_connect_id = new PDO($dsn, $this->user, $this->password,array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
            
            $this->db_connect_id->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            //ATTR_EMULATE_PREPARES 设置成false后会将 sql where 后的变量和 SQL模板是分两次发送给mysql服务器,再由mysql服务器完成拼接sql 这样避免sql注入。(sql注入原因主要是SQL语句由php完成拼接)
        }
        catch(Exception $e) 
        {  
           writelog($e->getMessage());
           exit();           
        }  
    }

    //
    // Other base methods
    //
    function sql_close()
    {
        if($this->db_connect_id)
        {
            if($this->query_result)
            {
                
                $this->query_result = NULL;
            }
            $this->db_connect_id = null;
            return true;
        }
        else
        {
            return false;
        }
    }

    //
    // Base query method
    //
     function sql_query($sql = "",$whereparam=NULL) 
     {
         
            $this->sql_freeresult();//查询前释放之前的结果集
            if ($sql != "") 
            {
                
                $this->query_result = $this->db_connect_id->prepare($sql);
                //var_dump($this->query_result);
                if($this->query_result===false)
                {
                    writelog("queryerro: ".$sql."\r\n"."param =".json_encode($whereparam));
                    $this->sql_error($sql);
                    return false;
                }
                $this->bindPdoParam($whereparam);
                $result = $this->query_result->execute();
                //echo $this->query_result->debugDumpParams();
            
                if ( false === $result) {
                    $this->sql_error($sql);
                    return false;
                }
            }        
            return false;
     }
     
     function sql_affectedrows()
     {
          if(!empty($this->query_result))
          {
            $this->numRows = $this->query_result->rowCount();
            return $this->numRows;
          }
          else
          {
            return -1;
          }
     }     
    //
    // Other query methods
    //
     private function bindPdoParam($whereparam=NULL)
    {
        // 参数绑定
        if($whereparam ==NULL)
        {
            return;
        }
           $i=0;
           for($i=0;$i<count($whereparam);$i++)//bindParam要求第二个参数是一个引用变量(reference),因此不能用foreach。好大一个坑
           {               
            $returnval= $this->query_result->bindParam($i+1,$whereparam[$i]);                      
           }
    }
    

    function sql_fetchrow($sql,$whereparam=NULL)
    {
        
        $this->sql_query($sql,$whereparam);
        $row = $this->query_result->fetch(\PDO::FETCH_ASSOC);
        return $row;
    }
    function sql_fetchrowset($sql,$whereparam=NULL)
    {
    
        $this->sql_query($sql,$whereparam);
        $rowset = $this->query_result->fetchAll(\PDO::FETCH_ASSOC);
        //var_dump($rowset);
        //die();
        $this->numRows = count( $rowset );
        return $rowset;
    }
    
    
    
    function sql_freeresult()
    {    
      if(!empty($this->query_result))
      {          
          $this->query_result = null;
      }
    }
    
      //启动事务
    public function startTrans() {
        if ( !$this->db_connect_id ) return false;
        if ($this->transTimes == 0) 
        {
            $this->db_connect_id->beginTransaction();
        }
       echo  $this->transTimes++;
        return ;
    }

    //提交事务
    public function commit() 
    {
        if ($this->transTimes > 0) 
        {echo  $this->transTimes ;
            $result = $this->db_connect_id->commit();
           echo  $this->transTimes = 0;
            if(!$result)
            {
                $this->sql_error();
                return false;
            }
        }
        return true;
    }

    // 事务回滚

    public function rollback() 
    {
        if ($this->transTimes > 0) 
        {
            $result = $this->db_connect_id->rollback();
           $this->transTimes = 0;
            if(!$result)
            {
                $this->sql_error();
                return false;
            }
        }
        return true;
    }
    
    //获取插入数据的最后的id
     public function getLastInsertId()
    {  
        return $this->db_connect_id->lastInsertId();          
    }

    function sql_error($sql)
    {
        $error = $this->db_connect_id->errorInfo();
        writelog("SQL : ".$sql."\r\nERROR : ".json_encode($error));
        return ;
    }
   function __destruct() 
   {
     
       $this->sql_close();   
   }

//日志函数

function writelog($logMessage,$destination='') {
        $now = date('Y-m-d H:i:s');
        $log_file_size = '2097152';//日志文件大小
        if(empty($destination))
            $destination = 'logs/'.'luckdraw_'.date('y_m_d').'.log';
        //检测日志文件大小,超过配置大小则备份日志文件重新生成
        if(is_file($destination) && $log_file_size <= filesize($destination) )
              rename($destination,dirname($destination).'/'.time().'-'.basename($destination));
        error_log("[{$now}] ".$_SERVER['REMOTE_ADDR'].' '.$_SERVER['REQUEST_URI']."\r\n{$logMessage}\r\n", 3,$destination);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值