php pdo mysql数据库操作类

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: 原文: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);
    }
}
相关实践学习
自建数据库迁移到云数据库
本场景将引导您将网站的自建数据库平滑迁移至云数据库RDS。通过使用RDS,您可以获得稳定、可靠和安全的企业级数据库服务,可以更加专注于发展核心业务,无需过多担心数据库的管理和维护。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
数据库连接 应用服务中间件 PHP
|
存储 SQL 关系型数据库
PHP与数据库交互:从基础到进阶
【10月更文挑战第9天】在编程的世界里,数据是流动的血液,而数据库则是存储这些珍贵资源的心脏。PHP作为一门流行的服务器端脚本语言,其与数据库的交互能力至关重要。本文将带你从PHP与数据库的基本连接开始,逐步深入到复杂查询的编写和优化,以及如何使用PHP处理数据库结果。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供宝贵的知识和技巧,让你在PHP和数据库交互的道路上更加从容不迫。
|
SQL 数据库连接 Linux
数据库编程:在PHP环境下使用SQL Server的方法。
看看你吧,就像一个调皮的小丑鱼在一片广阔的数据库海洋中游弋,一路上吞下大小数据如同海中的珍珠。不管有多少难关,只要记住这个流程,剩下的就只是探索未知的乐趣,沉浸在这个充满挑战的数据库海洋中。
390 16
|
Ubuntu PHP 数据库
|
SQL PHP 数据库
19 PHP如何利用PDO获取结果集
路老师在知乎上分享了关于PHP语言的知识,帮助大家入门并深入了解PHP。本文介绍了PDO中获取结果集的三种方法:`fetch()`、`fetchAll()` 和 `fetchColumn()`,并通过具体案例展示了如何使用这些方法从数据库中获取数据并展示在网页上。
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP开发领域,设计模式是解决常见问题的高效方案集合。它们不是具体的代码,而是一种编码和设计经验的总结。单例模式作为设计模式中的一种,确保了一个类仅有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的基本概念、实现方式及其在PHP中的应用。
单例模式在PHP中的应用广泛,尤其在处理数据库连接、日志记录等场景时,能显著提高资源利用率和执行效率。本文从单例模式的定义出发,详细解释了其在PHP中的不同实现方法,并探讨了使用单例模式的优势与注意事项。通过对示例代码的分析,读者将能够理解如何在PHP项目中有效应用单例模式。
|
PHP
PHP中的面向对象编程:理解类与对象
本文将深入探讨PHP中面向对象编程的核心概念——类与对象。通过实例讲解,帮助读者更好地理解如何在PHP中运用OOP编写更高效、可维护的代码。
200 9
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
279 2
|
SQL 关系型数据库 数据库连接
php连接数据库之PDO,PDO的简单使用和预定义占位符的使用以及PDOStatement对象的使用,占位符的不同形式,bindValue和bindParam绑定预定义占位符参数的区别
本文介绍了PHP中PDO(PHP Data Objects)扩展的基本概念和使用方法。内容包括PDO类和PDOStatement类的介绍,PDO的简单使用,预定义占位符的使用方法,以及PDOStatement对象的使用。文章还讨论了绑定预定义占位符参数的不同形式,即bindValue和bindParam的区别。通过具体示例,展示了如何使用PDO进行数据库连接、数据查询、数据插入等操作。
php连接数据库之PDO,PDO的简单使用和预定义占位符的使用以及PDOStatement对象的使用,占位符的不同形式,bindValue和bindParam绑定预定义占位符参数的区别
|
7月前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
484 158

热门文章

最新文章

推荐镜像

更多