PHP前置基础

变量

变量的简介

变量是一个可以改变的量

变量可以理解为是一个房间(仓库),而房间(仓库)是用于存放东西的,而变量也是。

变量的命名规范

  • 必须以 $ 开始,后面跟英文字母

  • 变量名的名称严格区分大小写

  • 变量名不能以数字开头,但是可以包含数字

  • 变量名可以是中文,但是不推荐这样使用

  • 变量的名字要有意义,比如 $name , $age , $addr

  • 要按照公司的命名规范去来。

变量的命名规则

  • 我们在定义变量的时候,尽量做到见名知意
  • 尽量使用驼峰命名法
    • 小驼峰命名法: 变量名的第二个单词大写,其余小写,例如: $myName (推荐)
    • 大驼峰命名法: 变量名的每个单词的首字母大写,其余小写,例如: $MyName
  • 在声明变量的时候,等号两边加上空格,例如 $name = 'x1ong';

单双引号的区别

  • 双引号可以解析变量,但是单引号不行。
1
2
3
4
5
<?php 
$name = 'x1ong';
echo '$name'; // $name;
echo "$name"; // x1ong
?>
  • 双引号执行转义,但是单引号不转义
1
2
3
4
<?php 
echo '\n'; // 输出字符串\n
echo "\n"; // 换行
?>
  • 单双引号都识别转义字符 \
1
2
3
4
5
6
<?php 
# \ 的作用在于将特殊字符转为普通字符
echo '\\'; // 输出 /
echo '\''; // 输出 '
echo "\""; // 输出 "
?>
  • 如果想让字符串和变量或其他字符连接在一起的话,需要使用 . 进行连接。
1
2
3
4
5
<?php 
$name = 'x1ong';
echo 'my name is ' . $name . "\n"; // my name is x1ong
echo $name . 666; // x1ong666
?>
  • 如果在双引号里面使用变量的时候,建议将变量名使用 {} 包裹
1
2
3
4
<?php 
$name = 'x1ong';
echo "{$name}"; // x1ong
?>

常见数据类型

  • 整数类型 (int)
1
2
3
4
5
6
7
8
<?php 
$int1 = 123;
$int2 = 456;
$int3 = 789;
var_dump($int1); // int(123)
var_dump($int2); // int(456)
var_dump($int3); // int(789)
?>
  • 浮点类型 ( float )
1
2
3
4
<?php  
$float1 = 3.14;
var_dump($float1); // double(3.14)
?>
  • 布尔类型 ( boolean )
1
2
3
4
5
6
<?php 
$bool1 = true;
var_dump($bool1); // bool(true)
$bool1 = false;
var_dump($bool1); // bool(true)
?>
  • 字符串类型 ( string )
1
2
3
4
5
6
7
8
<?php 
// 通过双引号或单引号包裹起来的都是字符串类型
$str1 = 'helloworld';
var_dump($str1); // string(10) "helloworld"

$str2 = "你好世界";
var_dump($str2); // string(12) "你好世界"
?>
  • 数组类型 ( array )
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
// 数组中可以是任意类型,我们将数组中的每个值,称之为元素

// 索引数组
$arr = array(1,3.14,'hello',true);
var_dump($arr);

// 关联数组
$arr2 = [
'name' => 'x1ong',
'age' => 17,
'addr' => 'henan'
];
var_dump($arr2);

// 同时也可以使用[] 定义一个数组
// 索引数组
$arr3 = [1,3,'hello',true,3.14];
var_dump($arr3);

// 关联数组
$arr4 = [
'name' => 'x1ong',
'age' => '8'
];
var_dump($arr4);
?>

数组类型转换

简介

​ 数组类型转换指的是将一个数据类型转为另一个数组类型。比如 int 类型转为 string 类型。

类型转换相关函数

  • intval() 获取变量的整数值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php 
$number1 = '123';
var_dump(intval($number1)); // int(123)

$number2 = '123abc';
var_dump(intval($number2)); // int(123)

$number3 = 'abc123';
var_dump(intval($number3)); // int(0)

$number4 = true;
var_dump(intval(number4)); // int(0)
$number5 = false;
var_dump(intval(number5)); // int(0)

$number6 = '3.14';
var_dump(intval($number6)); // int(3)

?>
  • floatval() 获取变量的浮点数值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php 
$number1 = '123';
var_dump(floatval($number1)); // double(123)

$number2 = '123abc';
var_dump(floatval($number2)); // double(123)

$number3 = 'abc123';
var_dump(floatval($number3)); // double(0)

$number4 = true;
var_dump(floatval(number4)); // double(0)
$number5 = false;
var_dump(floatval(number5)); // double(0)

$number6 = '3.14';
var_dump(floatval($number6)); // double(3.14)
?>
  • boolval() 获取变量的布尔值
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
<?php 
$number1 = '123';
var_dump(boolval($number1)); // bool(true)

$number2 = '123abc';
var_dump(boolval($number2)); // bool(true)

$number3 = 'abc123';
var_dump(boolval($number3)); // bool(true)

$number4 = true;
var_dump(boolval(number4)); // bool(true)
$number5 = false;
var_dump(boolval(number5)); // bool(true)

$number6 = '3.14';
var_dump(boolval($number6)); // bool(true)

$number7 = 0;
var_dump(boolval($number7)); // bool(false)


$number8 = array();
var_dump(boolval($number8)); // bool(false)

$number9 = '';
var_dump(boolval($number9)); // bool(false)

$number10 = null;
var_dump(boolval($number9)); // bool(false)
?>

判断数据类型常用函数

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php    
is_array($value); # 判断变量是否是一个数组
is_string($value); # 判断变量是否是一个字符串
is_bool($value); # 判断变量是否是一个布尔值
is_float($value); # 判断变量是否是一个浮点数
is_object($value); # 判断变量是否是一个对象
is_numerbic($value); # 判断变量是否是一个整型
is_resource($value); # 判断变量是否是一个资源类型
is_null($value); # 判断变量是否是一个空类型
is_scalar($value); # 判断变量是否是一个标量
gettype($value); # 返回变量的数据类型 获取变量的类型
var_dump($value); # 输出变量的值和其数据类型
?>

总结

