0%

PHP PDO操作数据库

虽然php不同spring,但还是应该尽量采用MVC的思想。

新建连接数据库的配置文件

1
2
3
4
5
6
7
8
9
// conf.php
return array(
'host'=>'localhost',
'user'=>'root',
'password'=>'',//因为测试,我就不设置密码,实际开发中,必须建立新的用户并设置密码
'dbName'=>'phpProject',
'charSet'=>'utf8',
'port'=>'3306'
);

新建获取pdo数据库连接对象的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
// Connection.php
$dbConf=include 'conf.php';

Class Connection{
private static $pdo;
/**
* 获取实例化的PDO,单例模式
* @return PDO
*/
public static function getInstance($dbConf){
if(!(self::$pdo instanceof PDO)){
$dsn ="mysql:host=".$dbConf['host'].";port=".$dbConf['port'].
";dbname=".$dbConf['dbName'].";charset=".$dbConf['charSet'];
try {
self::$pdo = new PDO($dsn,$dbConf['user'], $dbConf['password'], array(PDO::ATTR_PERSISTENT => true,PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); //保持长连接
self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
} catch (PDOException $e) {
print "Error:".$e->getMessage()."<br/>";
die();
}
}
return self::$pdo;
}
}

前端登录页面 Model

1
2
3
4
5
6
7
8
9
10
<!-- login.php -->
<form action="../../Controllers/LoginController.php" method="post">
用户名:<input type="text" name="username">
密码:<input type="password" name="password">
<button type="submit">登录</button>
<a href="../registed/registed.php">去注册</a>
<span style="color: red;">
<?php echo isset($_REQUEST['status'])?'用户名或密码错误':''; ?>
</span>
</form>

页面控制层 Controller

1
2
3
4
5
6
// LoginController.php
// 在获取前台表单数据并使用之前,需要先用isset()判断是否存在,不然如果别的地方请求到这个php文件,就会报错。
if(isset($_POST['username'])&&isset($_POST['password'])){
$user = new User($_POST['username'],$_POST['password']);
check($user);
}

业务逻辑层 Service

查询数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
// LoginService.php
include("../Connection/Connection.php");
$dbConf=include '../Connection/conf.php';
$pdo=Connection::getInstance($dbConf);

function check($user){
// 若需要读取session中的数据,则需在前面调用 session_start();
session_start();
// 若要在方法体内使用全局变量,需要在方法体内用 global 声明
global $pdo;
// 密码使用md5()加密后再存储进数据库。
$password = md5($user->getPassword());

$sql='SELECT * from User WHERE username=? and password=?';

$stmt = $pdo->prepare($sql);

$stmt->bindValue(1,$user->getUsername());
$stmt->bindValue(2,$password);

// 执行一条预处理语句 .成功时返回 TRUE, 失败时返回 FALSE
$stmt->execute();
// $rows = $stmt->fetchAll(); 取出所有的结果集
// print_r($rows);
if($stmt->rowCount()>0){
$row = $stmt->fetch();
// 将用户信息存入session。
$_SESSION['username']=$row['username'];
$_SESSION['id']=$row['id'];
$_REQUEST['error'] = '用户名或或者密码错误';

// 请求重定向
header("location: ../views/activity/activity.php");
}else{
// 请求重定向
header("location: ../views/login/login.php?status=0");
}
}

插入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
function addUser($user){
global $pdo;
$sql='SELECT * from User WHERE username=?';

$stmt = $pdo->prepare($sql);

$stmt->bindValue(1,$user->getUsername());
// 执行一条预处理语句 .成功时返回 TRUE, 失败时返回 FALSE
$stmt->execute();
if($stmt->rowCount()>0){
echo '此用户已存在';
}else{
$password = md5($user->getPassword());
// 开始事务处理
$pdo->beginTransaction();
try{
$sql = 'insert into USER(username,password) VALUES (:username,:password)';
$sth = $pdo->prepare($sql);
$sth->bindParam(':username', $user->getUsername());
$sth->bindParam(':password', $password);
$sth->execute();
// 提交事务
$pdo->commit();
echo '成功注册';
header("location: ../views/login/login.php");
}catch(PDOException $e){
$pdo->rollBack();
throw $e;
}
}
}

如果要执行多次查询,Prepare比query快多了

不管是在查询还是插入和更新中,我们都必须要防止sql注入攻击。在使用PDO操作数据库时,可以完全使用Prepare和Execute方法来避免sql注入攻击,但是使用query方法时,需要手动对接收到的字符串转义。可以通过quote方法转义字符串,具体为:

1
$sql="select * from User where username = "'.$pdo->quote($username).'" ";
-------------本文结束 感谢您的阅读-------------