php脚本链式操作

原生模拟链式操作,有些情况下做数据的时候,会发现用框架比较麻烦,原生sql连接也麻烦,所以搞了一份链式操作。

使用方法:php ./demo.php
贴代码
demo.php

<?php

	require "pdo.php";
	$host = "127.0.0.1";
	$dbname = "demo";
	$username = 'root';
	$password = 'root';
	$port = 3306;
	
	$conf['username'] = $username;
	$conf['password'] = $password;
	$conf['dsn'] = "mysql:dbname={$dbname};host={$host};port={$port}";
	
	$plat_db = new MyDb($conf);
	$sql = "SELECT * FROM _mytable LIMIT 1";
	$plat_info = $plat_db->findOne($sql);
	
	print_r($plat_info);

?>

pdo.php

<?php
	/**
	 * 数据库操作基类 基于pdo
	 * @author xuen
	 *    支持链式操作,支持参数绑定
	 * 说明1 只有在绑定了参数后,pdo才会自动处理单引号。
	 *  说明2 关闭连接时,要设置pdo null
	 *  说明3 在脚本处理完后,最好手动关闭连接。不然mysql并不一定会关闭连接。
	 *@example
	 *            $res=$db->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();    
	 */
	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 数组选项  
	     */
	    public   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);
	    }
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值