1
2
3
4
5
6
1. null转换为整型会是0
2. null转换为浮点数也是0
3. null转换为字符串会是空字符串''
4. '123.abc'这样的字符串转换为整数会将数字后面的所有字符都剔除,结果为123。
5. 'abc1234'这样的字符串转换为整数,以非数字开头,则转换的结果为0,转换为浮点型也是。
6. '123.456.789abc'这样的字符串转换为浮点型,会将123.456后面的都去掉(包括数字),从而结果为123.456

运算符

算数运算符

名称 操作符 举例
加法运算符 + $a + $b
减法运算符 - $a - $b
乘法运算符 * $a * $b
除法运算符 / $a / $b
取余运算符 % $a % $b

注意:在使用取余运算符的时候,如果被除数是负数,那么最终取到的余数也是一个负数

比较运算符

名称 说明
> 大于
< 小于
>= 大于等于
<= 小于等于
== 等于(不比较数据类型,会有类型转换)
=== 全等于(比较数据类型,不会有自动类型转换)
!= 不等于(不比较数据类型,会有自动类型转换)
!== 不等于((比较数据类型,不会有自动类型转换))

逻辑运算符

逻辑运算用来组合逻辑运算的结果,是程序设计中一组非常重要的运算符

运算符 举例 结果为真
&& 或 and (逻辑与) $a and $b 当$a和$b都为真时
|| 或 or (逻辑或) $a || $b 当$a或者$b有一个为真时
xor (逻辑异或) $a xor $b 当$a和$b一真一假时
! (逻辑非) $a 当$a为真时

自增自减运算符

运算符 举例 说明
++ $a ++ 自身加1
$b – 自身减1

这里分为先 ++ 还是后 ++++ 放在变量前面表示先自身增1,之后在做输出(或者执行后续代码)。++ 放在变量的后面表示当前行执行完之后再执行自身增 1 。(-- 也是如此)

1
2
3
4
5
6
7
8
<?php 
$number = 10;
echo $number++; // 10
echo $number; // 11

$number2 = 1;
echo ++$number2; // 2
?>

为false的几种情况

1
2
3
4
5
6
1. 整型除0以外,转为布尔值都为true
2. 如果浮点型0.00000000后面都是0则为false,如果后面有一个非0的数字,即为真。
3. 字符串类型只有空字符串转为布尔值为false,注意是空字符串''"",而不是" "
4. 空字符串的0位false,其他都为true
5. 空数组为false,其余都为真
6. null作为判断条件时也为false

流程控制语句

if 判断

单分支结构

1
2
3
if (条件表达式) {
真区间
}

双分支结构

1
2
3
4
5
if (条件表达式) {
真区间
}else {
假区间
}

多分支结构

1
2
3
4
5
6
7
8
9
if (条件表达式) {
真区间
} else if (条件表达式) {
真区间
} else if (条件表达) {
真区间
} else {
假区间
}

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php 
$score = 200;
if ($score < 60) {
echo "不及格<br/>";
} else if ($score == 60) {
echo "及格<br/>";
} else if ($score <= 70) {
echo "良好<br/>";
} else if ($score <= 80 ) {
echo "优秀<br/>";
} else if ($score <= 90 ) {
echo "厉害了<br/>";
} else if ($score == 100) {
echo "超神<br/>";
} else {
echo "成绩不太合法哦!<br/>";
}
?>

switch 判断

语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
switch (条件表达式) {
case 1:
echo "我是1的内容";
break;
case 2:
echo "我是2的内容";
break;
case 3:
echo "我是3的内容";
break;
default:
echo "我是默认内容";
break;
}

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php 
$res = 4 ;
switch ($res) {
case 1:
echo "我是1的内容<br/>";
break;
case 2:
echo "我是2的内容<br/>";
break;
case 3:
echo "我是3的内容<br/>";
break;
default:
echo "我是默认内容<br/>";
break;
}
?>

随机塞子示例

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
<?php 
$randmo_num = mt_rand(1,6);

echo "你的幸运数字为: " . $randmo_num . "<br/>";
switch ($randmo_num) {
case 1:
echo "做家务<br/>";
break;
case 2:
echo "只是洗个衣服<br/>";
break;
case 3:
echo "洗全套<br/>";
break;
case 4:
echo "去洗头<br/>";
break;
case 5:
echo "比心心(๑′ᴗ‵๑)I Lᵒᵛᵉᵧₒᵤ❤<br/>";
break;
case 6:
echo "去刷碗<br/>";
break;
}

?>

总结

当进行单值匹配的时候可以使用 switch 分支语句,当进行范围匹配的时候可以使用 if 分支语句。

循环结构

简介

生活中的循环即重复的做某件事情,而程序中的循环指的是重复的执行某个代码块。

php 中主要有三种循环,即 for 循环、while 循环 和 do..while 循环。

for 循环

语法

1
2
3
for (初始化表达式; 条件判断; 变量更新) {
循环体;
}

示例

1
2
3
4
5
<?php 
for ($i = 1;$i <= 5;$i++) {
echo $i . "<br/>";
}
?>

while 循环

语法

1
2
3
4
while (条件表达式) {
循环体
变量更新
}

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php 
$i = 1;
while ($i <= 5) {
echo "The number is " . $i . "<br />";
$i ++;
}

/*
输出:
The number is 1
The number is 2
The number is 3
The number is 4
The number is 5
*/
?>

do..while 循环

语法

1
2
3
4
do {
循环体
变量更新
}while (条件表达式)

示例

1
2
3
4
5
6
7
8
9
10
<?php 
$i = 1;
do {
echo "The number is " . $i . "<br />";
}while (i > 10);

/*
输出: The number is 1;
*/
?>

循环关键字

  • break 表示终止循环
  • continue 表示跳过本次循环,开始下一次循环。

break 示例

1
2
3
4
5
6
7
8
9
<?php 
for ($i=1; $i <=5; $i++) {
echo "The number is " . $i . "<br />";
break;
}
/*
输出: The number is 1<br />
*/
?>

continue 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php 
for ($i=1; $i <=5; $i++) {
if ($i == 4) {
continue;
}
echo "The number is " . $i . "<br />";
}
/*
输出:
The number is 1
The number is 2
The number is 3
The number is 5
*/
?>

