主要内容:
- mysqli的加载及验证
- 围绕一个登陆页面进行mysqli的增删改查
- prepare预处理机制防止sql注入
- 登录
1. mysqli的加载及验证
- 建立连接
<?php
/*检测mysqli扩展有没有加载成功
1. phpinfo();
2. var_dump(get_loaded_extensions());
3. function_exists('mysqli_connect')
*/
//建立到mysql的连接 ,并且打开指定到数据库
$mysqli = @new mysqli('localhost','root','zhoujielun521','apple');
//分别为地址,登陆账号,登陆密码,数据库名(注意这里不是table名)
// print_r($mysqli);
if ($mysqli->connect_errno) {
//获取上次mysql操作受影响的函数
die("CONNECT_ERROR:". $mysqli->connect_error);
}
// echo $mysqli->client_info;
echo $mysqli->server_info;
2.insert增加操作
- demo3.php中主要内容
<?php
//1.建立到mysql的连接 ,并且打开指定到数据库
$mysqli = @new mysqli('localhost','root','zhoujielun521','apple');
// print_r($mysqli);
if ($mysqli->connect_errno) {
//获取上次mysql操作受影响的函数
die("CONNECT_ERROR:". $mysqli->connect_error);
}
// 2. mysqli::set_charset()设置默认的客户端字符集
$mysqli->set_charset('utf-8');
//3.sql查询,$mysqli->query()只能执行单条查询
//多条命令的时候,可以用.=来继续写。
$sql = "INSERT INTO user(`username`,`password`) VALUES('Chloe1','Chloe1'),('Chloe2','Chloe2'),('Chloe3','Chloe3')";
$res = $mysqli->query($sql);
if ($res) {
echo "恭喜您注册成功,您是本站的第". $mysqli->insert_id . "位用户<br>";
} else{
//error返回最近一次错误代码的描述
echo "ERROR:" .$mysqli->errno.":".$mysqli->error;
}
3.delete删除和更新操作
- demo4中内容
<?php
//1.建立到mysql的连接 ,并且打开指定到数据库
$mysqli = @new mysqli('localhost','root','zhoujielun521','apple');
// print_r($mysqli);
if ($mysqli->connect_errno) {
//获取上次mysql操作受影响的函数
die("CONNECT_ERROR:". $mysqli->connect_error);
}
// 2. mysqli::set_charset()设置默认的客户端字符集
$mysqli->set_charset('utf-8');
// 3.sql查询,$mysqli->query()只能执行单条查询
// 更新数据记录
$sql = "UPDATE `user` SET `age`=18";
$res = $mysqli->query($sql);
if ($res) {
//$mysqli::affected_rows获取上次mysql操作受影响的行数
echo $mysqli->affected_rows."条记录受影响<br>";
}else{
echo "ERROR:" .$mysqli->errno.":".$mysqli->error;
}
//删除数据
$sql = "DELETE FROM `user` WHERE `id`>=19 ";
$res = $mysqli->query($sql);
if ($res) {
//$mysqli::affected_rows获取上次mysql操作受影响的行数
echo $mysqli->affected_rows."条记录受影响<br>";
}else{
echo "ERROR:" .$mysqli->errno.":".$mysqli->error;
}
//mysqli::close()关闭先前打开的数据库连接
$mysqli->close();
4. select查询操作
- demo2.php中内容
<?php
//1.建立到mysql的连接 ,并且打开指定到数据库
$mysqli = @new mysqli('localhost','root','zhoujielun521','apple');
// print_r($mysqli);
if ($mysqli->connect_errno) {
//获取上次mysql操作受影响的函数
die("CONNECT_ERROR:". $mysqli->connect_error);
}
// 2. mysqli::set_charset()设置默认的客户端字符集
$mysqli->set_charset('utf-8');
// 3.sql查询,$mysqli->query()只能执行单条查询
//select查询
//失败时返回 FALSE, 通过mysqli_query() 成功执行SELECT, SHOW, DESCRIBE或 EXPLAIN查询会返回一个mysqli_result 对象,其他查询则返回TRUE。
$sql = "SELECT `username`,`password` FROM `user`";
//
$res = $mysqli->query($sql);
//mysqli_result::fetch_all()抓取所有的结果行并且以关联数据,数值索引数组,或者两者皆有的方式返回结果集。
$a = $res->fetch_all(MYSQLI_BOTH);
print_r($a);
5. prepare预处理机制
<?php
//mysqli预处理机制 防止sql注入
//1.建立到mysql的连接 ,并且打开指定到数据库
$mysqli = @new mysqli('localhost','root','zhoujielun521','apple');
// print_r($mysqli);
if ($mysqli->connect_errno) {
//获取上次mysql操作受影响的函数
die("CONNECT_ERROR:". $mysqli->connect_error);
}
// 2. mysqli::set_charset()设置默认的客户端字符集
$mysqli->set_charset('utf-8');
//mysqli_stmt类的对象可以定义和执行参数化的SQL命令,即预处理(Prepared Statement)的机制。
//使用问号参数占位符来构成预处理sql语句
$sql = "INSERT INTO `user`(`username`,`password`,`age`)VALUES(?,?,?)";
//mysqli::prepare()准备(prepare)需要执行的 SQL 语句
//mysqli_prepare() 返回一个 statement 对象,如果发生错误则返回 FALSE。
$stmt = $mysqli->prepare($sql);
//mysqli_stmt::bind_param()绑定变量参数到 prepared 语句
// s i d->double
$username = 'php.cn';
$password = md5('php.cn');
$age = 12;
//
$stmt->bind_param('ssi',$username,$password,$age);
//执行预处理语句
//mysqli_stmt::execute()执行 prepared 查询
$res = $stmt->execute();
// var_dump($res);
if ($res) {
//返回上次查询中所自动生成的 ID
echo $stmt->insert_id;
}
6. 登陆表单:防止SQL注入
- 先是形成一个login.php表单
<!DOCTYPE html>
<html>
<head>
<title>用户登录</title>
</head>
<body>
<h2>用户登录</h2>
<form action="enter.php" method="post">
<table>
<tr>
<td>用户名</td>
<td>
<input type="text" name="username">
</td>
</tr>
<tr>
<td>密码</td>
<td>
<input type="password" name="password">
</td>
</tr>
<tr align="center">
<td colspan="2">
<input style=" border:red;background: red" type="submit" name="sub">
</td>
</tr>
</table>
</form>
</body>
</html>
- 不安全的验证enter.php文件,直接用sql语句查询并返回。有可能会返回所有的值,并进行删除
<?php
//数据接受
$username = $_POST['username'];
$password = $_POST['password'];
//mysqli预处理机制 防止sql注入
//1.建立到mysql的连接 ,并且打开指定到数据库
$mysqli = @new mysqli('localhost','root','zhoujielun521','apple');
// print_r($mysqli);
if ($mysqli->connect_errno) {
//获取上次mysql操作受影响的函数
die("CONNECT_ERROR:". $mysqli->connect_error);
}
// 2. mysqli::set_charset()设置默认的客户端字符集
$mysqli->set_charset('utf-8');
//mysqli_stmt类的对象可以定义和执行参数化的SQL命令,即预处理(Prepared Statement)的机制。
//使用问号参数占位符来构成预处理sql语句
//字符串中可以适用{}来将变量直接引入,这样php引擎是可以解析的。
$sql = "SELECT * FROM `user` WHERE `username`='{$username}' AND `password`='{$password}'";
echo $sql;
/*这种情况如果username输入' or 1=1 #,密码随便输入就可以拿到所有的数据。原因是这个意思是:username为空或1=1,这样就变成了一个永远正确的判断。而#在sql语句中将后面所有的都变成注释了。不发挥作用了 */
die;
$res = $mysqli->query($sql);
//num_rows返回语句结果集中的行数
var_dump($res->num_rows);
具体展示出来的sql语句见下图:
- 下面使用?占位符及stmt来进行,更安全
<?php
//数据接收
$username = $_POST['username'];
$password = $_POST['password'];
//mysqli预处理机制 防止sql注入
//1.建立到mysql的连接 ,并且打开指定到数据库
$mysqli = @new mysqli('localhost','liang','622788','liangtest');
// print_r($mysqli);
if ($mysqli->connect_errno) {
//获取上次mysql操作受影响的函数
die("CONNECT_ERROR:". $mysqli->connect_error);
}
// 2. mysqli::set_charset()设置默认的客户端字符集
$mysqli->set_charset('utf-8');
//mysqli_stmt类的对象可以定义和执行参数化的SQL命令,即预处理(Prepared Statement)的机制。
//使用问号参数占位符来构成预处理sql语句
$sql = "SELECT * FROM `my_user` WHERE `username`=? AND `password`=?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('ss',$username, $password);
$stmt->execute();
//mysqli_stmt::get_result()获取 prepared 语句中的结果。
$res = $stmt->get_result();
print_r($res);
//最后这几个也是值得琢磨的一些方法。后面再去琢磨。
//htmlspecialchars();
//trim();
//strip_tags();
7. 实战部分
- 使用mysqli类的对象去连接数据库,然后获取到mysqli_result对象,使用mysqli _result对象中的成员方法或者属性将获得的结果集中的数据(二维数组)遍历出来
- 连接部分后面用pdo实现了。遍历的方法有固定的一些种,后面会整理。下面列一个
foreach ($res as $key => $value) {
foreach ($value as $k => $v) {
printf('<pre>%s</pre>',print_r($v,true));
//从大的res到value,再从value推进到v。
}
}
echo '<hr><br>';