小言_互联网的博客

【PHP 面向对象】面向对象(OOP)编程之PDO对象操作数据库知识点归纳总结(五)

173人阅读  评论(0)

PDO 是什么

PDO 是 PHP Date Object(PHP 数据对象)的简称,它是 PHP 为访问数据库定义的一个轻量级的、一致性的接口,它提供了一个数据访问抽象层,这样无论你使用什么数据库,都可以通过同一函数执行查询和获取数据,大大简化了数据库的操作,并能够屏蔽不同数据库之间的差异。

PDO 是与 PHP5.1 版本一起发行的,使用 PDO 可以很方便地进行跨数据库程序的开发,以及不同数据库间的移植,目前 PDO 支持的数据库包括 Firebird、FreeTDS、Interbase、MySQL、SQL Server、ODBC、Oracle、Postgre SQL、SQLite 和 Sybase 等。

PDO 的特点

我们可以将 PDO 看作是一个“数据库访问抽象层”,作用是统一各种数据库的访问接口。与 MySQL 和 MSSQL 函数库相比,PDO 让跨数据库的使用更具有亲和力,与 ADODB 和 MDB2 相比,PDO 更加高效。

PDO 将通过一种轻型、清晰、方便的函数,统一各种不同的数据库的共有特性,实现 PHP 脚本在最大程度上的抽象性和兼容性。

PDO 吸取了现有数据库扩展成功和失败的经验教训,利用 PHP5 的最新特性,可以轻松地与各种数据库进行交互。

PDO 扩展是模块化的,能够在运行时为用户数据库后端加载驱动程序,而不必重新编译或重新安装整个 PHP 程序。例如,PDO_MySQL 扩展会替代 PDO 扩展实现 MySQL 数据库 API,它还有一些用于 Oracle、Postgre SQL、ODBC 和 Firebird 的驱动程序。

开启 PDO扩展

默认情况下,PDO 在 PHP 中为开启状态,但是要启用对某个数据库驱动程序的支持,仍需要进行相应的配置操作。

以 Windows 系统下为例,在配置文件 php.ini 中有关 PDO 相关的配置信息如下所示:

;extension=pdo_firebird
;extension=php_pdo_mysql.dll
;extension=pdo_oci
;extension=pdo_odbc
;extension=pdo_pgsql
;extension=pdo_sqlite

提示:开启相应的配置只需要去除配置项前面的分号;,然后重启 Apache 服务器即可。

验证相关的配置是否开启成功,只需要执行 phpinfo() 函数就行,在输出的页面中搜索配置的名称,如果存在则说明开启成功

使用PDO连接数据库

在使用 PDO 与不同数据库之间交互时,PDO 对象中的成员方法是统一各种数据库的访问接口,所以在使用 PDO 与数据库交互之前,首先要创建一个 PDO 对象,然后再通过对象的构造函数来连接数据库。

new PDO(string $dsn[, string $username [, string $password [, array $driver_options]]]);

参数说明如下:

  • $dsn:数据源名称或叫做 DSN(Data Source Name 的缩写),包含了请求连接到数据库的信息。通常一个 DSN 是由 PDO 驱动程序的名称,紧随其后是一个冒号,再后面是可选的驱动程序的数据库连接信息,比如主机名、端口和数据库名。以 MySQL 数据库为例 $dsn 可以定义为:mysql:host=localhost;port=3306;dbname=dbname;charset=utf8,分别定义了数据库类型、端口号、数据库名和字符集;
  • $username:可选参数,用来表示 DSN 字符串中的用户名;
  • $password:可选参数,用来表示 DSN 字符串中的密码;
  • $driver_options:可选参数,一个具体驱动的连接选项的键/值数组。

PHP 数据对象:https://www.php.net/manual/zh/book.pdo.php

预定义常量:https://www.php.net/manual/zh/pdo.constants.php

创建 PDO 对象

$pdo = new PDO($dsn, $user, $pwd); 参数:dsn,数据库用户名,数据库密码