函数

无参函数

语法:

1
2
3
funciton 函数名() {
// 函数体代码
}

示例:

1
2
3
4
5
6
7
8
<?php 
function test() {
echo "hello world";
}

// 定义函数之后,并不会立即执行函数,需要使用函数名()进行调用。
test(); // 调用函数
?>

有参函数

语法:

1
2
3
4
5

// 在定义的时候,传入的参数名叫做形参,如果在定义的时候,就指定了参数的值,那么在调用的时候,可以传入对应参数的值
function 函数名(参数1,参数2,参数3) {
// 函数体代码
}

示例:

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
<?php 
function info($name = 'x1ong',$age = 17,$addr = '河南'){
echo "My name is " . $name;
echo "<br />";
echo "My age is " . $age;
echo "<br />";
echo "My address is " . $addr;
echo "<br />";
echo "<hr />";
}

info(); // 使用默认函数 参数的值使用默认值
info('lulu',18,'henan'); // 这里写入的参数叫做实参 如果给函数传入了值那么就不再使用默认参数的值
info('test','18','文件','10',10,30,40,50,60); // 参数可以多,但是不能少

function login($name,$password){
echo "username is : " . $name;
echo "<br />";
echo "password is : " . $password;
}
login('x1ong','Admin123'); // 实参可以多于形参,但是实参不能少于形参

// 从一个将实参中的数字作为形参的参数数组。
function admin(...$arr){
var_dump($arr);
echo "<br />";
}
admin(1,'hello','world','admin','xxx');
// 将实参中的数字打散按位填充作为形参的值,
function arr($name,$age,$addr,$gender){
echo $name;
echo "<br />";
echo $age;
echo "<br />";
echo $addr;
echo "<br />";
echo $gender;
echo "<br />";
}
arr(...['x1ong',17,'henan','sex']);
?>

匿名函数

1
2
3
4
5
6
<?php
$x1ong = function (){
echo "helloworld";
};
$x1ong();
?>

内置函数

数学函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 随机数:
rand() # 产生一个随机整数
mt_rand() # 更好的产生一个随机数

# 小数:
floor() # 舍去法取整
ceil() # 进1法取整
round() # 四舍五入取整

# 其他:
abs() # 取绝对值
pi() # 无参 获取pi的值
# M_PI 常量 获取的值跟pi() 的值一致。
min() # 返回数组中的最小数
max() # 返回数组中的最大数

字符串函数

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
# 大小写转换:
strtolower() # 将所有字母转换为小写
strtouppper() # 将所有字母转换为大写
lcfirst() # 将首字母小写
ucfirst() # 将首字母大写
ucwords() # 每个单词的首字母大写,默认以空格区分单词,可以指定

# 空白处理:
trim() # 首尾去空,可以指定去除的字符
ltrim() # 只取出左边的空白字符,可以指定去除的字符
rtrim() # 别名chop() 去除右边的空白字符,可以指定去除的字符

# 查找定位:
strstr() # 别名strchr() 查找字符串首次出现的位置,如果存在则返回之后的所有字符串,否则返回false
stristr() # 不区分大小写的strstr()
strrchar() # 查找字符串最后一次出现的位置,如果存在则返回之后的所有字符,否则返回false
strpos() # 返回字符串首次出现的位置
stripos() # strpos的忽略大小写版本
strrpos() # 返回字符串最后一次出现的位置
strripos() # strrpos()的忽略大小写版本
substr() # 返回字符串的子串(截取字符串)

# 比较:
strcmp() # 二进制比较字符串
strcasecmp() # strcmp() 忽略大小写的版本
strnatcmp() # 自然顺序比较
strnatcasecmp() # strnatcmp()忽略大小写版本

# 顺序:
str_shuffle() # 随意打乱字符串
strev() # 反转字符串

# 转换:
char() # 将ascii转换为字符
ord() # 将字符串的首字母转换为ascii码

时间函数

  • date() 函数把时间戳格式的数字,转为可读性更好的时间格式
  • time() 获取当前时间的时间戳

配置时区函数

1
2
3
<?php
date_default_timezone_set('RPC'); // 设置当前时区为中国标准时间 默认为UTC
?>

配置时区 配置文件

1
date.timezone = "asia/shanghai"

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php 
echo time();
date_default_timezone_set('PRC'); // 设置当前时区为中国标准时间,默认为UTC,比中国慢了8个小时,该配置只对当前php文件生效,对所有文件生效需要修改配置文件。
echo '<br />';
echo date_default_timezone_get() ; // 获取当前的时区
echo '<br />';
echo date('Y-m-d h:i:s'); // 格式化时间戳,如果不指定,默认为当前时间
/*
输出:
1691749048
PRC
2023-08-11 06:17:28
*/
?>

文件包含

文件包含主要指,将其他文件的代码引入到当前页面之中。这就叫做文件包含。include() 程序执行到include时才会进行文件包含,如果找不到包含的文件路径,则只会发出警告继续执行后面的代码。

include_once()include() 基本一致,但是 include_once 遇到已经包含过的文件不会重复包含,而 include() 会。

require()include() 基本一致 但是require()包含的文件如果不存在,则程序就会停止执行。

require_once()include_once() 基本一致,不同的是 require_once() 包含的文件如果不存在,程序则会终止执行。

1
2
3
4
<?php
include 'filename1.php';
require 'filename2.php';
?>

数组类型

数组的取值

  • 索引数组 通过下标取值
1
2
3
4
5
6
7
8
9
10
<?php 
$arr = array(1,3,'hello',true);
echo $arr[0]; // 1
echo $arr[1]; // 3
echo $arr[2]; // hello

// 数组元素的赋值
$arr[2] = 'world';
echo $arr[2]; // world
?>
  • 关联数组 通过 key 取值
1
2
3
4
5
6
7
8
9
10
<?php 
$arr = array(
'name' => 'x1ong',
'age' => 10,
'address' => 'HN'
);
echo $arr['name']; // x1ong
echo $arr['age']; // 10
echo $arr['address']; // HN
?>
  • 二维数组
1
2
3
4
5
6
7
8
9
10
11
12
<?php 
$info = array(
'name' => ['x1ong','xiaoming','xiaohong','xiaoliang'],
'age' => [10,9,8,7],
'address' => ['JX','HN','BJ','CQ']
);

