PHPDay0E:PDO操作数据库,单例模式

目录

0x00 PHP操作数据库的3种方式

0x01 PDO连接数据库

0x02 PDO的exec的使用

0x03 关于PDOStatment

0x04 关于PDO类中事务的使用

0x05 其他的两种连接操作

0x06 单例模式


0x00 PHP操作数据库的3种方式

1.PHP的MySQL扩展

存在很多安全问题,php5.5.0已经废弃,并在将来可能被移除

2.php的mysqli扩展

php的MySQL扩展的增强版

3.php数据对象(PDO:PHP DATA OBJECT)

PDO提供了一个统一的接口,可以让你不用管具体要连接的数据库类型,可以无缝切换数据库服务器

要使用PDO,要保证PDO的扩展已经打开了

0x01 PDO连接数据库

PDO类

PDOStatement类

PDOException 异常类

<?php
try{
    $db = new PDO($dsn,$username,$pwd);
}catch(PDOException $e){
    echo 'fail to connection:'.$e->getMessage();
}
?>
  1 <?php
  9 try{
 10         $db = new PDO('mysql:host=localhost;dbname=gaokao;port=3306;charset = utf8','root','root');
 11         echo '连接成功';
 12         //var_dump($db);
 13 }catch(PDOException $e){
 14         die('操作失败'.$e->getMessage());
 15 }
 17 ?>     

0x02 PDO的exec的使用

 <?php
 11 try{
 12         $db = new PDO('mysql:host=localhost;dbname=gaokao;p    ort=3306;charset = utf8','root','root');
 13         echo '连接成功';
 14         var_dump($db);
 15 }catch(PDOException $e){
 16         die('操作失败'.$e->getMessage());
 17 }
 18 $name = "梁朝伟";
 19 $pwd = md5('123');
 20 $sql = "INSERT INTO user (name,pwd)VALUES('$name','$pwd');";
 21 $ret = $db->exec($sql);
?>

其中$ret是语句影响的行数,不会返回select查询的结果;

那么查询数据库应该用什么呢?用prepare();

0x03 关于PDOStatment

1.prepare() 预处理

返回一个PDOStatement类的对象。

主要用来提高相同SQL模块查询性能,并且能防止SQL注入(推荐用这个)

使用方式1:

PDOStatement::bindParam(变量名,值) 绑定一个参数到指定的?占位符处。

PDOStatement::execute() 执行一条预处理语句。 返回值为是否执行成功。

<?php
    $stmt = $db->prepare('INSERT INTO user(name,pwd) VALUES(?,?)');
    $name = '刘玉玲';
    $pwd = md5('123');
    $stmt->bindParam(1,$name);
    $stmt->bindParam(2,$pwd);
    $ret = $stmt->execute();

?>

使用方式2:

<?php
    $stmt = $db->prepare('INSERT INTO user(name,pwd) VALUES(:u,:p)');
    $name = '刘玉玲';
    $pwd = md5('123');
    $stmt->bindParam(:u,$name);
    $stmt->bindParam(:p,$pwd);
    $ret = $stmt->execute();

?>

使用方式3:推荐

<?php
    $stmt = $db->prepare('INSERT INTO user(name,pwd) VALUES(:u,:p)');
    $name = '刘玉玲';
    $pwd = md5('123');
    $data = [':u'=>$name,':p'=>$pwd];
    $ret = $stmt->execute($data);
    echo $db->lastInsertId();

?>

PDO::lastInsertId() 当sql语句执行插入操作后,通过该函数可以获得插入的Id

查询数据

通过PDOStatement::fetchAll()可以返回所有查询结果。默认既返回关联数组又返回索引数组

PDOStatement::fetchAll(PDO::FETCH_ASSOC) 只返回关联数组

PDOStatement::fetchAll(PDO::FETCH_NUM) 只返回索引数组

PDOStatement::fetch()只返回查询结果的中一条。默认返回关联数组和索引数组

PDOStatement::rowCount() 返回查询结果的行数

PDOStatement::errorInfo() 返回SQL语句的错误信息,是一个数组

PDOStatement::errorCode 返回错误码

$sql="SELECT * FROM user";
$stmt = $db->prepare($sql);
$ret = $stmt->execute();
echo '<pre/>';
var_dump($stmt->fetchAll());
echo '<pre/>';
echo stmt->rowCount();
print_r(stmt->errorInfo());
echo stmt->errorCode();

0x04 关于PDO类中事务的使用

事务是指单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行

例如:进行转账操作就必须用事务来完成。A给B转账,要么执行成功,A的账户余额减少(执行减少的SQL语句成功)并且B的账户余额增加(执行增加的SQL语句也成功)。

要么执行失败,A的账户余额不减少,B的账户余额也不增加。

必须是InnoDB的数据库引擎

流程:

<?php
try{
    $db = new PDO('mysql:host=localhost;dbname=gaokao;charset=utf8','root','root');
}catch(PDOException $e){
    die('连接失败:'.$e->getMessage());
}
//1.开启异常
$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
try{
    //2.开启事务
    $db->beginTransaction();
    $from = $db->exec('UPDATE user SET fee = fee-500 WHERE id =1');
    $to = $db->exec('UPDATE user SET fee = fee+500 WHERE id = 2');
    //3.如果上面两句都没有问题,就不会抛出异常,那么就提交。即让两句都真正生效
    $db->commit()
}catch(PDOException $e){
        //3.如果其中一句执行的有问题,那么就回滚。即让已经生效的生效的语句不要生效
       $db->rollback();
       echo $e->getMessage();
}

?>

0x05 其他的两种连接操作

mysql的扩展连接操作;

5.6之后已经废弃

<?php
//1.连接数据库
$conn = mysql_connect($host,$username,$pwd) or die('连接失败');
//2.选择某个数据库
mysql_select_db($dbname,$conn);
//3.执行sql语句
$result = mysql_query("select * from xxx表");
//4.提取数据
$row = mysql_fetch_row($result);
var_dump($row);
?>

mysqli的扩展连接,对象的形式

<?php
$db = new mysqli($host,$username,$pwd);
$result = $db->query('SELECT * FROM user');
$row = $result->fetch_row();
var_dump($row);
?>

0x06 单例模式

所谓单例模式,就是某个类在实例化的过程中只有一个实例,在数据库连接中使用单例模式实例化数据库连接对象,可以避免重复的实例化对象而造成的资源浪费。

实现单例模式的三个条件:

1.需要一个保存类的唯一实例的静态成员变量 属性为私有

2.构造函数和克隆函数必须声明为私有的,防止外部程序new类从而失去单例模式的意义。并且防止外部克隆

3.必须提供一个访问这个实例的public 静态方法(通常为getInstance方法),从而返回唯一实例的一个引用。

为什么要静态成员变量和静态成员函数,因为他们不需要实例化就可以访问。

三私一公

<?php
class Db{
	//存储类的唯一的实例化对象
	private static $instance;
	//禁止外部new类
	private function __construct(){}
	//禁止外部克隆对象。
	private function __clone(){}
	//对外访问的方法 实现类的实例
	public static function getInstance(){
	//判断是否有实例化,如果没有实例化,就实例化
		if(!self::$instance instanceof Db){
			self::$instance = new self();//相当于new Db()
		}
		//已经实例化,直接返回实例化
		return self::$instance;
	}
}
$db1 = Db:getInstance();
$db2 = Db:getInstance();
$db3 = Db:getInstance();

?>
发布了156 篇原创文章 · 获赞 19 · 访问量 8942

猜你喜欢

转载自blog.csdn.net/weixin_43415644/article/details/104026027