<?php
    $type = 'mysql';     //数据库类型
    $host = 'localhost'; //数据库主机名
    $dbname = 'test';    //使用的数据库名称
    $username = 'root';  //数据库连接用户名
    $username  = 'root'; //数据库连接密码
    $dsn="$type:host=$host;dbname=$dbname";
	 try{
   
        // 可选,设置错误提示级别为WARNING
        $params = array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING);
         //初始化一个PDO对象
        $pdo= new PDO($dsn,$user,$pwd,$params);
         # 设置结果集的默认获取的方式 (默认索引数组和关联数组)
   		$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);
    }catch(Exception $e){
   
        die('数据库连接失败:'.$e -> getMessage());
    }
?>

使用PDO执行SQL语句

在 PDO 中,我们可以使用三种方式来执行 SQL 语句,分别是 exec() 方法,query() 方法,以及预处理语句 prepare() 和 execute() 方法。

执行sql语句: exec() 、query()、 perpare();

1、query用来处理有结果集的,如select, 返回 PDOStatement 对象,失败返回false(当为 PDO::ERRMODE_SILENT,这也是默认的值)

2、exec用来处理有返回影响行数的(int),如 insert(插入的行数)、 delete(删除的行数) 、update(和原数值不等才算), 失败返回false (当为 PDO::ERRMODE_SILENT,这也是默认的值)

3、prepare 执行所有sql,可以完全替代 query,exec的功能,并且可以防止SQL注入

错误报告是针对执行的sql出错时

PDO::ERRMODE_SILENT(0) :默认 不提示任何错误 ,连接时无论如何都会提示,只有在执行后面的方法时才会起作用
PDO::ERRMODE_WARNING(1) : 警告
PDO::ERRMODE_EXCEPTION(2):异常(推荐使用) 用try catch捕获,也可以手动抛出异常 new PDOException($message, $code, $previous)

1) exec() 方法

当执行 INSERT、UPDATE 和 DELETE 等不需要返回结果集的 SQL 语句时,可以使用 PDO 对象中的 exec() 方法。该方法成功执行后,将返回受影响的行数

主要思路:
(1)连接数据库、数据库的用户名、数据库的密码
(2)生成PDO对象
(3)执行查询

<?php
    # $stmt = $pdo->exec($sql); 执行SQL增删改语句,返回值是false或 受影响的整型数量
    $dsn  = 'mysql:host=localhost;dbname=users;';
    $username = 'root';
    $password  = 'root';
	// 生成PDO对象  
	$pdo = new PDO($dsn,$user,$pwd);
	$sql = "insert into user(name,age,sex) values('zhang','18','男')";
    $res = $pdo -> exec($sql);
    if($res) echo '成功添加 '.$res.' 条数据!';
?>
# exec用法
try {
   
    $sql = "insert into users (`user_name`, `user_pwd`) values('zhang', '123'),('admin', 'admin')";
    $rows = $pdo->exec($sql);  // 影响的条数 2
    $id = $pdo->lastInsertId(); //最后插入的id,有多条时返回的是第一条的id
} catch (Exception $e) {
   
   echo $pdo->errorInfo();
}

注释:exec主要用于执行没有返回结果集的操作,比如insert、delete、update,返回的是影响的记录条数

2) query() 方法

当执行需要返回结果集的 SELECT 查询语句时,可以使用 PDO 对象中的 query() 方法。如果该方法执行成功,则会返回一个 PDOStatement 对象。如果使用了query() 方法,并想了解获取的数据行总数,可以使用 PDOStatement 对象中的 rowCount() 方法获取。

PDO::query(string $sql)
# 执行SQL查询语句,返回值是false或 PDOStatement 类型的对象
$stmt = $pdo->query($sql); 
# 读取结果中的数量
echo $stmt->rowCount();
# 返回结果集第一条数据
$stmt->fetch(PDO::FETCH_ASSOC);
# 返回结果集全部数据
$stmt->fetchAll(PDO::FETCH_ASSOC);
# 直给pdo对象全局设置返回类型
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);

通过设置第二个参数可以调整返回值的样式:

  • PDO::FETCH_BOTH 关联+索引数组(默认值)
  • PDO::FETCH_ASSOC 关联数组
  • PDO::FETCH_NUM 索引数组
  • PDO::FETCH_OBJ 对象类型