echo $info['name'][0] . "<br />";
echo $info['age'][0] . "<br />";
echo $info['address'][0] . "<br />";

?>
  • 三维数组
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php 
$info = array(
'student' => array(
'names' => ['x1ong','xiaoming','xiaohong'],
'age' => [10,9,8,7],
'address' => ['BJ','HN','SH','CQ']

),
);
echo $info['student']['names'][0] . "<br />";
echo $info['student']['age'][0] . "<br />";
echo $info['student']['address'][0] . "<br />";
?>

数组的遍历

遍历索引数组的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php 
$arr = ['x1ong','xiaoming','xiaohong','xiaoliang'];

$length = count($arr); // 计算数组的长度

$flag = 0;
while ($flag < $length){
echo $arr[$flag] . "<br />";
$flag++;
}
/*
输出:
x1ong
xiaoming
xiaohong
xiaoliang
*/
?>
遍历关联数组的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php 
$arr = array(
'name' => 'x1ong',
'age' => 17,
'addr' => 'China',
);

foreach ($arr as $key => $value) {
echo $key . '=' . $value . "<br />";
}
/*
输出:
name=x1ong
age=17
addr=China
*/
?>

数组相关的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# key和value相关函数
array_keys() # 获取数组的key
array_values() # 获取数组的value
array_flip() # 交换数组中key和value的位置,原本的key变value,value变key
in_array() # 判断某个值是否在数组中
array_search() # 在数组中搜索某个值,在则返回它的key,不在则返回false
array_key_exists() # 判断某个键是否在某个数组中,返回值true和false
count() # 获取数组中元素的个数
array_change_key_case(array,case) # 将数组中的所有key转为全大写或小写 ,case值为CASE_UPPER或CASE_LoWER(默认值)
array_count_values() # 计算数组中值出现的次数。
array_key_first() # 得到数组中第一个key名
array_key_lsast() # 得到数组中最后一个key名
array_pop() # 弹出数组中的最后一个元素
array_push() # 将一个单元或多个单元压入数组的末尾
array_unshfit() # 将一个单元或多个压入数组的开始
array_reverse() # 将数组反转
array_sum() # 对数组中的数值进行求和。
array_product() # 对数组中的数值求乘积
array_unique() # 删除数组中重复的值
shuffle() # 随便排序一个数组
array_rand() # 从数组中随机取出一个或多个随机键

超全局变量

超全局变量在 php4.1.0 以后被启用,是 php 的内置变量,在脚本的任意位置都可以访问到该变量 php 的超全局变量列表

变量名称 说明
$GLOBALS 存放了所有全局变量的数组, key 就是变量的名称
$_SERVER 包含了诸如请求头信息、路径等等信息
$_REQUEST 用于收集通过 GETPOST 提交的参数和值
$_POST 接受所有来自 POST 传输的参数,参数名为 key ,值为 value
$_GET 接受所有来自 GET 传输的参数,参数名为key,值为value
$_FILES 是用来获取 post 方法上传文件的信息
$_ENV 获取环境变量
$_COOKIE 接收请求头中的 Cookie 字段的 keyvalue

cookie 常用于识别用户。cookie 是一种服务器留在用户计算机上的小文件。每当同一台计算机通过浏览器请求页面时,这台计算机将会发送 cookie。通过 PHP,您能够创建并取回 cookie 的值。

setcookie() 函数用于设置 cookie注释:setcookie() 函数必须位于 <html> 标签之前。

语法:

1
setcookie(name, value, expire, path, domain);

示例一:

在下面的例子中,我们将创建名为 “user“ 的 cookie,并为它赋值 “admin“。我们也规定了此 cookie 在一小时后过期:

1
2
3
4
5
6
<?php
setcookie("user", "admin", time()+3600);
?>

<html>
...
1
2
3
4
5
6
7
<?php
// 输出 cookie 值
echo $_COOKIE["user"];

// 查看所有 cookie
print_r($_COOKIE);
?>
1
2
3
4
<?php
// 设置 cookie 过期时间为过去 1 小时
setcookie("user", "", time()-3600);
?>

Session

session 的简介

sessioncookie都是一种会话控制,都是跟踪用户会话的技术手段。而会话就是服务器和客户端的一次次通话。

sessioncookie的几个重要区别:

  1. session 在服务端,而 cookie 在客户端存储
  2. cookie 在本地,可以随便修改,因此 session 更安全
  3. cookie 在本地,可以永久有效,但是 session 在服务器,如果设置永久有效,随着用户的增多,那么会导致内存溢出。
  4. session 会在一段时间内保存到你的服务器,如果服务器追求访问速度,那么不推荐使用 session
  5. cookie 需要浏览器支持,而 session 不需要。

使用 session

**1. 在每个文件中每次使用 session 之前需要开启 session **

1
2
3
<?php 
session_start();
?>

2. 设置 session

1
2
3
4
5
6
7
8
<?php
// ...
if ( $result['username'] === $in_username && $result['password'] === $in_password ) {
// 设置 session
$_SESSION['username'] = $in_username;
}
// ...
?>

3. 销毁 session

1
2
3
4
5
6
7
<?php 
// 使用 session_destroy() 进行销毁
session_destroy(); // 销毁一个会话中的全部数据

// 使用 unset() 函数销毁
unset($_SESSION['uname']);
?>

文件操作

文件的读取

readfile()

**语法: ** readfile(filename)

作用: 将一个文件的文件内容读取出来,并输出。

1
2
3
<?php 
readfile('1.txt');
?>

file()

语法: file(filename, flags 可选参数)

作用: 把整个文件内容读入到一个索引数组中。以行进行分割。

1
2
3
4
5
6
7
8
9
10
<?php 
print_r(file('1.txt'));
/*
Array
(
[0] => helloworld
[1] => 你好世界
)
*/
?>

file_get_contents()

语法: file_get_contents(filename, ...可选参数)

作用: 将整个文件的内容读取到一个字符串。

1
2
3
<?php 
echo file_get_contents('1.txt');
?>

文件的创建及写入

file_put_contents()

语法:file_put_contents(filename,data,...可选参数)

作用: 将数据写入到文件

