封装MySQL的单例,连接数据库并对数据进行增删改查操作
单例:
一个类只能有一个对象
应用场景:多次请求数据库只需要一个连接对象。
实现:三私一公
1、私有的静态属性用来保存对象的单例
2、私有的构造方法用来阻止在类的外部实例化
3、私有的__clone阻止在类的外部clone对象
4、公有的静态方法用来获取对象的单例
实现封装MySQL单例的思路:
第一步:实现单例
第二步:初始化参数
第三步:连接数据库
第四步:操作数据
1、执行数据操作语句(增、删、改)
2、执行数据查询语句
a) 返回二维数组
b) 返回一维数组
c)返回一行一列
代码的实现:
<?php class MySQLDB { private static $instance;//私有的静态属性用来保存对象的单例 private $host; private $port; private $user; private $pwd; private $charset; private $link; private $dbname;
//私有的构造方法用来阻止在类的外部实例化 private function __construct($param){ $this->initData($param); $this->connectDB(); } //私有的__clone阻止在类的外部clone对象 private function __clone(){ } //获取单例,公有的静态方法用来获取对象的单例 static function getInstance($param){ if(!self::$instance instanceof self){ self::$instance = new self($param); } return self::$instance; } //初始化参数 private function initData($param = array()){ $this->host = $param['host']??'127.0.0.1'; $this->port = $param['port']??'3306'; $this->user = $param['user']??''; $this->pwd = $param['pwd']??''; $this->dbname = $param['dbname']??''; $this->charset = $param['charset']??'utf8'; } //连接数据库 private function connectDB(){ $this->link =@mysqli_connect($this->host,$this->user,$this->pwd,$this->dbname); if(!$this->link){ echo '连接数据库失败'; echo '错误:'.mysqli_connect_error,'<br>'; echo '错误码:'.mysqli_connect_errno,'<br>'; exit; } mysqli_set_charset($this->link,$this->charset); } //执行数据库的增、删、改、查语句 private function executeSQL($sql){ $rs = mysqli_query($this->link,$sql); if(!$rs){ echo '执行sql语句失败'; echo '错误:'.mysqli_error($this->link); echo '错误码:'.mysqli_errno($this->link); exit; } return $rs; } //执行增、删、改 并返回执行结果(true 或 false) function executeZSG($sql){ if(in_array(substr($sql,0,6),array('delete','update','insert'))){ return $this->executeSQL($sql); }else{ echo '非法访问<br>'; exit; } } //获取自动增长的编号 function getIncrement(){ return mysqli_insert_id($this->link); } //执行查询语句 private function query($sql){ if(substr($sql,0,4) == 'desc' || substr($sql,0,4) == 'show' || substr($sql,0,6) == 'select'){ return $this->executeSQL($sql); }else{ echo '非法访问<br>'; exit; } } // 执行查询语句,返回二维数组 function fetchAll($sql,$type='assoc'){ $rs = $this->query($sql); $type = $this->getType($type); return mysqli_fetch_all($rs,$type); } //匹配一维数组 function fetchRow($sql,$type='assoc'){ $list = $this->fetchAll($sql,$type); if(!empty($list)){ return $list[0]; } return array(); } //匹配一行一列 function fetchColumn($sql){ $list = $this->fetchAll($sql,'num'); if(!empty($list)){ return $list[0]; } return null; } //获取匹配类型 private function getType($type){ switch($type){ case 'num': return MYSQLI_NUM; case 'both': return MYSQLI_BOTH; default: return MYSQLI_ASSOC; } } } $param = array( 'user' => 'root', 'pwd' => 'root', 'dbname' => 'mycool' ); //获取单例 $db=MySQLDB::getInstance($param); // var_dump($db); //更新 // $db->executeZSG("update b set age=122 where id=11"); //插入 // if($db->executeZSG("insert into b values (null,55,66,22)")) // echo '编号是:'.$db->getIncrement(); // 删除 // if($db->executeZSG("delete from b where id=11")) // echo '删除成功'; //查询 // $list=$db->fetchAll('select * from b','assoc'); // var_dump($list); // $list=$db->fetchRow('select * from b where id=9','num'); // var_dump($list); // $list=$db->fetchColumn('select count(*) from b','assoc'); // var_dump($list);
小结一下:
1、instanceof 用来判断对象是否属于某个类
2、参数必须从外部传递到内部,不能写死到类的内部。
3、为了保证代码的可重用性,一个方法只实现一个功能,所以初始化参数和连接数据库分到两个方法中。