php pdo mysql数据库操作类

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 原文:php pdo mysql数据库操作类   findAll(array( 'field'=>'ID,albumName,albumImage, mainActor,directors,tags,info,area, keywords,wflag,year,mod_versi...

原文:php pdo mysql数据库操作类

 

findAll(array(
 'field'=>'ID,albumName,albumImage,
 mainActor,directors,tags,info,area,
 keywords,wflag,year,mod_version,totalDuration',
 'where'=>$where,
 'order'=>'flag desc,hit_count desc',
 'limit'=>"{$limit['offset']},{$limit['pagesize']}"
 ));
 $res=$db->field('ID,stitle,jisu,liuchang,gaoqing,chaoqing,
 totalDuration,bTime,eTime')
 ->where($where)
 ->limit("{$limit['offset']},{$limit['pagesize']}")
 ->findAll();
/
 final class MyDb
 {
 private $pdo;
 public $tableName;//表名
private $sql;//当前执行的SQL语句
public $error='';//当前执行sql的错误消息
public $prefix='';//前缀
public $charset='utf8';
 public $sqlQuery=array(
 'field'=>'',
 'where'=>'1',
 'join'=>'',
 'group'=>'',
 'having'=>'',
 'order'=>'',
 'limit'=>'',
 'union'=>'',
 'params'=>array()
 );
 public $fields=array();//得到当前表所有的字段名称

 

	private static $_instance=array();
	
	protected $dbName;
	
	//用户名
	protected $username;
	
	private $k;
	//密码
	protected $password;
	
	//主机名
	protected $host;
	
	//端口号
	protected $port;
	
	//一个时间戳,表示当前链接在什么时候过期,过期后,将重建一个对象。
	protected $expireTime;
	
	//PDO链接属性数组
	protected $attr=array(
	    //这个超时参数,实际上mysql服务器上的配置为准的。这里用于什么时候重建对象
	    //说明如是设置了这个参数,如果不显式的将pdo设为null,可能造成连接资源在mysql上不被释放。
	    \PDO::ATTR_TIMEOUT=>30,
	    \PDO::ATTR_ERRMODE=>\PDO::ERRMODE_SILENT,
	    \PDO::ATTR_ORACLE_NULLS=>\PDO::NULL_NATURAL,
        //如果设置了这个参数为true,inndob,需要手动commit
	    //\PDO::ATTR_AUTOCOMMIT=>false,
	    \PDO::ATTR_DEFAULT_FETCH_MODE=>\PDO::FETCH_ASSOC,
	    \PDO::ATTR_PERSISTENT=>FALSE
	);
	
	/**
	 * 构造方法
	 * @param array $config 配置文件
	 * @param array $attr 数组选项  
	 */
	private  function __construct($config,$attr)
	{
	    //索引数组合并不能使用merge
	    foreach ($this->attr as $key=>$row)
	    {
	    	if(isset($attr[$key]))
	    	    $this->attr[$key]=$attr[$key];
	    }
		$this->pdo=new \PDO($config['dsn'], $config['username'], 
		    $config['password'],$this->attr);
		
		if(isset($config['prefix']) && $config['prefix']!='')
			$this->prefix=$config['prefix'];
		if(isset($config['charset']) && $config['charset']!='')
			$this->charset=$config['charset'];
		$this->pdo->exec("set names {$this->charset}");
		
		//保存当前数据库名称,主机,端口。
		preg_match('/dbname=(\w+)/', $config['dsn'],$ma);
		preg_match('/host=(.*?);/', $config['dsn'],$ma1);
		preg_match('/port=(\w+)/', $config['dsn'],$ma2);
		$this->dbName=$ma[1];
		$this->host=$ma1[1];
		$this->port=$ma2[1]?$ma2[1]:3306;
	
		$this->username=$config['username'];
		$this->password=$config['password'];
		
		//设置链接过期时间
		$timeout=$this->attr[\PDO::ATTR_TIMEOUT];
		$this->expireTime=time()+$timeout;
	}
	
	private function __clone(){}

    /**
     * @param $config
     * @param array $attr
     * @return \iphp\core\MyDb
     */
    static public function  getInstance($config,$attr=array())
	{
	    if(!is_array($config))
	    	$config=App::getApp()->getConfig($config);
	    $k=md5(implode('', $config));	   
	     
	    //如果连接没有创建,或者连接已经失效
		if( !(static::$_instance[$k] instanceof self))
		{
		    static::$_instance[$k]=new self($config,$attr);	
		    static::$_instance[$k]->k=$k;
		}
		//如果连接超时。
        elseif(time()>static::$_instance[$k]->expireTime)
        {
            static::$_instance[$k]->close();
            static::$_instance[$k]=new self($config,$attr);
            static::$_instance[$k]->k=$k;
        }		
		return static::$_instance[$k];
	}
	/**
	 * 
	 * @param unknown_type $tableName
	 * @return $this
	 */
	public function tableName($tableName)
	{
		$this->tableName=$this->prefix.$tableName;
		//$this->setField();
		return $this;
	}

    /**
     * @return \PDO
     */
    public function getPdo()
	{
		return $this->pdo;
	}
	/**
	 * 得到当前sql语句,并完成参数替换
	 * @return string
	 */
	public function getSql()
	{
		return $this->sql;
	}

    /**
     * @param string $sql
     * @return bool
     */
    public function findAll($sql='')
	{
		$stmt=$this->query($sql);
		if(!$stmt)
			return false;
		return $stmt->fetchAll();
	}

    /**
     * @param string $sql
     * @return bool
     */
    public function findOne($sql='')
	{
		$this->sqlQuery['limit']=1;
		$stmt=$this->query($sql);
		if($stmt===false)
			return false;
		return $stmt->fetch();
	}
	/**
	 * 根据主键查找记录
	 * @param mixed $ids 
	 * @return 返回一维或二维数组
	 */
	public function find($ids)
	{
		$num=count(explode(',', $ids));
		$this->setField();
		if($num==1)
		{
			$res= $this->where("{$this->fields[$this->tableName]['pk']}='{$ids}'")
			->findOne();
		}
		else
		{
			//如果是字符串主键,要加引号
			$tmp=explode(',', $ids);
			$tmp=array_map(function($item){
				return "'".$item."'";
			}, $tmp);
			$ids=implode(',', $tmp);
			$res= $this->where("{$this->fields[$this->tableName]['pk']} in ({$ids})")
			->findAll();
		}
		return $res;
	}

	/**
	 * 插入数据的方法,自动完成参数绑定
	 * @param  array $data 一维数组 array(Field=>value)
	 * @return boolean | int
	 */
	public function insert($data)
	{
		$this->setField();
		$params=array();
		$field=array();
		$placeholder=array();
		foreach($data as $key=>$row)
		{
			//删除非法字段信息
			if(!in_array($key, $this->fields[$this->tableName]))
				continue;
			$params[':'.$key]=$row;
			$field[]=$key;
			$placeholder[]=':'.$key;
		}
		//插入当前记录
		$sql="insert into {$this->tableName} (".implode(', ', $field).') values ('.
			implode(', ', $placeholder).')';
		$this->sqlQuery['params']=$params;
		$this->sql=$sql;
		return $this->exec($sql,$this->sqlQuery['params']);
	}
	/**
	 * 删除记录
	 * @param string $where where条件
	 * @param array $params 绑定参数
     * @return bool
	 */
	public function delete($where = '',$params = array())
	{
		if($where!='')
			$this->sqlQuery['where']=$where;
		if($params!='')
			$this->sqlQuery['params']=$params;
		$sql="delete from {$this->tableName} where {$this->sqlQuery['where']}";
		$this->sql=$sql;
		return $this->exec($sql,$this->sqlQuery['params']);
	}

	/**
	 * 简化的delete()方法,基于主键的删除
	 */
	public function del($ids)
	{
		$this->setField();
		$tmp=explode(',', $ids);
		$tmp=array_map(function($item){
			return "'".$item."'";
		}, $tmp);
		$ids=implode(',', $tmp);
		$sql="delete from {$this->tableName} where {$this->fields[$this->tableName]['pk']}".
		" in ($ids)";
		$this->sql=$sql;
		return $this->exec($sql);
	}

	/**
	 * 得到插入的最后ID号
	 */
	public function lastId()
	{
		return $this->pdo->lastInsertId();
	}

	/**
	 * 修改数据 update 支持参数绑定 只支持where参数
	 * @param array $data 要改变的列的值数组 array(列名=>值)
	 * @param  string $where where条件
	 * @param  array $params 绑定参数
	 * @return boolean | int 受影响的行数
 	 */
	public function update($data,$where='',$params= array())
	{
		$this->setField();
		if(!is_array($data))
			return false;
		if($where!='')
			$this->sqlQuery['where']=$where;
		if($params!='')
			$this->sqlQuery['params']=$params;
		$updateField=array();
		foreach($data as $key=>$value)
		{
			//不合法的字段不要
			if(!in_array($key, $this->fields[$this->tableName]))
				continue;
			$updateField[]="{$key}=:{$key}";
			$this->sqlQuery['params'][":{$key}"]=$value;
		}
		$sql="update {$this->tableName} set ".implode(',', $updateField)
			." where {$this->sqlQuery['where']}";
		$this->sql=$sql;
		return $this->exec($sql,$this->sqlQuery['params']);
	}

	/**
	 * 得到数据表的所有字段信息
	 */
	public function setField()
	{
		if(is_array($this->fields[$this->tableName]))
			return;
		$sql="desc {$this->tableName} ";
		$res=$this->findAll($sql);
		foreach ($res as $row)
		{
			if($row['Key']=='PRI')
				$this->fields[$this->tableName]['pk']=$row['Field'];
			$this->fields[$this->tableName][]=$row['Field'];
		}
	}

	//得到当前操作表的字段信息
	public function getField()
	{
	    if(!$this->fields[$this->tableName])
	        $this->setField();
		return $this->fields[$this->tableName];
	}

	//得到记录总数
	public function count($sql='')
	{
		$this->sqlQuery['field']='count(*) as c';
		$stmt=$this->query($sql);
		if(!$stmt)
			return false;
		$res=$stmt->fetch();
		//执行完之后要重置查询字段
		return $res['c'];
	}

	//得到sql执行错误
	public function getError()
	{
		return $this->error;
	}

	public function setError($error)
	{
		$this->error=$error;
	}

	/**
	 * 扫行有结果集的查询,支持参数绑定
	 * 如果你需要遍历数据库,请使用query方法,然后foreach 返回的stmt对象便可。
	 * @param mixed $sql 
	 * @return boolean|PDOStatement
	 */
	public function query($sql='')
	{
		$sql=$this->joinSql($sql);
		$stmt=$this->pdo->prepare($sql);
		$errorInfo=$stmt->errorInfo();
		$stmt->setFetchMode(\PDO::FETCH_ASSOC);
		$stmt->execute($this->sqlQuery['params']);
		//清除sql条件值,desc类部执行的sql语句,不用清楚缓存
		if(strpos($sql,'desc')!==0)
			$this->clearSqlQuery();
		$errorInfo=$stmt->errorInfo();
		if($errorInfo[0]!='00000')
		{
			$this->setError($errorInfo[2]);
			return false;
		}
		return $stmt;
	}

	/**
	 * 执行没有结果集的查询,支持参数绑定
	 * @param string $sql
	 * @param array $params
	 * @return 返回受影响行数或false
	 */
	public function exec($sql,$params = array())
	{
		$stmt=$this->pdo->prepare($sql);
		if($params!='')
			$this->sqlQuery['params']=$params;
		$stmt->execute($this->sqlQuery['params']);
		$this->clearSqlQuery();
		$errorInfo=$stmt->errorInfo();
		if($errorInfo[0]!='00000')
		{
			$this->setError($errorInfo[2]);
			return false;
		}
		return $stmt->rowCount();
	}

	//设定绑定参数
	public function params($params)
	{
		$this->sqlQuery['params']=empty($params)?'':$params;
		return $this;
	}

    /**
     * 自动绑定参数
     * @param $params
     * @return $this
     */
    public function autoParams($params)
    {
        $this->setField();
        foreach ($params as $key => $row) {
            if(in_array($key, $this->fields[$this->tableName])) {
                $this->sqlQuery['params'][":{$key}"] = $row;
            }
        }
        return $this;
    }

	/**
	 * 组合sql语句
	 * @param mixed $sql
	 * @return 返回组合的sql语句
	 */
	public function joinSql($sql)
	{
		if(is_string($sql) && $sql!='')
		{
			$this->sql=$sql;
			return $sql;
		}
		elseif(is_array($sql) && $sql!='')
		{
			foreach ($sql as $key=>$row)
			{
				if(!array_key_exists($key, $this->sqlQuery))
					continue;
				$this->sqlQuery[$key]=$row;
			}
		}
		else {}
		$this->sql="select {$this->sqlQuery['field']} from {$this->tableName}\n";
		if($this->sqlQuery['join']!='')
			$this->sql.="{$this->sqlQuery['join']} ";
		$this->sql.="where {$this->sqlQuery['where']}\n";
		if($this->sqlQuery['group']!='')
			$this->sql.="group by {$this->sqlQuery['group']}\n";
		if($this->sqlQuery['having']!='')
			$this->sql.="having {$this->sqlQuery['having']}\n";
		if($this->sqlQuery['order']!='')
			$this->sql.="order by {$this->sqlQuery['order']}\n";
		if($this->sqlQuery['limit']!='')
			$this->sql.="limit {$this->sqlQuery['limit']}\n";
		if($this->sqlQuery['union']!='')
			$this->sql.="union {$this->sqlQuery['union']}\n";
		return $this->sql;
	}

	//设定字段的方法
	public function field($field)
	{
		$this->sqlQuery['field']=empty($field)?'*':$field;
		return $this;
	}

	/**
	 * 
	 * @param unknown_type $where
	 * @return \iphp\core\MyDb
	 */
	public function where($where)
	{
		$this->sqlQuery['where']=empty($where)?'1':$where;
		return $this;
	}

    /**
     * @param $tableName
     * @param $condition
     * @return $this
     */
    public function join($tableName,$condition)
	{
		$this->sqlQuery['join'].="join {$tableName} on {$condition}\n";
		return $this;
	}

    /**
     * @param $tableName
     * @param $condition
     * @return $this
     */
    public function leftjoin($tableName,$condition)
	{
		$this->sqlQuery['join'].="left join {$tableName} on {$condition}\n";
		return $this;
	}

    /**
     * @param $tableName
     * @param $condition
     * @return $this
     */
    public function rightjoin($tableName,$condition)
	{
		$this->sqlQuery['join'].="right join {$tableName} on {$condition}\n";
		return $this;
	}

    /**
     * @param $group
     * @return $this
     */
    public function group($group)
	{
		$this->sqlQuery['group']=empty($group)?'':$group;
		return $this;
	}

    /**
     * @param $having
     * @return $this
     */
    public function having($having)
	{
		$this->sqlQuery['having']=empty($having)?'':$having;
		return $this;
	}

    /**
     * @param $order
     * @return $this
     */
    public function order($order)
	{
		$this->sqlQuery['order']=empty($order)?'':$order;
		return $this;
	}

    /**
     * @param $limit
     * @return $this
     */
    public function limit($limit)
	{
		$this->sqlQuery['limit']=empty($limit)?'':$limit;
		return $this;
	}

    /**
     * @param $union
     * @return $this
     */
    public function union($union)
	{
		$this->sqlQuery['union']=empty($union)?'':$union;
		return $this;
	}

	/**
	 * 清除sql缓存
	 */
	public function clearSqlQuery()
	{
		//清除缓存前,先保存当前sql语句。
		if(!empty($this->sqlQuery['params']))
		{
			foreach ($this->sqlQuery['params'] as $key=>$param)
				$this->sql=str_replace($key, '"'.$param.'"', $this->sql);
		}
		$this->sql=nl2br($this->sql);
		foreach ($this->sqlQuery as $key=>$row)
		{
			if($key=='where')
				$this->sqlQuery[$key]='1';
			elseif ($key=='field')
				$this->sqlQuery[$key]='*';
			elseif ($key=='params')
				$this->sqlQuery[$key]=array();
			else 
				$this->sqlQuery[$key]='';
		}
	}

	//再执行findone findall方法之前,得到当前要执行的sql语句,
	public function getSqlCache()
	{
		$sql=$this->joinSql('');
		if(!empty($this->sqlQuery['params']))
		{
			foreach ($this->sqlQuery['params'] as $key=>$param)
				$sql=str_replace($key, '"'.$param.'"', $sql);
		}
		return $sql;
	}
	
	/**
	 * 得到当前数据库名称
	 */
	public function getDbName()
	{
		return $this->dbName;
	}
	
	/**
	 * 得到用户名
	 */
	public function getUser()
	{
		return $this->username;
	}
	
	/**
	 * 得到密码
	 */
	public function getPass()
	{
		return $this->password;
	}
	
	public function  getHost()
	{
		return $this->host;
	}
	
	public function getPort()
	{
		return $this->port;
	}
	
	/**
	 * 得到连接相关的详细信息。
	 */
	public function getConnInfo()
	{
		return array(
		    'host'=>$this->host,
		    'port'=>$this->port,
		    'username'=>$this->username,
		    'password'=>$this->password,
		    'dbname'=>$this->dbName,
		);
	}

    /**
     * 开启事务,并设置错误模式为异常
     * 使用try cacth 来回滚或提交
     * beginTransaction()方法将会关闭自动提交(autocommit)模式,
     * 直到事务提交或者回滚以后才能恢复为pdo设置的模式
     */
    public function beginTransaction()
    {
        $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
        return $this->pdo->beginTransaction();
    }

    /**
     * 提交
     * @return bool
     */
    public function commit()
    {
        return $this->pdo->commit();
    }

    /**
     * 回滚事务
     * @return bool
     */
    public function rollBack()
    {
        return $this->pdo->rollBack();
    }

	/**
	 * 关闭连接
	 */
	public function close()
	{
		$this->pdo=null;
	}
	
	/**
	 * 关闭所有连接
	 */
	public static function closeAll()
	{
		foreach(static::$_instance as $o)
		{
		    if($o instanceof self)
		        $o->close();
		}
	}
	
	/**
	 * 得到当前表的下一次自增长ID
	 */
	public function getNextAutoIncrement($tableName)
	{
	    $sql="show table status where name ='{$tableName}'";
	    $res=$this->findOne($sql);
	    return $res['Auto_increment'];
	    
	}


    /**
     * 为一个表增加一个TIMESTAMP字段
     * @param $tableName 表名
     * @param $name 字段名
     * @return bool|int
     */
    public function addTIMESTAMP($tableName,$name='utime')
    {
        $addSql="alter table {$tableName} add {$name} TIMESTAMP
                 NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;";
        $addSql.="ALTER TABLE {$tableName} ADD index {$name}($name)";

        return $this->exec($addSql);
    }
}
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
28天前
|
SQL 缓存 PHP
PHP技术探究:优化数据库查询效率的实用方法
本文将深入探讨PHP中优化数据库查询效率的实用方法,包括索引优化、SQL语句优化以及缓存机制的应用。通过合理的优化策略和技巧,可以显著提升系统性能,提高用户体验,是PHP开发者不容忽视的重要议题。
|
1月前
|
SQL 关系型数据库 MySQL
Python怎么操作Mysql数据库
Python怎么操作Mysql数据库
49 0
|
1月前
|
SQL 关系型数据库 MySQL
python如何操作mysql数据库
python如何操作mysql数据库
24 0
|
1月前
|
Java 程序员 PHP
PHP对象和类
PHP对象和类
19 0
|
2月前
|
SQL 存储 算法
mysql常用指令操作
mysql常用指令操作
|
16天前
|
存储 SQL 关系型数据库
【MySQL】4. 表的操作
【MySQL】4. 表的操作
19 0
|
24天前
Mybatis+mysql动态分页查询数据案例——条件类(HouseCondition)
Mybatis+mysql动态分页查询数据案例——条件类(HouseCondition)
14 1
|
29天前
|
SQL 关系型数据库 MySQL
|
2月前
|
存储 关系型数据库 MySQL
MySQL技能完整学习列表5、数据库操作——1、创建数据库和表——2、修改表结构(ALTER TABLE)
MySQL技能完整学习列表5、数据库操作——1、创建数据库和表——2、修改表结构(ALTER TABLE)
183 0
|
14天前
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)