1
2
3
<?php
file_put_contents('flag.txt','helloworld'); // 此时创建文件flag.txt 内容为 helloworld
?>

fopen() 相关

语法: file(filename, mode,...可选参数)

作用: 打开文件或者 URL

文件打开模式:

模式 说明
r 只读方式打开,将文件指针指向文件头。
r+ 读写方式打开,将文件指针指向文件头。
'w' 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建。
'w+' 读写方式打开,否则行为同 'w'
'a' 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。在这种情况下,fseek() 没有效果,写入总是追加。
'a+' 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。在这种情况下,fseek() 只相应读取位置,写入总是追加。
1
2
3
4
5
6
7
8
<?php 
// 1. 打开文件
$file = fopen('2.txt','w');
// 2. 写入文件内容
fwrite($file,'helloworld');
// 3. 关闭文件
fclose($file);
?>

这里也可以通过fseek()改变文件读取位置的指针,也可以使用fread()函数做文件的读取。

PHP类和对象基础

基础概念

类是对一个类别的抽象概念,而具体的则是对象,比如汽车就是一个类

而对象则是我的宝马,而不是宝马,宝马也是一个类,对象是一个具体到每个事物

PHP官方解释: 类是对象的抽象,对象是类的具像(具体对象)

如何创建一个类:

使用class关键字进行创建,Class ClassName{}

1
2
3
4
5
<?php 
class Demo {
// 这里面是类中的内容
}
?>

类中的成员

  • 属性和行为
    • 成员属性 —> 变量(在类中定义的变量称之为属性)
    • 行为 –> 成员方法(在类中定义的函数称之为方法)
    • 成员常量

类名的命名规范:

类名通常使用大驼峰式命名法
persontest 的大驼峰命名法就是PersonTest 小驼峰命名法就是personTest

创建一个demo类

1
2
3
4
5
6
7
8
9
10
11
12
<?php 
class Demo {
public $name = 'x1ong';
public function eat() {
echo $this->name . '在吃饭!';
}
}
// 初始化(实例化)这个Demo类
$obj = new Demo;
// 调用类中的eat方法
$obj->eat(); // 输出: x1ong在吃饭
?>

类的继承

继承的好处:

  • 子类继承了父类,那么就拥有了父类可以有的属性和方法
  • 子类拥有父亲的所有可以拿到的属性,还有自己独特的属性

继承的语法:

1
class 子类名 extends 父类名 {}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php 
// 父类
class Person {
public $name = 'x1ong';
public function addInfo() {
echo "<h1>这是一个没用的信息</h1>";
}
}
// SubClass子类继承Person
class SubClass extends Person {

}
// 实例化子类
$obj = new SubClass();
// 子类可以直接调用父类的公有方法
$obj->addInfo();
// 子类可以直接调用父类的公有属性
echo $obj->name;
?>

类的访问权限

  • public 公用的,可以在外部访问、类内部访问、被继承
  • protected 受保护的,可以在类内部访问,可以被继承,不能在类外部访问
  • private 私有的,只能在类的内部访问,不可以被继承,不可以在类外部访问

在类中的属性必须要加上访问权限,如果没有则会报错。
在类中的方法,可以不加访问权限,默认则为public

以下使用属性演示访问权限,方法的访问权限一致:

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
<?php 
// 父类
class Person {
public $name = 'x1ong';
protected $id = '41282820020327xxxx';
private $position = '计算机从业人员';
}
// SubPerson继承父类Proson
class SubPerson extends Person {
function __construct() {
// public 可以在外部访问、类内部访问、被继承
echo '我父亲的名字为: ' . $this->name . PHP_EOL;
// protected 可以在类内部访问,可以被继承,不能在类外部访问
echo '我父亲的身份证号为: ' . $this->id . PHP_EOL;
// provate 只能在类的内部访问,不可以被继承,不可以在类外部访问。
// echo '我父亲的职位为: ' . $this->position . PHP_EOL;

}
}

$obj = new SubPerson;
// 外部访问public 可以
echo $obj->name;

// 外部访问protected 不可以
echo $obj->id;

// 外部访问private 不可以
// echo $obj->position;

?>

类中方法的重写

重写的前置知识

重写方法也叫做重载
重写的作用: 父类的方法不适合子类使用,那么这个时候子类可以重写父类的方法
重写一般分为两种:

  • 完全重写
  • 在父类的基础上增加一定的功能

子类调用的方法是子类重写后的方法,父类还是调用父类的方法

在子类中如果想要调用父类的方法,就需要使用parent关键字,其语法如下:

1
parent::FunctionName();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php 
// 父类
class Person {
public $name = 'x1ong';
function jump() {
echo '我能跳3米';
}
}

// SubPerson 继承父类Person
class SubPerson extends Person {
// 魔术方法: __construct 当对象被实例化的时候自动调用
function __construct() {
// 子类调用父类的方法 使用parent关键字
parent::jump();
}
}
$obj = new SubPerson;
?>

完全重写

完全重写:不使用父类的方法,直接在子类中重写定义一个相同的方法名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php 
class Person{
function jump() {
echo '我能跳3米' . PHP_EOL;
}
}
class SubPerson extends Person {
function jump() {
echo '我能跳9米' . PHP_EOL;
}
}
$obj = new SubPerson;
$obj->jump(); // 我能跳9米

$obj2 = new Person;
$obj2->jump(); // 我能跳3米
?>

子类调用的方法是子类重写后的方法,父类还是调用父类的方法

在父类方法的基础上强化

在父类方法的基础上增加一些额外的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php 
class Person {
function work() {
echo '我工作勤勤恳恳' . PHP_EOL;
}
}

class SubPerson extends Person {
function work() {
// 调用父类方法
parent::work();
// 在父类的基础上增加功能
echo "我恋爱认认真真" . PHP_EOL;
}
}

$obj = new SubPerson;
$obj->work();
?>

重写的权限只能放大

重写方法的访问权限只能放大,不能缩写。

缩小化报错代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php 
class Person {
public function work() {
echo '我工作勤勤恳恳' . PHP_EOL;
}
}
class SubPerson extends Person {
// 从父类的public降级到protected 权限缩小化 报错!!!
protected function work() {
// 完全重写
echo '我恋爱认认真真' . PHP_EOL;
}
}
?>