<?php  
	$dsn  = 'mysql:host=127.0.0.1;dbname=mydb';
    $user = 'root';
    $pwd  = 'root';
    $pdo = new PDO($dsn,$user,$pwd);
    $sql = "SELECT * FROM users ";
    // 获取PDOStatement对象
    $stmt = $pdo -> query($sql,PDO::FETCH_ASSOC);
    echo "<pre>";
    print_r($stmt);
    // 获取结果集全部数据
    print_r($stmt->fetchAll());
    
?>

设置结果集参数也可以通过fetch和fetchAll()传入

<?php  
	$sql = "SELECT * FROM users ";
    // 获取PDOStatement对象
    $stmt = $pdo -> query($sql);
    // 获取结果集中第一条数据 返回关联数组
	$res = $stmt->fetchAll(PDO::FETCH_ASSOC);
	echo "<pre>";
    print_r($res);
?>

为了避免每次获取结果集都反复的设置参数, setAttribute()方法是设置部分属性我们可以直接在连接数据库时给pdo对象统一的来设置

<?php  
	$dsn  = 'mysql:host=127.0.0.1;dbname=mydb';
    $user = 'root';
    $pwd  = 'root';
    $pdo = new PDO($dsn,$user,$pwd);
    # 设置结果集的默认获取的方式 (默认索引数组和关联数组)
   	$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);
    $sql = "SELECT * FROM users ";
    // 获取PDOStatement对象
    $stmt = $pdo -> query($sql);
    // 获取结果集中第一条数据 返回关联数组
	$res = $stmt->fetchAll();
	echo "<pre>";
    print_r($res);
    
?>

使用 query() 和 exec() 方法有以下几点需要注意:

  • query() 和 exec() 都可以执行所有的 SQL 语句,只是返回值不同而已;
  • query() 可以实现所有 exec() 的功能;
  • 当把 select 语句应用到 exec() 时,总是返回 0;
  • 如果要看查询的具体结果,可以通过 foreach 语句完成循环输出。

3) 预处理语句方式

当同一个查询需要多次执行时(有时需要迭代传入不同的条件参数),使用预处理语句的方式来实现效率会更高。使用预处理语句就需要使用 PDO 对象中的 prepare() 方法去准备一个将要执行的查询,再使用 PDOStatement 对象中的 execute() 方法来执行。


$stmt = $pdo -> prepare($sql);
$stmt -> execute([参数1,参数2]);

$args = $stmt->fetchAll(参数):读取查询结果数组

$arg = $stmt->fetch(参数):读取一条查询结果数组,参数同上

$obj = $stmt->fetchObject():直接读取一条结果为对象类型
    
$pdo->errorInfo():读取错误信息,返回值是数组类型

SQL 语句模板中可以包含零个或多个参数占位标记,格式可以是命名(:name)或问号(?)的形式,当它执行时将用真实数据取代。在同一个 SQL 语句里,命名和问号形式不能同时使用,只能选择其中一种参数形式。如果使用命名形式的占位标记,那么标记的命名必须是唯一的。使用预处理语句可以有效的避免传统的方式中SQL注入问题

使用命名形式的参数占位符,查询指定的 SQL 语句

<?php  
	#无序方式 命名占位符
    $dsn  = 'mysql:host=127.0.0.1;dbname=mydb';
    $user = 'root';
    $pwd  = 'root';

    $pdo = new PDO($dsn,$user,$pwd);
    $sql = "SELECT user_name,user_email FROM users WHERE user_sex = :sex";
    $sth = $pdo -> prepare($sql);

    $sth -> execute([':sex'=>0]);
    $res = $sth -> fetchAll();
	echo '<pre>';
    print_r($res);
    
?>

使用问号形式的参数占位符,查询指定的 SQL 语句

<?php
     #有序方式 问号占位符
    $dsn  = 'mysql:host=127.0.0.1;dbname=mydb';
    $user = 'root';
    $pwd  = 'root';

    $pdo = new PDO($dsn,$user,$pwd);
    $sql = "SELECT user_name,user_email FROM users WHERE user_sex= ?";
    
    $sth = $pdo -> prepare($sql);
    $sth -> execute([0]);
    $res = $sth -> fetchAll(PDO::FETCH_ASSOC);
    echo '<pre>';
    print_r($res);
   
?>

使用PDOStatement::bindParam() 提前引用绑定参数,而不是执行的时候绑定参数。