放大化正常代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php 
class Person {
private function work() {
echo '我工作勤勤恳恳' . PHP_EOL;
}
}
class SubPerson extends Person {
// 从父类的private升级到protected 权限放大化 正常!!!
protected function work() {
// 完全重写
echo '我恋爱认认真真' . PHP_EOL;
}
}
?>

final 关键字

在定义类的时候,前面加上 final 关键字,表示该类内部的属性和方法不能被继承,在定义方法的前面加上 final 表示该函数不能被重写

无法继承的类

1
2
3
4
5
6
7
8
9
10
11
12
<?php 
final class Person {
public $name = "x1ong";

public function eat() {
echo $this->name . "正在吃饭";
}
}

// 报错代码: Fatal error: Class subClass may not inherit from final class (Person)
class subClass extends Person {
}

无法重写的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php 
class Person {
public $name = "x1ong";

final public function eat() {
echo $this->name . "正在吃饭";
}
}

class subClass extends Person {
// 报错代码: Fatal error: Cannot override final method Person::eat()
public function eat() {
// ...
}
}

类常量

基础概念

类常量,也就是定义在类中的常量,在类的外部可以使用 defineconst 进行定义常量

php中我们可以理解为值不变的量叫作常量,那么,什么又是类常量呢?其实类常量也很容易理解,我们可以把类中始终保持不变的值称为常量,如果该常量定义在类中就可以称之为类常量。一定要记得在定义和使用常量的时候不需要使用 $ 符号。

常量定义方法:

1
2
3
4
5
6
7
8
9
<?php 
// 定义常量式1:
define("USER","root");
echo USER;

// 定义常量方式2:
const NAME = 'x1ong';
echo NAME;
?>

类常量的定义方法:

在类内部只能使用 const 定义常量,因此推荐在类外部使用 define 进行定义常量,在类的内部使用const关键字进行定义。

1
2
3
4
5
<?php 
class Demo {
// 类常量的定义方式
const NAME = 'x1ong';
}

类常量的调用方式

在类的内部:

1
// self::常量名 或者 $this::常量名

在类的外部:

1
// 类名::常量名 或者 $obj_name::常量名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
class Conn {
const USERNAME = 'root';
const PASSWORD = 'toor';

function config() {
// 类内调用
echo '用户名: ' . self::USERNAME . PHP_EOL;
echo '密码: ' . $this::PASSWORD . PHP_EOL;
}
}
$obj = new Conn;
$obj->config();
// 类外调用
echo Conn::USERNAME . PHP_EOL;
echo $obj::PASSWORD . PHP_EOL;

静态属性和静态方法

基础概念

static 关键字如果用来修饰属性或者方法时,那么该属性是属于整个类的,而不是属于某个对象,因此可以直接通过类名调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php 
class Demo {
// 定义静态属性
static public $name = 'x1ong';
// 定义静态方法
static function msg() {
echo 'My name is ' . self::$name;
}
}

$obj = new Demo;
// 类外访问
Demo::msg();

调用方式

在类的内部调用静态属性:

1
// self::$静态属性名 

在类的外部调用静态属性:

1
// 类名::$静态属性名 或者 $obj_name::$静态属性名

在类的内部调用静态方法:

1
// self::静态方法名() 或者 类名::静态方法名() static::静态方法名() 

在类的外部调用静态方法:

1
// 类名::静态方法名() 或者 $obj_name::静态方法名()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php 
class Demo {
static public $name = 'x1ong';
static public $age = 18;
function msg() {
// 类内部调用
echo 'My name is ' . self::$name . PHP_EOL;
echo 'MY age is ' . $this::$age . PHP_EOL;
}
static function info() {
echo 'hello world' . PHP_EOL;
}
}

$obj = new Demo;
$obj->msg();
// 类外访问
Demo::info();
$obj::info();

魔术方法

__construct()

触发条件:构造函数,当一个类被实例化的时候自动调用
参数: 任意长度的参数,常用于初始化属性的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php 
class Demo {
public $name;
public $age;
public $gender;

function __construct($name,$age,$gender) {
// 属性初始化
$this->name = $name;
$this->age = $age;
$this->gender = $gender;
}
}

$obj = new Demo('x1ong',17,'male'); // 实例化(初始化)类
echo $obj->name;
echo $obj->age;
echo $obj->gender;
?>

__destruct()

触发条件: 析构函数,在对象的所有引用被删除或者当对象被销毁时执行的魔术方法。
参数: 无参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php 
class Demo {
function msg() {
echo '这是一条无用的信息' . "<br />";
}

function __destruct() {
echo '我是__destruct()执行的内容' . "<br />";
}
}

$obj = new Demo; // 执行1次
$obj->msg();
echo 'helloworld' . "<br />";
// 序列化和反序列化
$ser = serialize($obj);
unserialize($ser); // 执行2次
?>

__toString()

触发条件: 当对象被 echo(被作为字符串输出) 时触发
一般情况下,该函数都需要有return
参数:无参数

1
2
3
4
5
6
7
8
9
<?php 
class Demo {
function __toString() {
return '我是当对象被echo的时候执行的函数 __toString';
}
}
$obj = new Demo;
echo $obj;
?>

__invoke()

触发条件:当对象被当成函数时调用

1
2
3
4
5
6
7
8
<?php 
class Demo {
function __invoke() {
echo '我是对象被当做函数调用时执行的__invoke()';
}
}
$obj = new Demo;
$obj();

__get()

触发条件: 当对象从外部访问一个不存在(或不可访问)的属性时调用该方法
参数: $name 该值为访问的属性名

1
2
3
4
5
6
7
8
9
10
11
<?php 
class Demo {
private $name = 'x1ong';
function __get($name) {
echo '你访问的属性值不存在或不可访问,访问名称为: ' . $name;
}
}

$obj = new Demo;
echo $obj->name;
?>

__set()

触发条件: 当对象对外部设置一个不存在(或不可访问)的属性时调用该方法
参数: 形参2个 例如 $name,$value 该值分别为访问的属性和设置的值。

在类的外部可以为类的属性重新赋值:

1
2
3
4
5
6
7
8
9
10
<?php 
class Demo {
public $name = 'x1ong';
}
$obj = new Demo;
echo $obj->name . PHP_EOL; // x1ong
// 为类的属性name重新赋值
$obj->name = 'pony';
echo $obj->name . PHP_EOL; // pony
?>

但是遇到了访问不到的属性,一旦为他们重新赋值则会报错:

1
2
3
4
5
6
7
8
9
<?php 
class Demo {
protected $name = 'x1ong';
}
$obj = new Demo;
echo $obj->name . PHP_EOL; // x1ong
// 为类的属性重新赋值 报错 !!! 原因:外部访问不到protected
$obj->name = 'pony';
?>

那么如何为外部访问不到的属性重新赋值呢,这个时候就需要用到魔术方法__set()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php 
class Demo {
// 受保护的属性 类的外部访问不到
protected $name = 'x1ong';
function __set($name,$value) {
// 在类的内部为属性重新赋值
$this->name = $value;
echo $this->name . PHP_EOL;
echo '当设置一个类外无法访问的属性时,自动调用__set()方法' . PHP_EOL;
}
}
$obj = new Demo;
// 为类的属性重新赋值
$obj->name = 'pony';
?>

__clone()

触发条件: 在克隆一个对象的时候调用
在这里可以对克隆出来的对象属性做一些操作
参数:无

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php 
class Demo {
public $name;
public $age;
public $gender;
function __construct($name,$age,$gender) {
$this->name = $name;
$this->age = $age;
$this->gender = $gender;
}
function __clone() {
echo '我在对象被克隆的时候调用: __clone()' . PHP_EOL;
}
}
$obj = new Demo('x1ong',18,'male');
$obj2 = clone $obj; // 克隆一个对象
echo $obj2->name; // x1ong
?>

__call()

触发条件:在调用一个不存在的方法时调用
参数:$args1(调用的方法名),$args2(传入的参数值,是个数组)

1
2
3
4
5
6
7
8
9
10
<?php 
class Demo {
function __call($args1,$args2) {
echo '我是调用对象的一个不存在的方法时执行的__call()';
echo $args1 . PHP_EOL;
print_r($args2);
}
}
$obj = new Demo;
$obj->addInfo(1,2,3);

__callStatic()

触发条件:当调用不存在的静态方法时
参数:$args1(调用的方法名),$args2

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php 
class Demo {
static function __callStatic($name, $arguments) {
echo '我是当调用一个不存在的静态方法时执行的__callStatic()' . PHP_EOL;
echo '调用的静态方法名为' . $name . PHP_EOL;
echo '传入的参数为:' . PHP_EOL;
print_r($arguments);
}

}

$obj = new Demo;
Demo::config('root');

__isset()

触发条件:对不可访问或不存在属性使用isset()或者empty()的时候触发
参数:$args1(不存在的成员属性名称)

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php 
class Demo {
function __isset($name) {
echo '我是当对不可访问属性使用isset()或者empty()的时候触发的__isset()' . PHP_EOL;
echo '访问的属性名为' . $name . PHP_EOL;
}
}

$obj = new Demo;
// 触发一次 __isset()
isset($obj->x1ong);
// 触发一次 __isset()
empty($obj->name);

__unset()

触发条件:对不可访问或不存在的属性使用unset()时触发
参数:$args1(不可访问或者不存在的属性名称)

1
2
3
4
5
6
7
8
9
10
11
<?php 
class Demo {
function __unset($name) {
echo '我是对不可访问或不存在的属性使用unset()时触发__unset()' . PHP_EOL;
echo '访问的属性名为' . $name . PHP_EOL;
}
}

$obj = new Demo;
// 触发点
unset($obj->name);

抽象类和接口

前置知识

  • 抽象类不能被实例化

  • 抽象类存在的目的是为了子类继承

  • 抽象类的定义和普通类定义是一样的,只不过前面加上了一个关键字: abstract

  • 抽象类里面一般都要有抽象方法,抽象方法一般都是让子类实现的。并且子类必须实现,不实现就报错

  • 抽象方法如果有参数,参数有默认值,那么实现该方法时候的参数名一致,并且如抽象方法有默认值,

  • 抽象类可以继承抽象类,子类在实现的时候所有抽象方法都要实现

  • 抽象类中只有抽象方法,没有抽象属性

普通类

1
2
3
4
5
6
7
8
9
10
11
<?php
class Demo {
public $name;
function __construct($name) {
$this->name = $name;
echo $this->name;
}
}

$obj = new Demo("x1ong");
?>

抽象类

1
2
3
4
5
<?php
// 定义一个抽象类
abstract class Grandpa {
abstract public function medal();
}

数据库操作

mysqli 连接数据库

面向过程数据库连接示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php 
$host = 'localhost';
$username = 'root';
$password = 'toor';
$db = 'mysql';

// 创建连接
$conn = @mysqli_connect($host, $username, $password, $db);

// 检测连接
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
echo "数据库连接成功";
?>

面向过程登录页面示例

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
<?php 
$db_host = 'localhost';
$db_user = 'root';
$db_pass = 'toor';
$db_database = 'login';

// 创建连接
$conn = mysqli_connect($db_host, $db_user, $db_pass, $db_database);

// 检测连接
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login page</title>
</head>
<body>
<form method="post">
username: <input type="text" name="username" placeholder="请输入用户名">
<br>
password: <input type="password" name="password" placeholder="请输入密码">
<br>
<input type="submit" name="submit" value="login">
</form>
<?php
if (isset($_POST['username']) and isset($_POST['password']) and isset($_POST['submit'])) {
$username = addslashes($_POST['username']);
$password = md5($_POST['password']);
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$result = mysqli_query($conn, $sql);
$rows = mysqli_fetch_assoc($result);
if ($rows['username'] === $username && $rows['password'] === $password) {
echo "<script>alert('登录成功!欢迎用户: {$username}')</script>";
}else {
echo "<script>alert('登录失败,用户名或密码错误!')</script>";
}
}
?>
</body>
</html>

面相对象数据库连接实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php 
// 数据库连接信息
$db_host = '127.0.0.1';
$db_user = 'root';
$db_pass = 'toor';
$db_database = 'login';

// 创建连接
$conn = @new mysqli($db_host, $db_user, $db_pass, $db_database);