// 连接数据库
$dsn = "mysql:host=127.0.0.1;port=3306;dbname=mydb";
$opts = array(PDO::ATTR_AUTOCOMMIT=>0, PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION, PDO::ATTR_AUTOCOMMIT=>0);
try {
   
    $pdo = new PDO($dsn, 'root', 'root', $opts);
}catch(PDOException $e){
   
    echo $e->getMessage();
}


/* pdo中有两种占位符号
 *
*  ? 参数占位符            --- 索引数组, 按索引顺序使用
*  命名参数占位符           ----关联数组, 按名称使用,和顺序无关
*/


//准备好了一条语句,并入到服务器端,也已经编译过来了,就差为它分配数据过来
//同样适用于更新操作

// 命名参数占位符
$stmt=$pdo->prepare("insert into users (`user_name`, `user_pwd`,'user_email','create_time') values(:name,:pwd,:email,:time)");

//绑定参数,引用方式传递
$stmt->bindParam(":name", $name);
$stmt->bindParam(":pwd", $pwd);
$stmt->bindParam(":email", $email);
$stmt->bindParam(":time", $time);

#变量放到 bindParam 前后都可
$name="zhang";
$pwd = '1234';
$email = 'zhang@qq.com';
$time = time();


// 问号参数占位符
$stmt=$pdo->prepare("insert into users (`user_name`, `user_pwd`,'user_email','create_time') values(?,?,?,?)");
//绑定参数,引用方式传递
$stmt->bindParam(1, $name, PDO::PARAM_STR); #起始值为 1 
$stmt->bindParam(2, $pwd, PDO::PARAM_STR);
$stmt->bindParam(3, $email, PDO::PARAM_INT);
$stmt->bindParam(4, $time, PDO::PARAM_INT);

// 执行预处理语句
if($stmt->execute()){
   
    echo "执行成功";
    echo "最后插入的ID:".$pdo->lastInsertId();
}else{
   
    echo "执行失败!";
}
  • PDO类 数据库连接有关(连接、执行sql)
    • PDO::prepare — 准备要执行的语句,并返回语句对象
    • PDO::query — 执行 SQL 语句,以 PDOStatement 对象形式返回结果集
  • PDOStatement 处理结果集 ( p d o − > q u e r y ( ) 和 pdo->query()和 pdo>query()pdo->prepare()可以返回PDOStatement)
  • PDOException 异常处理类

https://www.php.net/manual/zh/class.pdostatement.php

总结:

1、query和exec都可以执行所有的sql语句,只是返回值不同而已。

2、query可以实现所有exec的功能。

3、当把select语句应用到 exec 时,总是返回 0

预处理语句(prepare)示例,sql只编译一次,执行相同的sql效率会高。单个相比exec,query效率也高。

注意:批量插入时,依次插入当遇到错误时后面的插入失败,但是前面的会插入成功。

pdo 预处理中 bindParam() 和 bindValue() 的不同之处:

  • PDOStatement::bindParam — 绑定一个参数到指定的变量名

  • PDOStatement::bindValue — 把一个值绑定到一个参数

  • 区别就是前者使用一个php变量绑定参数,而后者使用一个值。说白了一个是变量,一个是固定值

所以使用bindParam是第二个参数只能用变量名,而不能用变量值,而bindValue至可以使用具体值。

$stm = $pdo->prepare("select * from users where user = :user");  
$user = "jack";  
//正确  
$stm->bindParam(":user",$user);  
//错误  
//$stm->bindParam(":user","jack");  
//正确  
$stm->bindValue(":user",$user);  
//正确  
$stm->bindValue(":user","jack");  


// 另外在存储过程中,bindParam可以绑定为input/output变量,如下面
$stm = $pdo->prepare("call func(:param1)");  
$param1 = "abcd";  
$stm->bindParam(":param1",$param1); //正确  
$stm->execute(); 

存储过程执行过后的结果可以直接反应到变量上。

对于那些内存中的大数据块参数,处于性能的考虑,应优先使用前者


下面来演示一下SQL注入:

<?php  
	$dsn  = 'mysql:host=127.0.0.1;dbname=mydb';
    $user = 'root';
    $pwd  = 'root';
    $pdo = new PDO($dsn,$user,$pwd);
    # 设置结果集的默认获取的方式 (默认索引数组和关联数组)
   	$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);
   	// 模拟用户输入的用户名和密码
   	$name = "' or 1=1 # ";
   	$pwd = '1234';
    $sql = "select user_name,user_pwd from users where user_name = '{
     $name}' and user_pwd = '{
     $pwd}'";
    // 获取PDOStatement对象
    $stmt = $pdo -> query($sql);
    echo "<pre>";
    print_r($stmt);
    // 获取结果集中第一条数据 返回关联数组
	$res = $stmt->fetchAll();
    print_r($res);
    
?>

生成的sql语句是这样的,存在严重问题

select user_name,user_pwd from users where user_name='zhang' and user_pwd='1234';

# 但用户如果输入的用户名是 ' or 1=1 # 
select user_name,user_pwd from users where user_name='' or 1=1 #' and user_pwd='1234';

下面我们用预处理语句方式来查询看一下生成的SQL语句和执行结果

<?php  
	$dsn  = 'mysql:host=127.0.0.1;dbname=mydb';
    $user = 'root';
    $pwd  = 'root';
    $pdo = new PDO($dsn,$user,$pwd);
    # 设置结果集的默认获取的方式 (默认索引数组和关联数组)
   	$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);
   	// 模拟用户输入的用户名和密码
   	$name = "' or 1=1 # ";
   	$pwd = '1234';
    $sql = "select user_name,user_pwd from users where user_name=? and user_pwd=?";
    $stmt = $pdo -> prepare($sql);
	$stmt->execute([$name,$pwd]);
    echo "<pre>";
    print_r($stmt);
	$res = $stmt->fetchAll();
    print_r($res);
    
?>

PDO预处理能防止sql注入的原因:

1、先看预处理的语法

#无序方式 命名占位符预处理
$pdo->prepare('select user_name from users where user_name=:user_name');
$pdo->execute([':user_name'=>'admin']);
 #有序方式 问号占位符预处理
$pdo->prepare('select user_name from users where user_name=?');
$pdo->execute(['admin']);
  • prepare 服务器发送一条sql给mysql服务器,mysql服务器会解析这条sql。

  • execute 服务器发送一条sql给mysql服务器,mysql服务器不会解析这条sql,只会把execute的参数当做纯参数赋值给语句一。哪怕参数中有sql命令也不会被执行,从而实现防治sql注入。

实战:完善登录注册功能

文件夹基本结构如下:

common.php

<?php  
/**
 * 公共模型文件
 */

// 连接数据库服务
require "../../config/connect.php";

function checkName($uname){
   
	global $pdo;
	// 默认数据库中用户名不存在同名
	$isOccupied = false;
	// 编写查询用户名SQL语句
	$sql = "select user_name from users where user_name='{
     $uname}'";
	// 返回 pdo Statement对象
	$stmt =  $pdo->query($sql);
	// 以关联数组方式返回结果集
	$res = $stmt->fetchAll(PDO::FETCH_ASSOC);
	// 如果不想每次获取时都设置返回方式,也可以直接给pdo对象设置返回类型
	// $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);
	if($res){
   
		$isOccupied = true;
	}
	return $isOccupied;
}

function insertData(Array $user){
   
	global $pdo;
	// 获取当前时间戳
	$create_time = time();
	// 将密码进行加密处理
	$password = password_hash($user['pwd'],PASSWORD_BCRYPT);
		// 准备插入的sql语句
	$sql  = "insert into users (user_name,user_pwd,create_time,user_email) values ('{
     $user['userName']}','{
     $password}',{
     $create_time},'{
     $user['email']}')";
	// 执行插入SQL语句
	$count = $pdo->exec($sql);
	return $count;
}
?>

regist_check.php