// 检查连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
echo "数据库连接成功";
?>

面向对象登录页面示例

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
<?php 
// 数据库连接信息
$db_host = '127.0.0.1';
$db_user = 'root';
$db_pass = 'toor';
$db_database = 'login';

// 创建连接
$conn = @new mysqli($db_host, $db_user, $db_pass, $db_database);

// 检查连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login page</title>
</head>
<body>
<form method="post">
username: <input type="text" name="username" placeholder="请输入用户名">
<br>
password: <input type="password" name="password" placeholder="请输入密码">
<br>
<input type="submit" name="submit" value="login">
</form>
<?php
if (isset($_POST['username']) and isset($_POST['password']) and isset($_POST['submit'])) {
$username = addslashes($_POST['username']);
$password = md5($_POST['password']);
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$result = $conn->query($sql);
$rows = $result->fetch_assoc();
if ($rows['username'] === $username && $rows['password'] === $password) {
echo "<script>alert('登录成功!欢迎用户: {$username}')</script>";
}else {
echo "<script>alert('登录失败,用户名或密码错误!')</script>";
}
}
?>
</body>
</html>

预处理语句登录页面示例

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
<?php 
// 数据库连接信息
$db_host = '127.0.0.1';
$db_user = 'root';
$db_pass = 'toor';
$db_database = 'login';
// 创建连接
$conn = @new mysqli($db_host, $db_user, $db_pass, $db_database);
// 检查连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login page</title>
</head>
<body>
<form method="post">
username: <input type="text" name="username" placeholder="请输入用户名">
<br>
password: <input type="password" name="password" placeholder="请输入密码">
<br>
<input type="submit" name="submit" value="login">
</form>
<?php
if (isset($_POST['username']) and isset($_POST['password']) and isset($_POST['submit'])) {
$in_username = $_POST['username'];
$in_password = md5($_POST['password']);
// 预处理
$sql = $conn->prepare("SELECT username,password FROM users WHERE username=? AND password=?");
// 绑定参数
$sql->bind_param('ss',$in_username, $in_password);
// 绑定结果
$sql->bind_result($username,$password);
// 执行语句
$sql->execute();
// 将结果与变量进行绑定
$sql->fetch();
// 关闭连接
$sql->close();
$conn->close();
if ($in_username === $username && $in_password === $password) {
echo "<script>alert('登录成功!欢迎用户: {$username}')</script>";
}else {
echo "<script>alert('登录失败,用户名或密码错误!')</script>";
}
}
?>
</body>
</html>

预处理语句的工作原理:

  • 预处理:创建 SQL 语句模板并发送到数据库。预留的值使用参数 "?" 标记 。例如:
1
INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)
  • 数据库解析,编译,对SQL语句模板执行查询优化,并存储结果不输出。
  • 执行:最后,将应用绑定的值传递给参数("?" 标记),数据库执行语句。应用可以多次执行语句,如果参数的值不一样。

相比于直接执行SQL语句,预处理语句有两个主要优点:

  • 预处理语句大大减少了分析时间,只做了一次查询(虽然语句多次执行)。
  • 绑定参数减少了服务器带宽,你只需要发送查询的参数,而不是整个语句。
  • 预处理语句针对SQL注入是非常有用的,因为参数值发送后使用不同的协议,保证了数据的合法性。

PDO 连接数据库

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
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
<?php 
// 数据库配置信息
define("DB_TYPE", "mysql");
define("DB_HOST", "127.0.0.1");
define("DB_USER", "root");
define("DB_PASS", "toor");
define("DB_NAME", "login");
define("DB_PORT", "3306");
define("DB_CHARSET", "utf8");

// 定义dsn信息
$tpl = '%s:host=%s;dbname=%s;port=%s;cahrset=%s';
$args = [DB_TYPE, DB_HOST, DB_NAME, DB_PORT, DB_CHARSET];
$dsn = sprintf($tpl, ...$args);

// 创建数据库连接对象并检查连接
try {
$conn = new PDO($dsn, DB_USER, DB_PASS);
// 设置结果集的默认获取模式:只要关联部分
$conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (PDOException $e) {
echo $e->getMessage();
}

?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login page</title>
</head>
<body>
<form method="post">
username: <input type="text" name="username" placeholder="请输入用户名">
<br>
password: <input type="password" name="password" placeholder="请输入密码">
<br>
<input type="submit" name="submit" value="login">
</form>
</body>
</html>

<?php
if (isset($_POST['username']) and isset($_POST['password']) and isset($_POST['submit'])) {
$in_username = $_POST['username'];
$in_password = md5($_POST['password']);
$sql = "SELECT `username`,`password` FROM `users` WHERE `username` = ? AND `password` = ? LIMIT 0,1";
// 预处理语句
$stmt = $conn->prepare($sql);
// 绑定参数
$stmt->bindParam(1, $in_username);
$stmt->bindParam(2, $in_password);
// 执行sql语句
$stmt->execute();
// 获取结果集
$result = $stmt->fetch();
if ($result['username'] === $in_username && $result['password'] === $in_password) {
echo "<script>alert('登录成功!欢迎用户: {$in_username}')</script>";
}else {
echo "<script>alert('登录失败,用户名或密码错误!')</script>";
}
}
?>

文件上传操作

文件上传示例

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
<!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" enctype="multipart/form-data">
<input type="file" name="file">
<br>
<br>
<button>上传</button>
</form>
</body>
</html>

<?php
if (isset($_FILES['file'])) {
define("UPLOAD_PATH", "uploads/");
$fileName = $_FILES['file']['name'];
$tmpPath = $_FILES['file']['tmp_name'];
$allowExt = ['jpg', 'png', 'jpeg', 'gif'];
$fileExt = pathinfo($fileName)['extension'];
$filePath = UPLOAD_PATH . date('YmdHis') . rand(1,99) . "." . $fileExt;
if (is_uploaded_file($tmpPath)) {
if (in_array($fileExt, $allowExt)) {
if (move_uploaded_file($tmpPath, $filePath)) {
echo '<p style="color:red">上传成功</p>';
echo "<img src='$filePath' width='200' >";
}
}else {
echo '<p style="color:red">文件类型错误</p>';
}
}
}
?>