<?php  
// 导入公共函数库
require "./common.php";
// 接受用户登陆时提交的验证码
session_start();
// 接收PSOT传递过来的数据
$user = $_POST;
// 非表单提交访问页面给予提醒
if(empty($user)) die('请勿非法访问!!!');
// 判断请求的类型
if(isset($_POST['type']) && $_POST['type']==1 ){
   
	if(!empty($_POST["uname"])){
   
		// 调用函数判断用户名是否被占用
		$res = checkName($_POST["uname"]);
		if($res){
   
			echo json_encode(['status'=>0,'msg'=>'该用户名已被占用']);
		}else{
   
			echo json_encode(['status'=>1,'msg'=>'该用户名合法']);
		}
	}
}else if(isset($_POST['type']) && $_POST['type']==2 ){
   
	if(!empty($_POST["captcha"])){
   
	    if(strtolower($_SESSION["captcha"]) === strtolower($_POST["captcha"])){
   
	        echo json_encode(['status'=>1,'msg'=>'验证码正确']);
	    }else{
   
	        echo json_encode(['status'=>0,'msg'=>'验证码不正确']);
	    }
	}
}else{
   
	if(strlen($user['userName'])<4 || !preg_match("/^[A-Za-z]/i",$user['userName']) ){
   
		echo json_encode(['status'=>0,'msg'=>'用户名长度需不小于四位且以字母开头']);
	}else if(strcmp($user['pwd'],$user['cpwd'])!== 0){
   
		echo json_encode(['status'=>0,'msg'=>'两次密码输入不一致']);
	}else if(strcasecmp($_SESSION["captcha"],$user["captcha"])!== 0){
   
		echo json_encode(['status'=>0,'msg'=>'验证码不正确']);
	}else if(checkName($user['userName'])){
   
		echo json_encode(['status'=>0,'msg'=>'请勿重复多次提交']);
	}else{
   
		// 调用添加数据函数 返回受影响行数
		$count= insertData($user);
		if($count):
			echo json_encode(['status'=>1,'msg'=>'注册成功,请稍后……']);
		else:
			echo json_encode(['status'=>0,'msg'=>'注册失败~~~']);
		endif;
	}
}


?>

login_check.php

<?php  
// 连接数据库服务
require "./../config/connect.php";
// 接受用户登陆时提交的验证码
session_start();
if(empty($_POST)) die("请勿非法访问");
$username = $_POST['userName'];
$password = $_POST['pwd'];
$captcha = $_POST['captcha'];
// 预处理SQL模板
$sql = "select user_name,user_pwd from users where user_name = ?";
// prepare()方法-准备一条预处理语句 返回 pdo statement对象
$stmt = $pdo->prepare($sql);
// 绑定参数到指定的变量名
$stmt->bindParam(1,$username,PDO::PARAM_STR);
// 执行预处理SQL
$stmt->execute();
// 获取结果集
$res = $stmt->fetch();
// 判断查询出的数据条数
if($stmt->rowCount()==0){
   
	echo json_encode(['status'=>0,'msg'=>'该用户未注册……']); 
}else if(!password_verify($password,$res['user_pwd'])){
   
	echo json_encode(['status'=>0,'msg'=>'用户名或密码不正确']); 
}else if(strcasecmp($_SESSION["captcha"],$captcha)!== 0){
   
	echo json_encode(['status'=>0,'msg'=>'验证码错误……']); 
}else{
   
	echo json_encode(['status'=>1,'msg'=>'登录成功……']); 
}
?>

database.php

<?php
namespace pdo_edu;
return [
    'type'=> $type ?? 'mysql',
    'host'=> $host ?? 'localhost',
    'dbname'=> $dbname ?? 'mydb',
    'username'=> $username ?? 'root',
    'password'=> $password ?? 'root',
    'charset'=> $charset ?? 'utf8mb4',
    'port'=> $port ?? '3306'
];


connect.php

<?php  
namespace pdo_connect;
// 数据库配置信息
$config = require __DIR__."./database.php";
extract($config);

$dsn = sprintf("%s:host=%s;dbname=%s",$type,$host,$dbname);
try{
   
	// 可选,设置错误提示级别为WARNING
    $params = [\PDO::ATTR_ERRMODE=>\PDO::ERRMODE_WARNING];
	$pdo = new \PDO($dsn,$username,$password,$params);
}catch(Exception $e){
   
    die('数据库连接失败:'.$e -> getMessage());
}
?>

浏览效果:



浏览链接:

  • 登录:http://www.zhsh520.com/admin/login/login.html

  • 注册:http://www.zhsh520.com/admin/regist/regist.html


转载:https://blog.csdn.net/weixin_43958049/article/details/116759167
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场