PHP基础详解

1. PHP简述

详细解释

PHP(Hypertext Preprocessor,超文本预处理器)是一种通用开源脚本语言,主要用于Web开发。它最初被设计为服务器端脚本语言,现在已发展成为一种通用编程语言。

核心特点:

  • 开源免费:PHP是完全开源的,可以自由使用和修改
  • 跨平台:可以在Windows、Linux、macOS等操作系统上运行
  • 嵌入HTML:PHP代码可以嵌入到HTML中,便于Web开发
  • 服务器端执行:PHP代码在服务器上执行,结果以纯HTML形式返回给浏览器
  • 丰富的库:PHP拥有超过1000个内置函数,支持各种功能

PHP在Web开发中的角色:

  • 生成动态网页内容
  • 处理表单数据
  • 与数据库交互
  • 创建会话和Cookie
  • 生成图像和PDF
  • 与其他系统通信

PHP与Java/JavaScript的区别:

  • PHP是服务器端语言,Java可以是客户端也可以是服务器端
  • Java与JavaScript没有关系,只是名字相似
  • PHP执行在服务器上,JavaScript执行在客户端

示例

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
<?php
// PHP基本示例
echo "Hello, World!";

// 生成动态内容
$greeting = "Welcome to our website!";
$date = date("Y-m-d H:i:s");

echo "<h1>$greeting</h1>";
echo "<p>Current time: $date</p>";

// 表单处理示例
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$name = $_POST["name"] ?? "Guest";
echo "<p>Hello, $name! Your form was submitted successfully.</p>";
}
?>

<!DOCTYPE html>
<html>
<head>
<title>PHP Basic Example</title>
</head>
<body>
<h2>Simple Form</h2>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
<label for="name">Name:</label>
<input type="text" name="name" id="name">
<input type="submit" value="Submit">
</form>

<h3>Current Server Time</h3>
<?php echo date("Y-m-d H:i:s"); ?>
</body>
</html>

2. 基本语法格式

详细解释

PHP脚本以<?php开始,以?>结束。PHP代码可以嵌入到HTML中。

语法特点:

  • 标记:PHP代码需要放在特定的标记中
  • 注释:支持单行和多行注释
  • 变量:以$符号开头,后面跟着变量名
  • 语句:以分号;结束

PHP标记类型:

  • <?php ... ?>:标准标记(推荐)
  • <? ... ?>:短标记(需要在php.ini中启用short_open_tag)
  • <% ... %>:ASP风格标记(不推荐)
  • <script language="php"> ... </script>:脚本标记(不推荐)

变量命名规则:

  • 变量名必须以字母或下划线开头
  • 变量名可以包含字母、数字和下划线
  • 变量名区分大小写
  • 变量名不能包含空格

注释类型:

  • //:单行注释
  • #:单行注释(Unix风格)
  • /* ... */:多行注释

示例

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
<?php
// 标准PHP标记
echo "This is a standard PHP tag";

// 短标记(需要启用short_open_tag)
// <? echo "This is a short tag"; ?>

// 单行注释
echo "This is not a comment"; // This is a comment

# Another single-line comment

/*
* Multi-line comment
* This is line 2
* This is line 3
*/

// 变量声明
$myVariable = "Hello";
$number = 10;
$boolean = true;
$nullValue = null;

// 变量命名示例
$firstName = "John";
$last_name = "Doe";
$_private = "This is a private variable";
// $1stName = "Invalid"; // 以数字开头的变量名是无效的

// 语句以分号结束
$var1 = "Value 1";
$var2 = "Value 2";

// 混合HTML和PHP
?>
<h1><?php echo "Welcome to PHP"; ?></h1>
<p>This is HTML with PHP inside.</p>

<?php
// 代码块
if (true) {
echo "This is inside a code block";
}
?>

3. 数据类型、常量以及字符串

详细解释

PHP是一种弱类型语言,变量不需要显式声明类型,PHP会根据上下文自动确定类型。

PHP数据类型:

  • 标量类型boolean, integer, float, string
  • 复合类型array, object, callable, iterable
  • 特殊类型resource, null

常量:

  • 常量在定义后不可更改
  • 常量名通常大写
  • 常量名不需要$前缀
  • 常量可以是任何标量类型

字符串:

  • PHP支持单引号和双引号字符串
  • 双引号字符串会解析变量
  • 单引号字符串不会解析变量
  • 支持HEREDOC和NOWDOC语法

3.1 基本数据类型

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
<?php
// 布尔类型
$isTrue = true;
$isFalse = false;
var_dump($isTrue); // bool(true)
var_dump($isFalse); // bool(false)

// 整型
$int1 = 123; // 十进制
$int2 = 0123; // 八进制 (1*64 + 2*8 + 3 = 83)
$int3 = 0x1A; // 十六进制 (1*16 + 10 = 26)
$int4 = 0b101; // 二进制 (1*4 + 0*2 + 1 = 5)
var_dump($int1, $int2, $int3, $int4);

// 浮点型
$float1 = 3.14;
$float2 = 2.4e3; // 科学计数法 (2.4 * 10^3 = 2400)
var_dump($float1, $float2);

// 字符串
$string1 = 'This is a string';
$string2 = "This is a string with $float1";
$string3 = "This is a string with {$float1}"; // 使用花括号明确变量边界
var_dump($string1, $string2, $string3);

// NULL
$nullValue = null;
var_dump($nullValue); // NULL

// 数组
$array = array(1, 2, 3);
var_dump($array);

// 对象
class Person {
public $name;
}
$person = new Person();
$person->name = "John";
var_dump($person);

// 资源
$resource = fopen("example.txt", "r");
var_dump($resource);
fclose($resource);

3.2 常量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
// 定义常量
define("PI", 3.14159);
define("APP_NAME", "My Awesome App", true); // 第三个参数表示是否大小写不敏感

// 使用常量
echo "The value of PI is " . PI . "\n";
echo "App name: " . APP_NAME . "\n";

// 大小写敏感性
// echo app_name; // 如果第三个参数为false,这会报错
echo app_name; // 如果第三个参数为true,这会输出 "My Awesome App"

// 预定义常量
echo "Current file: " . __FILE__ . "\n";
echo "Current line: " . __LINE__ . "\n";
echo "PHP version: " . PHP_VERSION . "\n";
echo "OS: " . PHP_OS . "\n";

// 动态常量
$constantName = "PI";
echo "Value of $constantName: " . constant($constantName) . "\n";

3.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
42
43
44
45
46
47
48
49
50
51
<?php
// 字符串操作
$str1 = "Hello";
$str2 = "World";
$concat = $str1 . " " . $str2; // 字符串连接
echo "Concatenated: " . $concat . "\n";

// 字符串长度
echo "Length of '$concat': " . strlen($concat) . "\n";

// 字符串查找
$position = strpos($concat, "World");
echo "Position of 'World': " . $position . "\n";

// 字符串替换
$replaced = str_replace("World", "PHP", $concat);
echo "Replaced: " . $replaced . "\n";

// 字符串截取
$substring = substr($replaced, 0, 5);
echo "Substring: " . $substring . "\n";

// 字符串大小写转换
echo "Uppercase: " . strtoupper($replaced) . "\n";
echo "Lowercase: " . strtolower($replaced) . "\n";

// 字符串分割
$words = explode(" ", $replaced);
echo "Words: ";
print_r($words);

// 字符串格式化
$price = 19.99;
$formatted = sprintf("Price: $%.2f", $price);
echo "Formatted price: " . $formatted . "\n";

// HEREDOC语法
$heredoc = <<<EOT
This is a heredoc string.
It can span multiple lines.
Variables like $price will be parsed.
EOT;
echo "HEREDOC: " . $heredoc . "\n";

// NOWDOC语法(不解析变量)
$nowdoc = <<<'EOT'
This is a nowdoc string.
It can span multiple lines.
Variables like $price will NOT be parsed.
EOT;
echo "NOWDOC: " . $nowdoc . "\n";

4. 运算符

详细解释

PHP支持多种运算符,用于执行各种操作。

主要运算符类型:

  • 算术运算符+, -, *, /, %, **, ++, --
  • 赋值运算符=, +=, -=, *=, /=, %=, **=
  • 比较运算符==, !=, ===, !==, >, <, >=, <=
  • 逻辑运算符&&, ||, !, and, or, xor
  • 三元运算符? :
  • 其他运算符.(字符串连接),??(空合并)

4.1 算术运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
$a = 10;
$b = 3;

// 基本算术
echo "Addition: " . ($a + $b) . "\n"; // 13
echo "Subtraction: " . ($a - $b) . "\n"; // 7
echo "Multiplication: " . ($a * $b) . "\n"; // 30
echo "Division: " . ($a / $b) . "\n"; // 3.333...
echo "Modulo: " . ($a % $b) . "\n"; // 1
echo "Exponentiation: " . ($a ** $b) . "\n"; // 1000

// 递增/递减
$c = 5;
echo "Pre-increment: " . ++$c . "\n"; // 6
echo "Post-increment: " . $c++ . "\n"; // 6 (but $c is now 7
echo "Value after post-increment: " . $c . "\n"; // 7
echo "Pre-decrement: " . --$c . "\n"; // 6
echo "Post-decrement: " . $c-- . "\n"; // 6 (but $c is now 5
echo "Value after post-decrement: " . $c . "\n"; // 5

4.2 赋值运算符

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
$a = 10;
echo "Initial value: " . $a . "\n"; // 10

// 简单赋值
$a = 20;
echo "After simple assignment: " . $a . "\n"; // 20

// 复合赋值
$a += 5; // $a = $a + 5
echo "After +=: " . $a . "\n"; // 25

$a -= 3; // $a = $a - 3
echo "After -=: " . $a . "\n"; // 22

$a *= 2; // $a = $a * 2
echo "After *=: " . $a . "\n"; // 44

$a /= 4; // $a = $a / 4
echo "After /=: " . $a . "\n"; // 11

$a %= 3; // $a = $a % 3
echo "After %=: " . $a . "\n"; // 2

$a **= 3; // $a = $a ** 3
echo "After **=: " . $a . "\n"; // 8

4.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
<?php
$a = 5;
$b = "5";
$c = 10;

// 相等比较
echo "5 == 5: " . ($a == $a) . "\n"; // 1 (true)
echo "5 == '5': " . ($a == $b) . "\n"; // 1 (true)
echo "5 === 5: " . ($a === $a) . "\n"; // 1 (true)
echo "5 === '5': " . ($a === $b) . "\n"; // (empty string) (false)

// 不等比较
echo "5 != 10: " . ($a != $c) . "\n"; // 1 (true)
echo "5 !== '5': " . ($a !== $b) . "\n"; // 1 (true)

// 大小比较
echo "5 < 10: " . ($a < $c) . "\n"; // 1 (true)
echo "5 > 10: " . ($a > $c) . "\n"; // (empty string) (false)
echo "5 <= 5: " . ($a <= $a) . "\n"; // 1 (true)
echo "5 >= 10: " . ($a >= $c) . "\n"; // (empty string) (false)

// 空合并运算符 (PHP 7+)
$var1 = null;
$var2 = "Default value";
echo "Value: " . ($var1 ?? $var2) . "\n"; // "Default value"
echo "Value: " . ($var2 ?? "Another default") . "\n"; // "Default value"

4.4 逻辑运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
$age = 25;
$isStudent = true;
$hasDiscount = false;

// 逻辑与
echo "Adult and student: " . ($age >= 18 && $isStudent) . "\n"; // 1 (true)
echo "Adult and not student: " . ($age >= 18 && !$isStudent) . "\n"; // (empty string) (false)

// 逻辑或
echo "Student or has discount: " . ($isStudent || $hasDiscount) . "\n"; // 1 (true)
echo "Not student and no discount: " . (!$isStudent || !$hasDiscount) . "\n"; // 1 (true)

// 逻辑非
echo "Not student: " . (!$isStudent) . "\n"; // (empty string) (false)

// 逻辑运算符优先级
echo "Complex expression: " . ($age >= 18 && $isStudent || $hasDiscount) . "\n"; // 1 (true)
echo "Complex expression with parentheses: " . ($age >= 18 && ($isStudent || $hasDiscount)) . "\n"; // 1 (true)

4.5 三元运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
$age = 25;
$isStudent = true;

// 基本三元运算符
$greeting = ($age >= 18) ? "Adult" : "Minor";
echo "Greeting: " . $greeting . "\n"; // "Adult"

// 嵌套三元运算符
$discount = ($age >= 65) ? "Senior" : ($isStudent ? "Student" : "Regular");
echo "Discount: " . $discount . "\n"; // "Student"

// 空合并运算符 (PHP 7+)
$username = null;
$displayName = $username ?? "Guest";
echo "Display name: " . $displayName . "\n"; // "Guest"

// 短路三元运算符 (PHP 7.4+)
$role = "admin";
$permission = $role === "admin" ? "Full access" : ($role === "editor" ? "Edit access" : "View only");
echo "Permission: " . $permission . "\n"; // "Full access"

5. 控制语句

详细解释

控制语句用于控制程序的执行流程。

主要控制语句:

  • 条件语句if, if...else, if...elseif...else, switch
  • 循环语句while, do...while, for, foreach
  • 流程控制语句break, continue, return, exit

5.1 条件语句

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
<?php
$score = 85;

// if语句
if ($score >= 90) {
echo "Excellent!\n";
}

// if...else语句
if ($score >= 60) {
echo "Passed!\n";
} else {
echo "Failed!\n";
}

// if...elseif...else语句
if ($score >= 90) {
echo "A - Excellent!\n";
} elseif ($score >= 80) {
echo "B - Good!\n";
} elseif ($score >= 70) {
echo "C - Satisfactory!\n";
} elseif ($score >= 60) {
echo "D - Needs improvement!\n";
} else {
echo "F - Failed!\n";
}

// switch语句
$day = date("l"); // 获取当前星期

switch ($day) {
case "Monday":
echo "Start of the work week.\n";
break;
case "Tuesday":
case "Wednesday":
case "Thursday":
echo "Midweek.\n";
break;
case "Friday":
echo "End of the work week.\n";
break;
case "Saturday":
case "Sunday":
echo "Weekend!\n";
break;
default:
echo "Unknown day.\n";
}

5.2 循环语句

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
<?php
// while循环
$i = 1;
while ($i <= 5) {
echo "While loop: $i\n";
$i++;
}

// do...while循环
$j = 1;
do {
echo "Do...while loop: $j\n";
$j++;
} while ($j <= 5);

// for循环
for ($k = 1; $k <= 5; $k++) {
echo "For loop: $k\n";
}

// foreach循环(数组)
$colors = ["red", "green", "blue"];
foreach ($colors as $color) {
echo "Color: $color\n";
}

// foreach循环(关联数组)
$person = [
"name" => "John",
"age" => 30,
"city" => "New York"
];
foreach ($person as $key => $value) {
echo "Person $key: $value\n";
}

5.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
<?php
// break语句
for ($i = 1; $i <= 10; $i++) {
if ($i == 5) {
break; // 退出循环
}
echo "Break example: $i\n";
}

// continue语句
for ($i = 1; $i <= 5; $i++) {
if ($i == 3) {
continue; // 跳过本次迭代
}
echo "Continue example: $i\n";
}

// return语句(在函数中)
function getGreeting($name) {
if (empty($name)) {
return "Hello, Guest!";
}
return "Hello, $name!";
}
echo getGreeting("Alice") . "\n";
echo getGreeting(" ") . "\n";

// exit语句
$shouldExit = false;
if ($shouldExit) {
echo "Exiting...\n";
exit;
}
echo "This will be printed if shouldExit is false.\n";

6. PHP数组

详细解释

PHP数组是一种有序映射,可以存储多个值。

数组类型:

  • 索引数组:数字键名
  • 关联数组:字符串键名
  • 多维数组:数组中包含数组

数组操作:

  • 创建数组
  • 添加元素
  • 删除元素
  • 遍历数组
  • 数组排序
  • 数组函数

6.1 数组的创建与操作

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
<?php
// 创建索引数组
$fruits = array("Apple", "Banana", "Cherry");
// 或
$fruits = ["Apple", "Banana", "Cherry"];

// 创建关联数组
$person = array(
"name" => "John",
"age" => 30,
"city" => "New York"
);
// 或
$person = [
"name" => "John",
"age" => 30,
"city" => "New York"
];

// 创建多维数组
$students = [
["id" => 1, "name" => "Alice", "age" => 20],
["id" => 2, "name" => "Bob", "age" => 22],
["id" => 3, "name" => "Charlie", "age" => 21]
];

// 访问数组元素
echo "First fruit: " . $fruits[0] . "\n";
echo "Person name: " . $person["name"] . "\n";
echo "Second student name: " . $students[1]["name"] . "\n";

// 修改数组元素
$fruits[1] = "Blueberry";
$person["age"] = 31;

// 添加元素
$fruits[] = "Date"; // 添加到末尾
$person["email"] = "john@example.com"; // 添加新键值对

// 删除元素
unset($fruits[0]); // 删除索引0的元素
unset($person["city"]); // 删除"city"键

// 检查元素是否存在
echo "Fruit 'Banana' exists: " . (in_array("Banana", $fruits) ? "Yes" : "No") . "\n";
echo "Key 'email' exists: " . (array_key_exists("email", $person) ? "Yes" : "No") . "\n";

// 数组长度
echo "Number of fruits: " . count($fruits) . "\n";

6.2 数组函数

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
<?php
$numbers = [5, 3, 8, 1, 9, 4, 2, 7, 6];

// 排序函数
$sorted = $numbers;
sort($sorted); // 升序
echo "Sorted: " . implode(", ", $sorted) . "\n";

$sorted = $numbers;
rsort($sorted); // 降序
echo "Reverse sorted: " . implode(", ", $sorted) . "\n";

// 关联数组排序
$ages = [
"Alice" => 20,
"Bob" => 22,
"Charlie" => 21
];
asort($ages); // 按值排序
echo "Ages sorted by value: ";
foreach ($ages as $name => $age) {
echo "$name($age), ";
}
echo "\n";

ksort($ages); // 按键排序
echo "Ages sorted by key: ";
foreach ($ages as $name => $age) {
echo "$name($age), ";
}
echo "\n";

// 数组操作函数
$colors = ["red", "green", "blue"];
array_push($colors, "yellow"); // 添加到末尾
array_unshift($colors, "purple"); // 添加到开头
echo "After push and unshift: " . implode(", ", $colors) . "\n";

$last = array_pop($colors); // 移除末尾元素
$first = array_shift($colors); // 移除开头元素
echo "After pop and shift: " . implode(", ", $colors) . "\n";

// 数组切片
$subset = array_slice($colors, 1, 2); // 从索引1开始,取2个元素
echo "Array slice: " . implode(", ", $subset) . "\n";

// 数组映射
$squared = array_map(function($n) { return $n * $n; }, $numbers);
echo "Squared numbers: " . implode(", ", $squared) . "\n";

// 数组过滤
$even = array_filter($numbers, function($n) { return $n % 2 == 0; });
echo "Even numbers: " . implode(", ", $even) . "\n";

// 数组合并
$colors1 = ["red", "green"];
$colors2 = ["blue", "yellow"];
$allColors = array_merge($colors1, $colors2);
echo "Merged colors: " . implode(", ", $allColors) . "\n";

7. PHP 函数

详细解释

函数是可重用的代码块,用于执行特定任务。

函数特点:

  • 可以接受参数
  • 可以返回值
  • 可以有默认参数
  • 可以有类型声明(PHP 7+)
  • 支持可变参数(PHP 5.6+)

函数类型:

  • 用户定义函数:开发者创建的函数
  • 内置函数:PHP自带的函数
  • 匿名函数:没有名称的函数

7.1 函数定义与调用

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
<?php
// 基本函数
function greet($name) {
return "Hello, $name!";
}
echo greet("Alice") . "\n";

// 带默认参数的函数
function sayHello($name = "Guest") {
return "Hello, $name!";
}
echo sayHello() . "\n";
echo sayHello("Bob") . "\n";

// 返回多个值(通过数组)
function getPerson() {
return [
"name" => "Charlie",
"age" => 30,
"city" => "London"
];
}
$person = getPerson();
echo "Person name: " . $person["name"] . "\n";

// 类型声明(PHP 7+)
function add(int $a, int $b): int {
return $a + $b;
}
echo "5 + 3 = " . add(5, 3) . "\n";

// 可变参数(PHP 5.6+)
function sum(...$numbers) {
return array_sum($numbers);
}
echo "Sum: " . sum(1, 2, 3, 4, 5) . "\n";

// 匿名函数
$greet = function($name) {
return "Hi, $name!";
};
echo $greet("Dave") . "\n";

// 闭包(访问外部变量)
$prefix = "Welcome";
$greetWithPrefix = function($name) use ($prefix) {
return "$prefix, $name!";
};
echo $greetWithPrefix("Eve") . "\n";

7.2 函数高级特性

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
// 递归函数
function factorial($n) {
if ($n <= 1) {
return 1;
}
return $n * factorial($n - 1);
}
echo "Factorial of 5: " . factorial(5) . "\n";

// 生成器(PHP 5.5+)
function rangeGenerator($start, $end) {
for ($i = $start; $i <= $end; $i++) {
yield $i;
}
}
foreach (rangeGenerator(1, 5) as $number) {
echo "Number: $number\n";
}

// 通过引用传递参数
function increment(&$value) {
$value++;
}
$counter = 10;
increment($counter);
echo "Counter after increment: $counter\n";

// 函数作为参数
function apply($value, callable $callback) {
return $callback($value);
}
$squared = apply(5, function($n) { return $n * $n; });
echo "5 squared: $squared\n";

8. PHP 变量作用域

详细解释

变量作用域决定了变量在哪些部分可以被访问。

主要作用域:

  • 局部作用域:在函数内部声明的变量
  • 全局作用域:在函数外部声明的变量
  • 静态作用域:使用static关键字声明的变量

变量作用域特点:

  • 局部变量在函数执行完毕后销毁
  • 全局变量在脚本执行期间一直存在
  • 静态变量在函数执行完毕后保留其值

8.1 局部变量与全局变量

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
// 全局变量
$globalVar = "I'm global";

function testScope() {
// 局部变量
$localVar = "I'm local";

// 访问全局变量
global $globalVar;
echo "Global variable: $globalVar\n";

// 修改全局变量
$globalVar = "Modified global";

// 尝试访问外部变量(会报错)
// echo $externalVar;
}

// 调用函数
testScope();

// 检查全局变量是否被修改
echo "Global variable after function: $globalVar\n";

// 尝试访问局部变量(会报错)
// echo $localVar;

8.2 使用$GLOBAL数组

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$globalVar = "Original global value";

function testGlobalArray() {
// 使用$GLOBAL数组访问全局变量
$GLOBALS['globalVar'] = "Modified global value";
}

// 调用函数
testGlobalArray();

// 检查全局变量是否被修改
echo "Global variable: " . $globalVar . "\n";

8.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
<?php
function counter() {
// 静态变量,函数执行后保留其值
static $count = 0;
$count++;
return $count;
}

echo "Counter 1: " . counter() . "\n"; // 1
echo "Counter 2: " . counter() . "\n"; // 2
echo "Counter 3: " . counter() . "\n"; // 3

// 静态变量在函数外部不可访问
// echo $count; // 会报错

// 静态变量示例:缓存计算结果
function fibonacci($n) {
static $cache = [];

if (isset($cache[$n])) {
return $cache[$n];
}

if ($n <= 1) {
$result = $n;
} else {
$result = fibonacci($n - 1) + fibonacci($n - 2);
}

$cache[$n] = $result;
return $result;
}

echo "Fibonacci(10): " . fibonacci(10) . "\n"; // 55
echo "Fibonacci(20): " . fibonacci(20) . "\n"; // 6765

9. 类与对象

详细解释

PHP支持面向对象编程(OOP),允许开发者创建类和对象。

核心概念:

  • :对象的蓝图或模板
  • 对象:类的实例
  • 属性:类的变量
  • 方法:类的函数
  • 构造函数:对象创建时自动调用的方法
  • 析构函数:对象销毁时自动调用的方法
  • 继承:子类继承父类的属性和方法
  • 多态:同一方法在不同对象中有不同实现
  • 静态成员:属于类而非对象的成员
  • 静态方法:可以直接通过类名调用的方法

访问控制:

  • public:任何地方都可以访问
  • protected:类内部和子类可以访问
  • private:仅类内部可以访问
  • static:静态成员或方法,可直接通过类名访问

9.1 基本类与对象

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
<?php
class Person {
// 属性
public $name;
public $age;
// 静态成员变量
public static $count = 0;

// 构造函数
public function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
// 每创建一个对象,静态计数器增加
self::$count++;
}

// 方法
public function greet() {
return "Hello, my name is " . $this->name . " and I am " . $this->age . " years old.";
}

// 静态方法
public static function createDefault() {
return new Person("Anonymous", 0);
}

// 静态方法访问静态成员
public static function getCount() {
return "Total persons created: " . self::$count;
}
}

// 创建对象
$person1 = new Person("Alice", 25);
echo $person1->greet() . "\n";

// 访问静态成员
echo Person::$count . "\n"; // 1

// 使用静态方法
$person2 = Person::createDefault();
echo $person2->greet() . "\n";

// 调用静态方法
echo Person::getCount() . "\n"; // Total persons created: 2

// 访问属性
echo "Name: " . $person1->name . "\n";

// 检查对象类型
echo "Is Person: " . (is_a($person1, 'Person') ? "Yes" : "No") . "\n";

9.2 继承与多态

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?php
abstract class Animal {
protected $name;
protected $species;
// 静态成员变量
protected static $animalCount = 0;

public function __construct(string $name, string $species) {
$this->name = $name;
$this->species = $species;
// 每创建一个动物,静态计数器增加
self::$animalCount++;
}

public function getName(): string {
return $this->name;
}

public function getSpecies(): string {
return $this->species;
}

// 静态方法:获取动物总数
public static function getAnimalCount(): int {
return self::$animalCount;
}

// 抽象方法
abstract public function makeSound(): string;

// 多态核心:不同动物移动方式不同
abstract public function move(): string;

// 公共行为(所有动物共享)
public function introduce(): string {
return "I'm {$this->name}, a {$this->species}.";
}
}

class Dog extends Animal {
public function __construct(string $name) {
parent::__construct($name, "Dog");
}

// 实现抽象方法
public function makeSound(): string {
return "Woof! Woof!";
}

// 实现抽象方法
public function move(): string {
return "runs on four legs";
}

// 子类特有行为
public function fetch(string $item): string {
return "{$this->name} is fetching the {$item}!";
}
}

class Cat extends Animal {
public function __construct(string $name) {
parent::__construct($name, "Cat");
}

public function makeSound(): string {
return "Meow! Meow!";
}

public function move(): string {
return "sneaks silently";
}

public function scratch(string $surface): string {
return "{$this->name} is scratching the {$surface}!";
}
}

class Bird extends Animal {
public function __construct(string $name) {
parent::__construct($name, "Bird");
}

public function makeSound(): string {
return "Chirp! Chirp!";
}

public function move(): string {
return "flies through the air";
}

public function layEggs(int $count): string {
return "{$this->name} laid {$count} eggs.";
}
}

// 多态函数:接受任何Animal子类
function observeAnimal(Animal $animal): void {
echo $animal->introduce() . "\n";
echo " - Sound: " . $animal->makeSound() . "\n";
echo " - Movement: " . $animal->move() . "\n";

// 类型检测:安全调用子类特有方法
if ($animal instanceof Dog) {
echo " - Special: " . $animal->fetch("ball") . "\n";
} else if ($animal instanceof Cat) {
echo " - Special: " . $animal->scratch("couch") . "\n";
} else if ($animal instanceof Bird) {
echo " - Special: " . $animal->layEggs(3) . "\n";
}

echo "------------------------\n";
}

// 创建不同动物
$animals = [
new Dog("Buddy"),
new Cat("Whiskers"),
new Bird("Tweety")
];

// 统一处理所有动物
foreach ($animals as $animal) {
observeAnimal($animal);
}

// 使用静态方法获取动物总数
echo "Total animals created: " . Animal::getAnimalCount() . "\n";

9.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
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
<?php
// 接口
interface Shape {
public function getArea();
public function getPerimeter();
}

// 抽象类
abstract class GeometricShape implements Shape {
protected $color;
// 静态成员变量
protected static $shapeCount = 0;

public function __construct($color) {
$this->color = $color;
// 每创建一个形状,静态计数器增加
self::$shapeCount++;
}

public function getColor() {
return $this->color;
}

// 静态方法
public static function getShapeCount() {
return self::$shapeCount;
}

// 抽象方法
abstract public function getArea();
abstract public function getPerimeter();
}

// 具体实现
class Circle extends GeometricShape {
private $radius;

public function __construct($color, $radius) {
parent::__construct($color);
$this->radius = $radius;
}

public function getArea() {
return pi() * $this->radius * $this->radius;
}

public function getPerimeter() {
return 2 * pi() * $this->radius;
}
}

class Rectangle extends GeometricShape {
private $width;
private $height;

public function __construct($color, $width, $height) {
parent::__construct($color);
$this->width = $width;
$this->height = $height;
}

public function getArea() {
return $this->width * $this->height;
}

public function getPerimeter() {
return 2 * ($this->width + $this->height);
}
}

// 使用接口
function printShapeInfo(Shape $shape) {
echo "Shape info:\n";
echo "- Area: " . $shape->getArea() . "\n";
echo "- Perimeter: " . $shape->getPerimeter() . "\n";
if ($shape instanceof GeometricShape) {
echo "- Color: " . $shape->getColor() . "\n";
}
}

$circle = new Circle("red", 5);
$rectangle = new Rectangle("blue", 4, 6);

printShapeInfo($circle);
printShapeInfo($rectangle);

// 使用静态方法获取形状总数
echo "Total shapes created: " . GeometricShape::getShapeCount() . "\n";

9.4 静态方法与静态属性详解

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
<?php
class Database {
// 静态属性 - 单例模式
private static $instance = null;
private $connection;

// 私有构造函数 - 防止直接实例化
private function __construct($host, $username, $password, $database) {
$this->connection = new mysqli($host, $username, $password, $database);
}

// 静态方法 - 获取单例实例
public static function getInstance($host = 'localhost', $username = 'root', $password = '', $database = 'test') {
if (self::$instance === null) {
self::$instance = new self($host, $username, $password, $database);
}
return self::$instance;
}

// 静态方法 - 直接执行查询
public static function query($sql, $params = []) {
$instance = self::getInstance();
$stmt = $instance->connection->prepare($sql);
if ($params) {
$types = str_repeat('s', count($params));
$stmt->bind_param($types, ...$params);
}
$stmt->execute();
return $stmt->get_result();
}

// 静态实用方法
public static function sanitize($input) {
return htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
}

// 防止克隆
private function __clone() {}

// 防止反序列化
private function __wakeup() {}
}

// 使用单例模式
$db = Database::getInstance();
$results = Database::query("SELECT * FROM users WHERE name = ?", ["John"]);
while ($row = $results->fetch_assoc()) {
echo "User: " . Database::sanitize($row['name']) . "<br>";
}

// 静态实用类示例
class MathUtils {
// 静态常量
const PI = 3.14159265359;

// 静态属性
private static $instances = 0;

// 静态方法
public static function add($a, $b) {
self::$instances++;
return $a + $b;
}

public static function multiply($a, $b) {
self::$instances++;
return $a * $b;
}

public static function getInstanceCount() {
return self::$instances;
}

// 静态方法使用静态常量
public static function circleArea($radius) {
return self::PI * $radius * $radius;
}
}

// 使用静态方法
echo "2 + 3 = " . MathUtils::add(2, 3) . "<br>";
echo "4 * 5 = " . MathUtils::multiply(4, 5) . "<br>";
echo "Circle area (radius=5): " . MathUtils::circleArea(5) . "<br>";
echo "Total method calls: " . MathUtils::getInstanceCount() . "<br>";

9.5 命名空间

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
<?php
// 命名空间示例
namespace MyProject\Utils;

class StringHelper {
// 静态成员变量
private static $instanceCount = 0;

// 构造函数
public function __construct() {
self::$instanceCount++;
}

// 静态方法
public static function reverse($string) {
self::$instanceCount++;
return strrev($string);
}

// 静态方法访问静态成员
public static function getInstanceCount() {
return self::$instanceCount;
}
}

// 另一个命名空间
namespace MyProject\Database;

class Connection {
// 静态连接实例
private static $connection = null;

// 静态方法
public static function connect($host, $username, $password, $database) {
if (self::$connection === null) {
self::$connection = new \mysqli($host, $username, $password, $database);
}
return self::$connection;
}

// 静态方法
public static function disconnect() {
if (self::$connection !== null) {
self::$connection->close();
self::$connection = null;
}
}
}

// 使用命名空间
namespace Main;

// 导入命名空间
use MyProject\Utils\StringHelper;
use MyProject\Database\Connection as DB;

// 使用静态方法
echo StringHelper::reverse("Hello") . "\n"; // olleH
echo "StringHelper instances: " . StringHelper::getInstanceCount() . "\n"; // 1

// 创建实例会增加计数
new StringHelper();
echo "StringHelper instances: " . StringHelper::getInstanceCount() . "\n"; // 2

// 使用别名
$conn = DB::connect("localhost", "root", "password", "test_db");
echo "Database connected\n";

// 完全限定名称
echo \MyProject\Utils\StringHelper::reverse("World") . "\n"; // dlroW
echo "StringHelper instances: " . \MyProject\Utils\StringHelper::getInstanceCount() . "\n"; // 3

// 关闭数据库连接
DB::disconnect();
echo "Database disconnected\n";

10. PHP超级全局变量

详细解释

超级全局变量是PHP预定义的全局数组,可以在脚本的任何作用域中访问。

主要超级全局变量:

  • $GLOBALS:引用全局作用域中可用的全部变量
  • $_SERVER:服务器和执行环境信息
  • $_GET:HTTP GET方法传递的变量
  • $_POST:HTTP POST方法传递的变量
  • $_FILES:HTTP文件上传变量
  • $_COOKIE:HTTP Cookies
  • $_SESSION:会话变量
  • $_REQUEST:HTTP请求变量(GET, POST, COOKIE)
  • $_ENV:环境变量

示例

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
<?php
// $GLOBALS
$globalVar = "I'm global";
function testGlobal() {
echo $GLOBALS['globalVar'] . "\n";
}
testGlobal();

// $_SERVER
echo "Server name: " . $_SERVER['SERVER_NAME'] . "\n";
echo "Request URI: " . $_SERVER['REQUEST_URI'] . "\n";
echo "User Agent: " . $_SERVER['HTTP_USER_AGENT'] . "\n";

// $_GET
// 假设URL为: example.com/test.php?name=Alice&age=25
echo "Name from GET: " . ($_GET['name'] ?? 'Not provided') . "\n";
echo "Age from GET: " . ($_GET['age'] ?? 'Not provided') . "\n";

// $_POST
// 假设表单提交了name和email字段
if ($_SERVER["REQUEST_METHOD"] == "POST") {
echo "Name from POST: " . ($_POST['name'] ?? 'Not provided') . "\n";
echo "Email from POST: " . ($_POST['email'] ?? 'Not provided') . "\n";
}

// $_COOKIE
// 设置Cookie
setcookie("username", "Alice", time() + 3600);
echo "Username Cookie: " . ($_COOKIE['username'] ?? 'Not set') . "\n";

// $_SESSION
session_start();
$_SESSION['user'] = "Alice";
echo "User in session: " . ($_SESSION['user'] ?? 'Not set') . "\n";

// $_REQUEST
echo "Name from REQUEST: " . ($_REQUEST['name'] ?? 'Not provided') . "\n";

// $_FILES
// 用于文件上传
if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_FILES["file"])) {
$file = $_FILES["file"];
echo "Uploaded file: " . $file["name"] . "\n";
echo "File type: " . $file["type"] . "\n";
}

11. PHP Include 文件

详细解释

PHP提供文件包含机制,允许将一个PHP文件的内容包含到另一个PHP文件中。

主要文件包含函数:

  • include:包含文件,如果文件不存在,产生警告,脚本继续执行
  • require:包含文件,如果文件不存在,产生致命错误,脚本终止
  • include_once:与include相同,但确保文件只被包含一次
  • require_once:与require相同,但确保文件只被包含一次

文件包含特点:

  • 可以包含任意类型的文件(.php, .html, .txt等)
  • 包含的文件会执行其中的PHP代码
  • 被包含文件可以访问包含文件的变量(根据作用域规则)

11.1 基本文件包含

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
<?php
// header.php
?>
<header>
<h1>My Website</h1>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</nav>
</header>

<?php
// footer.php
?>
<footer>
<p>&copy; 2023 My Website. All rights reserved.</p>
</footer>

<?php
// index.php
?>
<!DOCTYPE html>
<html>
<head>
<title>My Website</title>
</head>
<body>
<?php include 'header.php'; ?>

<main>
<h2>Welcome to My Website</h2>
<p>This is the main content of the page.</p>
</main>

<?php include 'footer.php'; ?>
</body>
</html>

11.2 文件包含高级用法

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
// config.php
$databaseConfig = [
'host' => 'localhost',
'username' => 'root',
'password' => 'password',
'database' => 'myapp'
];

// functions.php
function formatCurrency($amount) {
return '$' . number_format($amount, 2);
}

// 工具类
class FileHelper {
// 静态方法
public static function getFileExtension($filename) {
return pathinfo($filename, PATHINFO_EXTENSION);
}

public static function sanitizeFilename($filename) {
return preg_replace('/[^a-zA-Z0-9\.\-_]/', '', $filename);
}
}

// main.php
// 使用require_once确保配置只加载一次
require_once 'config.php';
require_once 'functions.php';

// 使用静态方法
$filename = "document.pdf";
$extension = FileHelper::getFileExtension($filename);
$safeName = FileHelper::sanitizeFilename("report/2023!.pdf");

// 使用配置
$dsn = "mysql:host={$databaseConfig['host']};dbname={$databaseConfig['database']}";
// ...数据库连接代码...

// 使用函数
echo "Price: " . formatCurrency(19.99) . "\n";
echo "File extension: " . $extension . "\n";
echo "Sanitized filename: " . $safeName . "\n";

// 动态包含
$page = $_GET['page'] ?? 'home';
$validPages = ['home', 'about', 'contact'];

if (in_array($page, $validPages)) {
include "$page.php";
} else {
include "404.php";
}

12. PHP 文件处理

详细解释

PHP提供了一套完整的文件操作函数,用于读取、写入、创建和删除文件。

主要文件操作函数:

  • fopen():打开文件
  • fclose():关闭文件
  • fread():读取文件
  • fwrite():写入文件
  • file_get_contents():读取整个文件到字符串
  • file_put_contents():将字符串写入文件
  • file():读取文件到数组
  • file_exists():检查文件是否存在
  • is_file():检查是否为文件
  • is_dir():检查是否为目录
  • mkdir():创建目录
  • rmdir():删除目录
  • unlink():删除文件
  • rename():重命名文件或目录

12.1 基本文件操作

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
// 创建和写入文件
$filename = "example.txt";
$content = "Hello, World!\nThis is a test file.\n";

// 使用fopen和fwrite
$handle = fopen($filename, "w");
fwrite($handle, $content);
fclose($handle);

// 使用file_put_contents(更简单)
file_put_contents($filename, $content);

// 读取文件
$contents = file_get_contents($filename);
echo "File contents:\n$contents\n";

// 逐行读取
$lines = file($filename);
echo "Lines:\n";
foreach ($lines as $line) {
echo $line;
}

// 检查文件是否存在
if (file_exists($filename)) {
echo "File exists.\n";
}

// 获取文件信息
echo "File size: " . filesize($filename) . " bytes\n";
echo "File last modified: " . date("Y-m-d H:i:s", filemtime($filename)) . "\n";

12.2 高级文件操作

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<?php
// 创建目录
$dir = "uploads";
if (!file_exists($dir)) {
mkdir($dir, 0777, true);
echo "Directory created.\n";
}

// 递归读取目录
function listFiles($dir) {
$files = [];
if ($handle = opendir($dir)) {
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
$path = $dir . '/' . $entry;
if (is_dir($path)) {
$files = array_merge($files, listFiles($path));
} else {
$files[] = $path;
}
}
}
closedir($handle);
}
return $files;
}

$allFiles = listFiles(".");
echo "All files:\n";
foreach ($allFiles as $file) {
echo $file . "\n";
}

// 文件复制和移动
$source = "example.txt";
$destination = "backup/example.txt";

// 创建备份目录
if (!file_exists("backup")) {
mkdir("backup");
}

// 复制文件
if (copy($source, $destination)) {
echo "File copied successfully.\n";
}

// 重命名/移动文件
$renamed = "example_backup.txt";
if (rename($source, $renamed)) {
echo "File renamed successfully.\n";
}

// 删除文件
if (file_exists($renamed)) {
unlink($renamed);
echo "File deleted.\n";
}

// 创建静态文件处理器
class FileProcessor {
private static $instance = null;
private $logFile;

private function __construct($logFile = 'file_log.txt') {
$this->logFile = $logFile;
}

public static function getInstance($logFile = 'file_log.txt') {
if (self::$instance === null) {
self::$instance = new self($logFile);
}
return self::$instance;
}

public static function createFile($filename, $content = '') {
$instance = self::getInstance();
$result = file_put_contents($filename, $content);
$instance->log("Created file: $filename");
return $result !== false;
}

public static function readFile($filename) {
$instance = self::getInstance();
if (!file_exists($filename)) {
$instance->log("File not found: $filename");
return false;
}
$instance->log("Read file: $filename");
return file_get_contents($filename);
}

private function log($message) {
$timestamp = date('Y-m-d H:i:s');
$logEntry = "[$timestamp] $message\n";
file_put_contents($this->logFile, $logEntry, FILE_APPEND);
}

private function __clone() {}
}

// 使用静态方法
FileProcessor::createFile('test.txt', 'This is a test file.');
$content = FileProcessor::readFile('test.txt');
echo $content . "\n";

13. PHP获取文件属性

详细解释

PHP提供了一系列函数来获取文件的属性信息,如大小、类型、权限等。

主要文件属性函数:

  • file_exists():检查文件是否存在
  • is_file():检查是否为文件
  • is_dir():检查是否为目录
  • is_readable():检查文件是否可读
  • is_writable():检查文件是否可写
  • fileatime():获取文件上次访问时间
  • filemtime():获取文件上次修改时间
  • filectime():获取文件创建时间
  • filesize():获取文件大小
  • filetype():获取文件类型

示例

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
90
91
92
<?php
$filename = "example.txt";

// 检查文件是否存在
if (file_exists($filename)) {
echo "File exists.\n";

// 检查文件类型
echo "Is file: " . (is_file($filename) ? "Yes" : "No") . "\n";
echo "Is directory: " . (is_dir($filename) ? "Yes" : "No") . "\n";

// 检查权限
echo "Is readable: " . (is_readable($filename) ? "Yes" : "No") . "\n";
echo "Is writable: " . (is_writable($filename) ? "Yes" : "No") . "\n";

// 获取时间信息
echo "Last accessed: " . date("Y-m-d H:i:s", fileatime($filename)) . "\n";
echo "Last modified: " . date("Y-m-d H:i:s", filemtime($filename)) . "\n";
echo "File creation: " . date("Y-m-d H:i:s", filectime($filename)) . "\n";

// 获取文件大小
echo "File size: " . filesize($filename) . " bytes\n";

// 获取文件类型
echo "File type: " . filetype($filename) . "\n";

// 获取文件权限
$permissions = fileperms($filename);
echo "File permissions: " . decoct($permissions & 0777) . "\n";
} else {
echo "File does not exist.\n";
}

// 创建文件信息工具
class FileInfo {
// 静态缓存
private static $cache = [];

// 静态方法
public static function getInfo($filename) {
// 检查缓存
if (isset(self::$cache[$filename])) {
return self::$cache[$filename];
}

if (!file_exists($filename)) {
return null;
}

$info = [
'name' => basename($filename),
'path' => realpath($filename),
'size' => filesize($filename),
'type' => filetype($filename),
'mime' => mime_content_type($filename),
'readable' => is_readable($filename),
'writable' => is_writable($filename),
'created' => date("Y-m-d H:i:s", filectime($filename)),
'modified' => date("Y-m-d H:i:s", filemtime($filename)),
'accessed' => date("Y-m-d H:i:s", fileatime($filename))
];

// 缓存结果
self::$cache[$filename] = $info;
return $info;
}

// 静态方法
public static function formatSize($bytes) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$i = 0;
while ($bytes >= 1024 && $i < count($units) - 1) {
$bytes /= 1024;
$i++;
}
return round($bytes, 2) . ' ' . $units[$i];
}
}

// 使用静态方法
$info = FileInfo::getInfo("example.txt");
if ($info) {
echo "File: " . $info['name'] . "\n";
echo "Size: " . FileInfo::formatSize($info['size']) . "\n";
echo "Type: " . $info['type'] . "\n";
echo "MIME: " . $info['mime'] . "\n";
echo "Last modified: " . $info['modified'] . "\n";

// 从缓存获取
$cachedInfo = FileInfo::getInfo("example.txt");
echo "Retrieved from cache: " . ($info === $cachedInfo ? "Yes" : "No") . "\n";
}

14. PHP目录操作

详细解释

PHP提供了一套完整的目录操作函数,用于创建、读取和删除目录。

主要目录操作函数:

  • opendir():打开目录句柄
  • readdir():从目录句柄中读取条目
  • closedir():关闭目录句柄
  • scandir():列出目录中的所有文件和目录
  • mkdir():创建目录
  • rmdir():删除目录
  • chdir():改变当前目录
  • getcwd():获取当前工作目录

示例

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
<?php
// 创建目录
$dir = "example_dir";
if (!file_exists($dir)) {
mkdir($dir, 0777, true);
echo "Directory '$dir' created.\n";
}

// 列出目录内容
$files = scandir($dir);
echo "Directory contents of '$dir':\n";
foreach ($files as $file) {
if ($file != "." && $file != "..") {
echo "- $file\n";
}
}

// 递归读取目录
function recursiveScan($dir) {
$result = [];
$cdir = scandir($dir);
foreach ($cdir as $key => $value) {
if (!in_array($value, [".", ".."])) {
if (is_dir($dir . DIRECTORY_SEPARATOR . $value)) {
$result[$value] = recursiveScan($dir . DIRECTORY_SEPARATOR . $value);
} else {
$result[] = $value;
}
}
}
return $result;
}

$dirStructure = recursiveScan(".");
echo "Directory structure:\n";
print_r($dirStructure);

// 删除目录
function deleteDir($dir) {
$files = array_diff(scandir($dir), ['.', '..']);
foreach ($files as $file) {
$path = $dir . '/' . $file;
is_dir($path) ? deleteDir($path) : unlink($path);
}
return rmdir($dir);
}

// 创建测试目录结构
$testDir = "test_dir";
mkdir($testDir);
file_put_contents("$testDir/file1.txt", "Content 1");
mkdir("$testDir/subdir");
file_put_contents("$testDir/subdir/file2.txt", "Content 2");

// 删除测试目录
if (file_exists($testDir)) {
deleteDir($testDir);
echo "Test directory deleted.\n";
}

// 目录操作工具类
class DirectoryManager {
// 静态缓存
private static $cache = [];

// 单例实例
private static $instance = null;

private function __construct() {}

public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}

// 静态方法
public static function listFiles($dir, $recursive = false) {
// 检查缓存
$cacheKey = $dir . ($recursive ? '_recursive' : '');
if (isset(self::$cache[$cacheKey])) {
return self::$cache[$cacheKey];
}

if (!is_dir($dir)) {
return [];
}

$files = [];
$iterator = $recursive ? new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)) : new DirectoryIterator($dir);

foreach ($iterator as $file) {
if ($file->isFile()) {
$files[] = $file->getPathname();
}
}

// 缓存结果
self::$cache[$cacheKey] = $files;
return $files;
}

// 静态方法
public static function createDirectory($dir, $recursive = true) {
if (!file_exists($dir)) {
return mkdir($dir, 0777, $recursive);
}
return true;
}

// 静态方法
public static function deleteDirectory($dir) {
if (!is_dir($dir)) {
return false;
}

$files = array_diff(scandir($dir), ['.', '..']);
foreach ($files as $file) {
$path = $dir . '/' . $file;
if (is_dir($path)) {
self::deleteDirectory($path);
} else {
unlink($path);
}
}

return rmdir($dir);
}

private function __clone() {}
}

// 使用静态方法
$dir = "temp_dir";
if (DirectoryManager::createDirectory($dir)) {
echo "Directory created successfully\n";

// 创建一些文件
file_put_contents("$dir/file1.txt", "Content 1");
file_put_contents("$dir/file2.txt", "Content 2");

// 列出文件
$files = DirectoryManager::listFiles($dir);
echo "Files in directory:\n";
foreach ($files as $file) {
echo "- " . basename($file) . "\n";
}

// 递归列出(即使只有一个层级)
$allFiles = DirectoryManager::listFiles($dir, true);
echo "All files (recursive):\n";
foreach ($allFiles as $file) {
echo "- " . basename($file) . "\n";
}

// 从缓存获取
$cachedFiles = DirectoryManager::listFiles($dir);
echo "Retrieved from cache: " . ($files === $cachedFiles ? "Yes" : "No") . "\n";

// 删除目录
DirectoryManager::deleteDirectory($dir);
echo "Directory deleted\n";
}

15. 命名空间

详细解释

命名空间是PHP 5.3+引入的特性,用于解决命名冲突问题。

命名空间特点:

  • 避免类、函数和常量名称冲突
  • 可以嵌套(子命名空间)
  • 使用namespace关键字定义
  • 使用use关键字引入命名空间

命名空间访问:

  • 完全限定名称\Namespace\Class
  • 相对名称Class(在当前命名空间内)
  • 限定名称SubNamespace\Class

静态方法在命名空间中的使用:

  • 可以在命名空间中定义静态类
  • 静态方法可以通过完全限定名称调用
  • 在不同命名空间中可以有同名的静态类和方法

示例

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<?php
// 定义命名空间
namespace MyProject\Utils;

// 类定义
class StringHelper {
// 静态成员变量
private static $instanceCount = 0;

// 构造函数
public function __construct() {
self::$instanceCount++;
}

// 静态方法
public static function reverse($string) {
self::$instanceCount++;
return strrev($string);
}

// 静态方法
public static function getInstanceCount() {
return self::$instanceCount;
}
}

// 函数定义
function formatTime($timestamp) {
return date("Y-m-d H:i:s", $timestamp);
}

// 常量定义
const MAX_LENGTH = 100;

// 静态工具类
class MathHelper {
// 静态常量
const PI = 3.14159;

// 静态方法
public static function add($a, $b) {
return $a + $b;
}

public static function multiply($a, $b) {
return $a * $b;
}

// 静态方法使用静态常量
public static function circleArea($radius) {
return self::PI * $radius * $radius;
}
}

// 子命名空间
namespace MyProject\Utils\Math;

// 静态工具类
class Calculator {
// 静态成员变量
private static $operationCount = 0;

// 静态方法
public static function add($a, $b) {
self::$operationCount++;
return $a + $b;
}

public static function subtract($a, $b) {
self::$operationCount++;
return $a - $b;
}

// 静态方法
public static function getOperationCount() {
return self::$operationCount;
}
}

// 使用命名空间
namespace Main;

// 导入命名空间
use MyProject\Utils\StringHelper;
use MyProject\Utils\MathHelper;
use MyProject\Utils\Math\Calculator as MathCalc;

// 使用导入的类
echo StringHelper::reverse("Hello") . "\n"; // olleH
echo "StringHelper instances: " . StringHelper::getInstanceCount() . "\n"; // 1

// 创建实例会增加计数
new StringHelper();
echo "StringHelper instances: " . StringHelper::getInstanceCount() . "\n"; // 2

// 使用静态方法
echo "5 + 3 = " . MathHelper::add(5, 3) . "\n"; // 8
echo "Circle area (radius=5): " . MathHelper::circleArea(5) . "\n";

// 使用别名
echo "10 - 3 = " . MathCalc::subtract(10, 3) . "\n"; // 7
echo "Operation count: " . MathCalc::getOperationCount() . "\n"; // 1

// 完全限定名称
echo \MyProject\Utils\formatTime(time()) . "\n";

// 使用use导入多个元素
use MyProject\Utils\{
StringHelper as Str,
formatTime,
MAX_LENGTH
};

echo Str::reverse("World") . "\n"; // dlroW
echo formatTime(time()) . "\n";
echo "Max length: " . MAX_LENGTH . "\n";

// 另一个命名空间中的同名类
namespace AnotherProject;

class StringHelper {
// 静态方法
public static function reverse($string) {
return strtoupper(strrev($string));
}
}

// 在Main命名空间中使用
namespace Main;

// 完全限定名称调用
echo \AnotherProject\StringHelper::reverse("Hello") . "\n"; // OLLEH

16. 正则表达式

详细解释

正则表达式是一种强大的文本处理工具,用于模式匹配、搜索和替换。

PHP正则表达式函数:

  • preg_match():执行正则表达式匹配
  • preg_match_all():执行全局正则表达式匹配
  • preg_replace():执行正则表达式搜索和替换
  • preg_split():通过正则表达式分割字符串
  • preg_quote():转义正则表达式字符

正则表达式元字符:

  • ^:匹配字符串开始
  • $:匹配字符串结束
  • .:匹配任意字符(除换行符外)
  • *:匹配前一个元素0次或多次
  • +:匹配前一个元素1次或多次
  • ?:匹配前一个元素0次或1次
  • {n,m}:匹配前一个元素n到m次
  • []:字符类,匹配其中任一字符
  • |:选择,匹配左边或右边的表达式
  • ():分组,将多个元素视为一个整体

16.1 基本正则表达式

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<?php
// ====================== 元字符详解与验证 ======================
echo "【元字符详解与验证】\n";

// 1. ^: 匹配字符串开始
$pattern_start = '/^Hello/';
echo preg_match($pattern_start, "Hello World") ? "[✓] ^匹配开头成功\n" : "[✗] ^匹配开头失败\n";
echo preg_match($pattern_start, "Say Hello") ? "[✗] ^匹配开头错误\n" : "[✓] ^匹配开头正确拒绝\n";

// 2. $: 匹配字符串结束
$pattern_end = '/World$/';
echo preg_match($pattern_end, "Hello World") ? "[✓] $匹配结尾成功\n" : "[✗] $匹配结尾失败\n";
echo preg_match($pattern_end, "World Tour") ? "[✗] $匹配结尾错误\n" : "[✓] $匹配结尾正确拒绝\n";

// 3. .: 匹配任意字符(除换行符)
$pattern_dot = '/a.b/';
echo preg_match($pattern_dot, "acb") ? "[✓] .匹配任意字符成功\n" : "[✗] .匹配失败\n";
echo preg_match($pattern_dot, "a\nb") ? "[✗] .匹配换行符错误\n" : "[✓] .正确跳过换行符\n"; // 默认不匹配换行符

// 4. *: 匹配前元素0次或多次
$pattern_star = '/ab*c/';
echo preg_match($pattern_star, "ac") ? "[✓] *匹配0次成功 (ac)\n" : "[✗] *匹配0次失败\n";
echo preg_match($pattern_star, "abbbc") ? "[✓] *匹配多次成功 (abbbc)\n" : "[✗] *匹配多次失败\n";
echo preg_match($pattern_star, "adc") ? "[✗] *错误匹配非b字符\n" : "[✓] *正确拒绝 (adc)\n";

// 5. +: 匹配前元素1次或多次
$pattern_plus = '/ab+c/';
echo preg_match($pattern_plus, "abc") ? "[✓] +匹配1次成功 (abc)\n" : "[✗] +匹配1次失败\n";
echo preg_match($pattern_plus, "ac") ? "[✗] +错误匹配0次 (ac)\n" : "[✓] +正确拒绝0次\n";

// 6. ?: 匹配前元素0次或1次
$pattern_question = '/colou?r/';
echo preg_match($pattern_question, "color") ? "[✓] ?匹配0次成功 (color)\n" : "[✗] ?匹配0次失败\n";
echo preg_match($pattern_question, "colour") ? "[✓] ?匹配1次成功 (colour)\n" : "[✗] ?匹配1次失败\n";
echo preg_match($pattern_question, "colouur") ? "[✗] ?错误匹配2次 (colouur)\n" : "[✓] ?正确拒绝2次\n";

// 7. {n,m}: 匹配前元素n到m次
$pattern_range = '/\d{3,5}/';
echo preg_match($pattern_range, "123") ? "[✓] {3,5}匹配3位成功 (123)\n" : "[✗] {3,5}匹配3位失败\n";
echo preg_match($pattern_range, "12345") ? "[✓] {3,5}匹配5位成功 (12345)\n" : "[✗] {3,5}匹配5位失败\n";
echo preg_match($pattern_range, "12") ? "[✗] {3,5}错误匹配2位 (12)\n" : "[✓] {3,5}正确拒绝2位\n";
echo preg_match($pattern_range, "123456") ? "[✗] {3,5}错误匹配6位 (123456)\n" : "[✓] {3,5}正确拒绝6位\n";

// 8. []: 字符类
$pattern_class = '/[aeiou]/';
echo preg_match($pattern_class, "apple") ? "[✓] []匹配元音成功 (apple)\n" : "[✗] []匹配失败\n";
echo preg_match($pattern_class, "why") ? "[✗] []错误匹配无元音 (why)\n" : "[✓] []正确拒绝\n";

// 9. |: 选择
$pattern_or = '/cat|dog/';
echo preg_match($pattern_or, "I have a cat") ? "[✓] |匹配cat成功\n" : "[✗] |匹配失败\n";
echo preg_match($pattern_or, "My dog is cute") ? "[✓] |匹配dog成功\n" : "[✗] |匹配失败\n";
echo preg_match($pattern_or, "I love birds") ? "[✗] |错误匹配无cat/dog\n" : "[✓] |正确拒绝\n";

// 10. (): 分组
$pattern_group = '/(abc){2}/';
echo preg_match($pattern_group, "abcabc") ? "[✓] ()分组重复成功\n" : "[✗] ()分组匹配失败\n";
echo preg_match($pattern_group, "abc") ? "[✗] ()错误匹配单次\n" : "[✓] ()正确拒绝单次\n";

// ====================== 核心函数实战 ======================
echo "\n【核心函数实战】\n";

// preg_match() - 基础验证
$valid_email = "user+name@sub.domain.co.uk";
$invalid_email = "user@.com";
$email_pattern = '/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/i';

$result_valid = preg_match($email_pattern, $valid_email);
$result_invalid = preg_match($email_pattern, $invalid_email);
echo "[邮箱验证] 正例: " . ($result_valid ? "有效 ✓" : "无效 ✗") . "\n";
echo "[邮箱验证] 反例: " . ($result_invalid ? "有效 ✗" : "无效 ✓") . "\n";

// preg_match_all() - 数据提取
$html = '<a href="https://example.com">首页</a> | <a href="/contact">联系</a>';
$link_pattern = '/<a\s+href="([^"]+)">([^<]+)<\/a>/i';

preg_match_all($link_pattern, $html, $matches);
echo "\n[链接提取] 正例:\n";
print_r($matches[0]); // 完整匹配
echo "URLs: " . implode(', ', $matches[1]) . "\n";
echo "文本: " . implode(', ', $matches[2]) . "\n";

$no_links = "纯文本无链接";
$no_match = preg_match_all($link_pattern, $no_links, $empty);
echo "[链接提取] 反例: " . ($no_match === 0 ? "✓ 无匹配" : "✗ 错误匹配") . "\n";

// preg_replace() - 内容转换
$text = "价格: $19.99 | 优惠价: $9.50";
$currency_pattern = '/\$([\d.]+)/';

$formatted = preg_replace($currency_pattern, '¥\1元', $text);
echo "\n[货币转换] 正例:\n原始: $text\n转换: $formatted\n";

$no_currency = "免费内容";
$unchanged = preg_replace($currency_pattern, '¥\1元', $no_currency);
echo "[货币转换] 反例: " . ($unchanged === $no_currency ? "✓ 未修改" : "✗ 错误修改") . "\n";

// preg_split() - 高级分割
$csv = "苹果; 香蕉, 橙子 | 葡萄";
$split_pattern = '/[;,|]\s*/';

$fruits = preg_split($split_pattern, $csv, -1, PREG_SPLIT_NO_EMPTY);
echo "\n[智能分割] 正例:\n";
print_r($fruits); // Array ( [0] => 苹果 [1] => 香蕉 [2] => 橙子 [3] => 葡萄 )

$bad_pattern = '/[\d]/'; // 错误使用数字分割
$bad_result = preg_split($bad_pattern, $csv);
echo "[智能分割] 反例: 分割结果数量=" . count($bad_result) . " (错误模式)\n";

// preg_quote() - 安全转义
$user_input = "100$?+.*";
$unsafe_regex = "/$user_input/"; // 会导致正则错误
$safe_regex = "/" . preg_quote($user_input, '/') . "/";

$test_str = "产品价格100$?+.*特惠";
echo "\n[安全转义]\n";
echo "原始模式: " . @preg_match($unsafe_regex, $test_str) . " (会产生警告)\n";
echo "安全模式: " . preg_match($safe_regex, $test_str) . " ✓ 正确匹配\n";

// ====================== 综合应用案例 ======================
echo "\n【综合案例:日志分析与转换】\n";
$log_data = <<<LOG
192.168.1.105 - [09/Dec/2025:14:30:01 +0000] "GET /index.php?user=admin HTTP/1.1" 200 1234
10.0.0.5 - [09/Dec/2025:14:35:22 +0000] "POST /login.php HTTP/1.1" 401 567
172.16.0.22 - [09/Dec/2025:14:40:15 +0000] "GET /image.png HTTP/1.1" 404 321
LOG;

// 1. 使用preg_match_all提取日志数据
$log_pattern = '/^([\d.]+) - \[(.*?)\] "(GET|POST) ([^"]+)" (\d+) (\d+)$/m';
preg_match_all($log_pattern, $log_data, $log_matches, PREG_SET_ORDER);

// 2. 分析结果
echo "检测到 " . count($log_matches) . " 条有效日志\n";
foreach ($log_matches as $match) {
[$full, $ip, $time, $method, $path, $status, $size] = $match;

// 3. 使用preg_replace转换路径格式
$clean_path = preg_replace('/\?.*$/', '', $path); // 移除查询参数

// 4. 使用元字符验证状态码
$status_desc = preg_match('/^2\d{2}$/', $status) ? "成功" :
(preg_match('/^4\d{2}$/', $status) ? "客户端错误" : "其他");

echo sprintf("[%-15s] %s %s → %s (%s | %s字节)\n",
$ip, $method, $clean_path, $status_desc, $status, $size);
}

// 5. 使用preg_split按状态码分组
$grouped = preg_split('/^(.*?)$/m', $log_data, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
echo "\n[状态码分组] 4xx错误日志:\n";
foreach ($grouped as $line) {
if (preg_match('/" (4\d{2}) /', $line)) {
echo "⚠️ " . trim($line) . "\n";
}
}

// 6. 安全处理用户输入的搜索关键词
$search_term = "admin?404";
$safe_term = preg_quote($search_term, '/');
$matched_logs = preg_grep("/$safe_term/", explode("\n", $log_data));
echo "\n[安全搜索] 包含 '{$search_term}' 的日志:\n";
if (!empty($matched_logs)) {
foreach ($matched_logs as $log) echo "🔍 $log\n";
} else {
echo "✓ 未找到匹配日志\n";
}

16.2 高级正则表达式

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
<?php
/**
* 高级正则表达式详解
* 本示例覆盖PHP正则表达式的高级特性,包括:
* - 零宽断言(前瞻/后顾)
* - 命名捕获组
* - 模式修饰符详解
* - Unicode支持
* - 回溯控制
* - 正则表达式性能优化
* - 完整的错误处理
*/

// 1. 零宽断言(前瞻/后顾) - 验证密码强度
echo "【1. 零宽断言(前瞻/后顾)】\n";

/**
* 密码规则:
* - 至少8个字符
* - 必须包含至少一个大写字母(前瞻)
* - 必须包含至少一个小写字母(前瞻)
* - 必须包含至少一个数字(前瞻)
* - 不能以数字开头(后顾)
*/
$password_pattern = '/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?<!^\d).{8,}$/';

$passwords = [
"ValidPass123", // 有效: 满足所有条件
"invalidpass123", // 无效: 缺少大写字母
"VALIDPASS123", // 无效: 缺少小写字母
"ValidPassword", // 无效: 缺少数字
"1InvalidPass", // 无效: 以数字开头
"Sh0rt", // 无效: 长度不足
"Valid1Pass" // 有效: 满足所有条件
];

foreach ($passwords as $pwd) {
$result = preg_match($password_pattern, $pwd);
echo sprintf("[%-12s] %s\n",
$pwd,
$result ? "✓ 强密码" : "✗ 弱密码 - 不符合复杂度要求"
);
}

// 2. 命名捕获组 - 解析日期
echo "\n【2. 命名捕获组】\n";

/**
* 日期格式: YYYY-MM-DD 或 DD/MM/YYYY
* 使用命名捕获组提取年、月、日
*/
$date_pattern = '/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})|(?P<day2>\d{2})\/(?P<month2>\d{2})\/(?P<year2>\d{4})/';

$dates = [
"2023-12-25",
"31/12/2023",
"12-25-2023" // 无效格式
];

foreach ($dates as $date) {
if (preg_match($date_pattern, $date, $matches)) {
// 处理不同格式的日期
if (!empty($matches['year'])) {
$year = $matches['year'];
$month = $matches['month'];
$day = $matches['day'];
} else {
$year = $matches['year2'];
$month = $matches['month2'];
$day = $matches['day2'];
}
echo "[$date] ✓ 有效日期: {$year}{$month}{$day}日\n";
} else {
echo "[$date] ✗ 无效日期格式\n";
}
}

// 3. 模式修饰符详解
echo "\n【3. 模式修饰符详解】\n";

/**
* 常用修饰符:
* i - 不区分大小写
* m - 多行模式(^和$匹配每行开头结尾)
* s - 使.匹配包括换行符在内的所有字符
* u - UTF-8模式(支持Unicode)
* x - 扩展模式(忽略空格和注释)
*/

// 示例1: 多行模式(m)和Unicode(u)结合
$text_multiline = "苹果\nBanana\n樱桃\nDate";
$pattern_multiline = '/^[\p{L}]{3,}$/mu'; // 匹配每行中至少3个字母的单词(包含Unicode字符)

echo "多行文本:\n$text_multiline\n";
preg_match_all($pattern_multiline, $text_multiline, $matches_multiline);
echo "匹配结果(多行+Unicode): " . implode(", ", $matches_multiline[0]) . "\n";

// 示例2: 扩展模式(x) - 提高可读性
$pattern_verbose = '
/ # 分隔符
\b # 单词边界
(?<word> # 命名捕获组
\w+ # 一个或多个单词字符
)
\s+ # 一个或多个空白字符
\k<word> # 重复前面捕获的相同单词
\b # 单词边界
/x # 扩展模式
';

$text_repeat = "the the quick brown fox fox jumps over the lazy dog dog";
if (preg_match_all($pattern_verbose, $text_repeat, $matches_repeat)) {
echo "重复单词检测: " . implode(", ", $matches_repeat[0]) . "\n";
}

// 4. Unicode属性支持
echo "\n【4. Unicode属性支持】\n";

$international_text = "Hello 你好 123 こんにちは 456";
$pattern_unicode = '/[\p{L}\p{N}]+/u'; // 匹配所有字母和数字(包括非ASCII字符)

preg_match_all($pattern_unicode, $international_text, $matches_unicode);
echo "原始文本: $international_text\n";
echo "Unicode匹配结果: " . implode(", ", $matches_unicode[0]) . "\n";

// 5. 回溯控制 - 防止正则表达式灾难性回溯
echo "\n【5. 回溯控制】\n";

/**
* 问题: 当遇到恶意构造的输入时, 正则表达式可能会陷入灾难性回溯
* 解决方案: 使用原子组(?>...)或占有优先量词*+、++、?+、{n,m}+限制回溯
*/

// 危险模式示例(可能导致回溯爆炸)
$dangerous_pattern = '/^(a+)+$/';
$safe_pattern = '/^(?>a+)+$/'; // 使用原子组防止回溯

$test_string = str_repeat('a', 25) . 'b'; // 长字符串+不匹配字符

$start = microtime(true);
$result_dangerous = @preg_match($dangerous_pattern, $test_string, $matches, 0, 1000000); // 1秒超时
$time_dangerous = microtime(true) - $start;

$start = microtime(true);
$result_safe = preg_match($safe_pattern, $test_string);
$time_safe = microtime(true) - $start;

echo "回溯控制测试:\n";
echo "危险模式执行时间: " . sprintf('%.6f', $time_dangerous) . "s, 结果: " . ($result_dangerous === false ? "超时/错误" : $result_dangerous) . "\n";
echo "安全模式执行时间: " . sprintf('%.6f', $time_safe) . "s, 结果: $result_safe\n";

// 6. 高级URL解析
echo "\n【6. 高级URL解析】\n";

$url_parser = '/
^ # 字符串开始
(?:
(?<scheme>[a-z]+) # 协议(命名捕获)
:\/\/ # ://
)? # 协议部分是可选的
(?:
(?<auth>[^@]+)@ # 认证信息 username:password@
)? # 认证信息是可选的
(?<host> # 主机名(命名捕获)
(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+ # 子域名
[a-z]{2,63} # 顶级域名
| # 或者
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} # IPv4地址
)
(?::(?<port>\d+))? # 端口(命名捕获,可选)
(?<path>\/[^\?]*)? # 路径(命名捕获,可选)
(?:\?(?<query>[^#]*))? # 查询参数(命名捕获,可选)
(?:#(?<fragment>.*))? # 片段(命名捕获,可选)
$ # 字符串结束
/ix'; // 不区分大小写+扩展模式

$urls = [
"https://user:pass@example.com:8080/path/to/file?query=1#fragment",
"http://sub.domain.co.uk",
"ftp://192.168.1.1/file.txt",
"example.com/path",
"invalid_url"
];

foreach ($urls as $url) {
echo "\n分析URL: $url\n";
if (preg_match($url_parser, $url, $matches)) {
// 清理匹配结果,只保留命名捕获
$result = [];
foreach ($matches as $key => $value) {
if (!is_int($key) && $value !== '') {
$result[$key] = $value;
}
}
echo "✓ 有效URL\n";
foreach ($result as $name => $value) {
echo " $name: $value\n";
}
} else {
echo "✗ 无效URL格式\n";
}
}

// 7. 正则表达式工具类(增强版)
echo "\n【7. 增强版正则表达式工具类】\n";

class AdvancedRegexHelper {
// 静态常量 - 优化的正则表达式
const EMAIL_PATTERN = '/^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i';
const URL_PATTERN = '/^(?:https?:\/\/)?(?:[a-z0-9-]+\.)+[a-z]{2,6}(?:\/[\w\-\.?%&=]*)?$/i';
const PHONE_PATTERN = '/^\+?1?[-. (]*(\d{3})[-. )]*(\d{3})[-. ]*(\d{4})$/';
const CREDIT_CARD_PATTERN = '/^(?<visa>4\d{12}(?:\d{3})?)|(?<mastercard>5[1-5]\d{14})|(?<amex>3[47]\d{13})$/';
const HTML_TAG_PATTERN = '/<([a-z]+)([^<]*)>(.*?)<\/\1>/is';

// 验证方法
public static function validateEmail($email) {
return self::safeRegexMatch(self::EMAIL_PATTERN, $email);
}

public static function validateUrl($url) {
return self::safeRegexMatch(self::URL_PATTERN, $url);
}

public static function validatePhone($phone) {
return self::safeRegexMatch(self::PHONE_PATTERN, $phone);
}

public static function validateCreditCard($cardNumber) {
$cleanCard = preg_replace('/\s+/', '', $cardNumber);
return self::safeRegexMatch(self::CREDIT_CARD_PATTERN, $cleanCard);
}

// 提取方法
public static function extractEmails($text) {
return self::safeRegexMatchAll(self::EMAIL_PATTERN, $text);
}

public static function extractUrls($text) {
return self::safeRegexMatchAll(self::URL_PATTERN, $text);
}

public static function extractPhoneNumbers($text) {
return self::safeRegexMatchAll(self::PHONE_PATTERN, $text);
}

// 转换方法
public static function maskCreditCard($cardNumber) {
$cleanCard = preg_replace('/\D/', '', $cardNumber);
if (!self::validateCreditCard($cleanCard)) {
return "无效的信用卡号";
}

$last4 = substr($cleanCard, -4);
$masked = str_repeat('*', strlen($cleanCard) - 4) . $last4;
return preg_replace('/(\*{4})(?=\*{4})/', '$1 ', $masked);
}

public static function sanitizeHtml($html) {
// 仅保留安全的HTML标签
$allowedTags = ['b', 'i', 'u', 'em', 'strong', 'p', 'br', 'a'];
return preg_replace_callback(
self::HTML_TAG_PATTERN,
function($matches) use ($allowedTags) {
$tag = strtolower($matches[1]);
if (in_array($tag, $allowedTags)) {
// 仅对a标签特殊处理,清理href属性
if ($tag === 'a') {
$href = preg_match('/href\s*=\s*"([^"]*)"/i', $matches[2], $hrefMatches)
? $hrefMatches[1] : '';
if (preg_match('/^(https?:\/\/|mailto:)/i', $href)) {
return "<a href=\"$href\">" . self::sanitizeHtml($matches[3]) . "</a>";
}
}
return "<$tag>" . self::sanitizeHtml($matches[3]) . "</$tag>";
}
return self::sanitizeHtml($matches[3]); // 移除不允许的标签,但保留内容
},
$html
);
}

// 替换方法
public static function makeClickableLinks($text) {
$pattern = '/(?<![\w\/])(https?:\/\/|www\.)([\w\-\.]+\.[a-zA-Z]{2,}(?:\/[\w\.\/\?\&\=\-]*)?)/i';
return preg_replace_callback($pattern, function($matches) {
$url = $matches[0];
$display = (strlen($url) > 30) ? substr($url, 0, 27) . '...' : $url;
if (strpos($url, 'www.') === 0) {
$url = 'http://' . $url;
}
return "<a href=\"$url\" target=\"_blank\">$display</a>";
}, $text);
}

// 工具方法
private static function safeRegexMatch($pattern, $subject, $flags = 0) {
set_error_handler(function() {}); // 临时忽略错误
$result = preg_match($pattern, $subject, $matches, $flags);
restore_error_handler();

if ($result === false) {
$error = preg_last_error();
$errorMsg = self::getPregError($error);
trigger_error("正则表达式错误: $errorMsg", E_USER_WARNING);
return false;
}

return $result === 1;
}

private static function safeRegexMatchAll($pattern, $subject, $flags = PREG_PATTERN_ORDER) {
set_error_handler(function() {});
$result = preg_match_all($pattern, $subject, $matches, $flags);
restore_error_handler();

if ($result === false) {
$error = preg_last_error();
$errorMsg = self::getPregError($error);
trigger_error("正则表达式错误: $errorMsg", E_USER_WARNING);
return [];
}

return $matches[0] ?? [];
}

private static function getPregError($code) {
switch ($code) {
case PREG_NO_ERROR: return "无错误";
case PREG_INTERNAL_ERROR: return "内部错误";
case PREG_BACKTRACK_LIMIT_ERROR: return "回溯限制超出";
case PREG_RECURSION_LIMIT_ERROR: return "递归限制超出";
case PREG_BAD_UTF8_ERROR: return "无效的UTF-8数据";
case PREG_BAD_UTF8_OFFSET_ERROR: return "无效的UTF-8偏移量";
default: return "未知错误 ($code)";
}
}
}

// 8. 综合应用案例:文本内容分析器
echo "\n【8. 综合应用:智能文本内容分析器】\n";

class ContentAnalyzer {
private $text;
private $analysis;

public function __construct($text) {
$this->text = $text;
$this->analysis = [];
}

public function analyze() {
$this->analyzeSentences();
$this->analyzeKeywords();
$this->detectEntities();
$this->identifySensitiveContent();
return $this->analysis;
}

private function analyzeSentences() {
// 智能分割句子(处理缩写、引号等情况)
$sentencePattern = '/
(?<= # 后顾断言
[.!?] # 句号、问号、感叹号
[\]\])\'"]* # 可能跟随引号或括号
\s+ # 后跟空白
)
(?=[A-Z]) # 前瞻断言: 下一个字符是大写字母
| # 或者
(?<= # 处理缩写
\b(?:Mr|Mrs|Dr|Prof|Inc|Ltd|Jr|Sr|vs)\.
\s+
)
(?=[A-Z])/x';

$sentences = preg_split($sentencePattern, $this->text, -1, PREG_SPLIT_NO_EMPTY);
$this->analysis['sentences'] = $sentences;
$this->analysis['sentence_count'] = count($sentences);
}

private function analyzeKeywords() {
// 提取关键词(排除停用词)
$wordPattern = '/\b(?!(?:the|and|or|in|on|at|to|for|with|a|an|of|is|are|was|were|be|been|being)\b)[a-zA-Z]{3,}\b/';
preg_match_all($wordPattern, strtolower($this->text), $matches);

$words = array_count_values($matches[0]);
arsort($words);
$this->analysis['top_keywords'] = array_slice($words, 0, 5, true);
}

private function detectEntities() {
// 检测URL、邮箱、电话
$this->analysis['urls'] = AdvancedRegexHelper::extractUrls($this->text);
$this->analysis['emails'] = AdvancedRegexHelper::extractEmails($this->text);
$this->analysis['phones'] = AdvancedRegexHelper::extractPhoneNumbers($this->text);
}

private function identifySensitiveContent() {
// 识别潜在敏感内容
$patterns = [
'credit_cards' => '/\b(?:\d[ -]*?){13,16}\b/',
'ssn' => '/\b\d{3}[- ]?\d{2}[- ]?\d{4}\b/',
'password_like' => '/\b(password|pass|pwd)\s*[:=]\s*[\'"]?[\w@#$%^&*!]{5,}[\'"]?\b/i'
];

foreach ($patterns as $type => $pattern) {
preg_match_all($pattern, $this->text, $matches);
if (!empty($matches[0])) {
$this->analysis['sensitive'][$type] = count($matches[0]);
}
}
}

public function getReport() {
$analysis = $this->analyze();
$report = "===== 内容分析报告 =====\n";
$report .= "句子数量: {$analysis['sentence_count']}\n\n";

$report .= "【关键词频率】\n";
foreach ($analysis['top_keywords'] as $word => $count) {
$report .= "- $word: $count 次\n";
}

$report .= "\n【检测到的实体】\n";
$report .= "- 链接: " . (empty($analysis['urls']) ? "无" : implode(", ", $analysis['urls'])) . "\n";
$report .= "- 邮箱: " . (empty($analysis['emails']) ? "无" : implode(", ", $analysis['emails'])) . "\n";
$report .= "- 电话: " . (empty($analysis['phones']) ? "无" : implode(", ", $analysis['phones'])) . "\n";

if (!empty($analysis['sensitive'])) {
$report .= "\n【警告: 检测到敏感内容】\n";
foreach ($analysis['sensitive'] as $type => $count) {
$report .= "- $type: $count 处\n";
}
$report .= "请检查内容是否包含不应公开的个人信息!\n";
}

return $report;
}
}

// 9. 演示工具类用法
echo "\n【9. 高级工具类应用演示】\n";

// 验证示例
$emails = ["user@example.com", "invalid-email@", "name+tag@sub.domain.co.uk"];
foreach ($emails as $email) {
echo sprintf("邮箱 '%s': %s\n",
$email,
AdvancedRegexHelper::validateEmail($email) ? "✓ 有效" : "✗ 无效"
);
}

// 信用卡掩码
$cards = [
"4111 1111 1111 1111", // Visa
"5500 0000 0000 0004", // Mastercard
"3400 0000 0000 009" // Amex
];
foreach ($cards as $card) {
echo "信用卡: $card → " . AdvancedRegexHelper::maskCreditCard($card) . "\n";
}

// HTML清理
$html_content = '<p>安全内容 <b>加粗</b> 和 <a href="https://example.com" onclick="alert(1)">链接</a></p>
<script>alert("XSS攻击")</script>
合法<a href="http://example.com/path">内部链接</a>和<a href="javascript:alert(\'bad\')">危险链接</a>';

echo "\n原始HTML:\n$html_content\n";
echo "\n清理后的HTML:\n" . AdvancedRegexHelper::sanitizeHtml($html_content) . "\n";

// 10. 综合案例演示
echo "\n【10. 综合案例:内容安全分析】\n";

$sample_text = <<<TEXT
这是一份测试文档。其中包含一个有效的URL: https://www.example.com/path?query=1#section1
同时还有测试邮箱: contact@example.com 和 support.team@example.co.uk

请注意,我的信用卡号是 4111 1111 1111 1111,社会保险号 123-45-6789。
密码设置为: password=SecurePass123

联系我: (123) 456-7890 或 987-654-3210
更多信息请访问 www.our-company.com 或联系 admin@company.com
TEXT;

$analyzer = new ContentAnalyzer($sample_text);
echo $analyzer->getReport();

// 11. 正则表达式性能优化技巧
echo "\n【11. 正则表达式性能优化技巧】\n";

$large_text = str_repeat("Lorem ipsum dolor sit amet, consectetur adipiscing elit. ", 1000);
$search_word = "dolor";

// 非优化版本
$pattern_unoptimized = '/\b' . preg_quote($search_word, '/') . '\b/';

// 优化版本
$pattern_optimized = '/\b' . preg_quote($search_word, '/') . '\b/S'; // S修饰符表示研究正则表达式并优化

$iterations = 10;
$time_unoptimized = 0;
$time_optimized = 0;

for ($i = 0; $i < $iterations; $i++) {
$start = microtime(true);
preg_match_all($pattern_unoptimized, $large_text, $matches);
$time_unoptimized += microtime(true) - $start;

$start = microtime(true);
preg_match_all($pattern_optimized, $large_text, $matches);
$time_optimized += microtime(true) - $start;
}

echo "性能测试 (平均时间):\n";
echo "非优化模式: " . sprintf('%.6f', $time_unoptimized / $iterations) . " 秒\n";
echo "优化模式(S修饰符): " . sprintf('%.6f', $time_optimized / $iterations) . " 秒\n";
echo "性能提升: " . sprintf('%.1f', ($time_unoptimized / $time_optimized) * 100) . "%\n";

17. PHP与MySQL

详细解释

PHP提供了多种方式与MySQL数据库交互,主要包括:

  • MySQLi(MySQL Improved):面向对象和过程式接口
  • PDO(PHP Data Objects):数据访问抽象层,支持多种数据库

连接数据库步骤:

  1. 创建数据库连接
  2. 执行SQL查询
  3. 处理结果集
  4. 关闭连接

重要概念:

  • 预处理语句:防止SQL注入,提高性能
  • 事务:确保多个操作的原子性
  • 错误处理:捕获和处理数据库错误
  • 静态方法:用于创建单例模式或工具类

17.1 使用MySQLi(面向对象)

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
<?php
// 数据库连接参数
$host = "localhost";
$username = "root";
$password = "password";
$database = "test_db";

// 数据库工具类
class Database {
// 静态实例(单例模式)
private static $instance = null;
private $connection;

// 私有构造函数
private function __construct($host, $username, $password, $database) {
$this->connection = new mysqli($host, $username, $password, $database);
if ($this->connection->connect_error) {
die("Connection failed: " . $this->connection->connect_error);
}
}

// 获取单例实例
public static function getInstance($host = 'localhost', $username = 'root', $password = '', $database = 'test_db') {
if (self::$instance === null) {
self::$instance = new self($host, $username, $password, $database);
}
return self::$instance;
}

// 获取连接
public function getConnection() {
return $this->connection;
}

// 静态方法:执行查询
public static function query($sql, $params = []) {
$instance = self::getInstance();
$stmt = $instance->connection->prepare($sql);
if ($params) {
$types = str_repeat('s', count($params));
$stmt->bind_param($types, ...$params);
}
$stmt->execute();
return $stmt->get_result();
}

// 静态方法:插入数据
public static function insert($table, $data) {
$instance = self::getInstance();
$keys = array_keys($data);
$values = array_values($data);

$placeholders = implode(',', array_fill(0, count($keys), '?'));
$columns = implode(',', $keys);

$sql = "INSERT INTO $table ($columns) VALUES ($placeholders)";
$stmt = $instance->connection->prepare($sql);

$types = str_repeat('s', count($values));
$stmt->bind_param($types, ...$values);
$stmt->execute();

return $instance->connection->insert_id;
}

private function __clone() {}
}

// 创建连接
$conn = Database::getInstance($host, $username, $password, $database)->getConnection();
echo "Connected successfully\n";

// 创建表
$createTable = "CREATE TABLE IF NOT EXISTS users (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)";
if ($conn->query($createTable) === TRUE) {
echo "Table 'users' created successfully\n";
} else {
echo "Error creating table: " . $conn->error . "\n";
}

// 插入数据(普通查询)
$insert = "INSERT INTO users (name, email) VALUES ('John Doe', 'john@example.com')";
if ($conn->query($insert) === TRUE) {
echo "New record created successfully\n";
} else {
echo "Error: " . $insert . "\n" . $conn->error . "\n";
}

// 插入数据(预处理语句)
$name = "Jane Smith";
$email = "jane@example.com";
$stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email);
if ($stmt->execute()) {
echo "New record created using prepared statement\n";
} else {
echo "Error: " . $stmt->error . "\n";
}

// 使用静态方法插入数据
$userId = Database::insert('users', [
'name' => 'Static User',
'email' => 'static@example.com'
]);
echo "User created with ID: $userId\n";

// 查询数据
$result = $conn->query("SELECT id, name, email FROM users");
if ($result->num_rows > 0) {
echo "Users:\n";
while ($row = $result->fetch_assoc()) {
echo "ID: " . $row["id"] . " - Name: " . $row["name"] . " - Email: " . $row["email"] . "\n";
}
} else {
echo "No users found\n";
}

// 使用静态方法查询数据
$users = Database::query("SELECT id, name, email FROM users WHERE name = ?", ["John Doe"]);
if ($users->num_rows > 0) {
echo "Found users:\n";
while ($row = $users->fetch_assoc()) {
echo "ID: " . $row["id"] . " - Name: " . $row["name"] . " - Email: " . $row["email"] . "\n";
}
} else {
echo "No users found with that name\n";
}

// 更新数据
$update = "UPDATE users SET email='newemail@example.com' WHERE name='John Doe'";
if ($conn->query($update) === TRUE) {
echo "Record updated successfully\n";
} else {
echo "Error updating record: " . $conn->error . "\n";
}

// 删除数据
$delete = "DELETE FROM users WHERE name='Jane Smith'";
if ($conn->query($delete) === TRUE) {
echo "Record deleted successfully\n";
} else {
echo "Error deleting record: " . $conn->error . "\n";
}

// 事务示例
$conn->begin_transaction();
try {
$conn->query("INSERT INTO users (name, email) VALUES ('Transaction User', 'transaction@example.com')");
$conn->query("INSERT INTO users (name, email) VALUES ('Another User', 'another@example.com')");

// 模拟错误
// $conn->query("INVALID SQL");

$conn->commit();
echo "Transaction completed successfully\n";
} catch (Exception $e) {
$conn->rollback();
echo "Transaction failed: " . $e->getMessage() . "\n";
}

// 关闭连接
$conn->close();

17.2 使用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
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
<?php
// 数据库连接参数
$host = "localhost";
$username = "root";
$password = "password";
$database = "test_db";

// PDO数据库类
class PDODatabase {
// 静态实例(单例模式)
private static $instance = null;
private $pdo;

// 私有构造函数
private function __construct($host, $username, $password, $database) {
try {
$dsn = "mysql:host=$host;dbname=$database;charset=utf8";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$this->pdo = new PDO($dsn, $username, $password, $options);
} catch (PDOException $e) {
die("Connection failed: " . $e->getMessage());
}
}

// 获取单例实例
public static function getInstance($host = 'localhost', $username = 'root', $password = '', $database = 'test_db') {
if (self::$instance === null) {
self::$instance = new self($host, $username, $password, $database);
}
return self::$instance;
}

// 获取连接
public function getConnection() {
return $this->pdo;
}

// 静态方法:执行查询
public static function query($sql, $params = []) {
$instance = self::getInstance();
$stmt = $instance->pdo->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll();
}

// 静态方法:插入数据
public static function insert($table, $data) {
$instance = self::getInstance();
$keys = array_keys($data);
$placeholders = array_map(function($key) { return ":$key"; }, $keys);

$sql = "INSERT INTO $table (" . implode(',', $keys) . ") VALUES (" . implode(',', $placeholders) . ")";
$stmt = $instance->pdo->prepare($sql);

foreach ($data as $key => $value) {
$stmt->bindValue(":$key", $value);
}

$stmt->execute();
return $instance->pdo->lastInsertId();
}

// 静态方法:开始事务
public static function beginTransaction() {
$instance = self::getInstance();
return $instance->pdo->beginTransaction();
}

// 静态方法:提交事务
public static function commit() {
$instance = self::getInstance();
return $instance->pdo->commit();
}

// 静态方法:回滚事务
public static function rollBack() {
$instance = self::getInstance();
return $instance->pdo->rollBack();
}

private function __clone() {}
}

try {
// 创建连接
$pdo = PDODatabase::getInstance($host, $username, $password, $database)->getConnection();
echo "Connected to database using PDO\n";

// 创建表
$createTable = "CREATE TABLE IF NOT EXISTS users (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)";
$pdo->exec($createTable);
echo "Table 'users' created successfully\n";

// 插入数据(预处理语句)
$name = "Alice Johnson";
$email = "alice@example.com";
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (:name, :email)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':email', $email);
$stmt->execute();
echo "New record created using prepared statement\n";

// 使用静态方法插入数据
$userId = PDODatabase::insert('users', [
'name' => 'PDO Static User',
'email' => 'pdo_static@example.com'
]);
echo "User created with ID: $userId\n";

// 查询数据
$stmt = $pdo->query("SELECT id, name, email FROM users");
$users = $stmt->fetchAll();

if (count($users) > 0) {
echo "Users:\n";
foreach ($users as $user) {
echo "ID: " . $user['id'] . " - Name: " . $user['name'] . " - Email: " . $user['email'] . "\n";
}
} else {
echo "No users found\n";
}

// 使用静态方法查询
$johnUsers = PDODatabase::query("SELECT id, name, email FROM users WHERE name = :name", [':name' => 'John Doe']);
if (count($johnUsers) > 0) {
echo "Found John users:\n";
foreach ($johnUsers as $user) {
echo "ID: " . $user['id'] . " - Name: " . $user['name'] . " - Email: " . $user['email'] . "\n";
}
} else {
echo "No users named John found\n";
}

// 更新数据
$email = "updated@example.com";
$name = "Alice Johnson";
$stmt = $pdo->prepare("UPDATE users SET email = :email WHERE name = :name");
$stmt->bindParam(':email', $email);
$stmt->bindParam(':name', $name);
$stmt->execute();
echo "Record updated successfully\n";

// 事务示例
PDODatabase::beginTransaction();
try {
PDODatabase::insert('users', [
'name' => 'Transaction User',
'email' => 'pdo_transaction@example.com'
]);

PDODatabase::insert('users', [
'name' => 'Another User',
'email' => 'pdo_another@example.com'
]);

// 模拟错误
// PDODatabase::query("INVALID SQL");

PDODatabase::commit();
echo "Transaction completed successfully\n";
} catch (PDOException $e) {
PDODatabase::rollBack();
echo "Transaction failed: " . $e->getMessage() . "\n";
}

// 关闭连接
$pdo = null;
} catch (PDOException $e) {
die("Connection failed: " . $e->getMessage());
}

综合大例子:博客系统

以下是一个综合性的Web应用示例,包含所有前面介绍的知识点:

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
<?php
// 1. 命名空间和引入
namespace BlogApp;

use DateTime;
use Exception;
use PDO;
use PDOException;

// 2. 配置
define("DB_HOST", "localhost");
define("DB_NAME", "blog_db");
define("DB_USER", "root");
define("DB_PASS", "password");
define("MAX_POSTS_PER_PAGE", 5);

// 3. 工具类
class Utils {
// 静态缓存
private static $cache = [];

// 静态方法:清理输入
public static function sanitizeInput($data) {
return htmlspecialchars(trim($data), ENT_QUOTES, 'UTF-8');
}

// 静态方法:重定向
public static function redirect($url) {
header("Location: $url");
exit();
}

// 静态方法:获取当前URL
public static function getCurrentUrl() {
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
$uri = $_SERVER['REQUEST_URI'];
return "$protocol://$host$uri";
}

// 静态方法:缓存结果
public static function cached($key, $callback, $ttl = 3600) {
if (isset(self::$cache[$key])) {
return self::$cache[$key];
}

$result = $callback();
self::$cache[$key] = $result;
return $result;
}
}

// 4. 数据库连接类(单例模式)
class Database {
// 静态实例
private static $instance = null;
private $pdo;

// 私有构造函数
private function __construct() {
try {
$dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_PERSISTENT => true
];
$this->pdo = new PDO($dsn, DB_USER, DB_PASS, $options);
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
}

// 获取单例实例
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}

// 获取连接
public function getConnection() {
return $this->pdo;
}

// 静态方法:执行查询
public static function query($sql, $params = []) {
$instance = self::getInstance();
$stmt = $instance->pdo->prepare($sql);
$stmt->execute($params);
return $stmt;
}

// 静态方法:获取所有结果
public static function fetchAll($sql, $params = []) {
$stmt = self::query($sql, $params);
return $stmt->fetchAll();
}

// 静态方法:获取单行结果
public static function fetchOne($sql, $params = []) {
$stmt = self::query($sql, $params);
return $stmt->fetch();
}

// 静态方法:插入数据
public static function insert($table, $data) {
$columns = implode(',', array_keys($data));
$placeholders = ':' . implode(',:', array_keys($data));

$sql = "INSERT INTO $table ($columns) VALUES ($placeholders)";
$stmt = self::query($sql, $data);

$instance = self::getInstance();
return $instance->pdo->lastInsertId();
}

private function __clone() {}
}

// 5. 用户类
class User {
// 静态缓存
private static $userCache = [];

private $id;
private $name;
private $email;
private $password;

public function __construct($name, $email, $password) {
$this->name = $name;
$this->email = $email;
$this->password = password_hash($password, PASSWORD_DEFAULT);
}

public function save() {
$userId = Database::insert('users', [
'name' => $this->name,
'email' => $this->email,
'password' => $this->password
]);
$this->id = $userId;
return true;
}

// 静态方法:用户认证
public static function authenticate($email, $password) {
$sql = "SELECT * FROM users WHERE email = :email";
$user = Database::fetchOne($sql, [':email' => $email]);

if ($user && password_verify($password, $user['password'])) {
return $user;
}
return false;
}

// 静态方法:获取用户
public static function getById($id) {
// 检查缓存
if (isset(self::$userCache[$id])) {
return self::$userCache[$id];
}

$sql = "SELECT * FROM users WHERE id = :id";
$user = Database::fetchOne($sql, [':id' => $id]);

// 缓存结果
if ($user) {
self::$userCache[$id] = $user;
}

return $user;
}

// 静态方法:获取所有用户
public static function getAll() {
return Database::fetchAll("SELECT * FROM users");
}
}

// 6. 博客文章类
class Post {
private $id;
private $title;
private $content;
private $authorId;
private $createdAt;

public function __construct($title, $content, $authorId) {
$this->title = $title;
$this->content = $content;
$this->authorId = $authorId;
$this->createdAt = new DateTime();
}

public function save() {
$postId = Database::insert('posts', [
'title' => $this->title,
'content' => $this->content,
'author_id' => $this->authorId,
'created_at' => $this->createdAt->format('Y-m-d H:i:s')
]);
$this->id = $postId;
return true;
}

// 静态方法:获取所有文章
public static function getAll($page = 1, $limit = MAX_POSTS_PER_PAGE) {
$offset = ($page - 1) * $limit;
$sql = "SELECT p.*, u.name as author_name
FROM posts p
JOIN users u ON p.author_id = u.id
ORDER BY p.created_at DESC
LIMIT :limit OFFSET :offset";

$stmt = Database::getInstance()->getConnection()->prepare($sql);
$stmt->bindValue(':limit', (int)$limit, PDO::PARAM_INT);
$stmt->bindValue(':offset', (int)$offset, PDO::PARAM_INT);
$stmt->execute();

return $stmt->fetchAll();
}

// 静态方法:获取文章总数
public static function getCount() {
return Database::fetchOne("SELECT COUNT(*) as count FROM posts")['count'];
}

// 静态方法:获取单篇文章
public static function getById($id) {
$sql = "SELECT p.*, u.name as author_name
FROM posts p
JOIN users u ON p.author_id = u.id
WHERE p.id = :id";
return Database::fetchOne($sql, [':id' => $id]);
}

// 静态方法:按作者获取文章
public static function getByAuthor($authorId) {
$sql = "SELECT * FROM posts WHERE author_id = :author_id ORDER BY created_at DESC";
return Database::fetchAll($sql, [':author_id' => $authorId]);
}

// 静态方法:搜索文章
public static function search($query) {
$sql = "SELECT p.*, u.name as author_name
FROM posts p
JOIN users u ON p.author_id = u.id
WHERE p.title LIKE :query OR p.content LIKE :query
ORDER BY p.created_at DESC";
return Database::fetchAll($sql, [':query' => "%$query%"]);
}
}

// 7. 路由处理
function handleRequest() {
$path = $_SERVER['REQUEST_URI'];
$method = $_SERVER['REQUEST_METHOD'];

// 静态文件处理
if (preg_match('/\.(css|js|png|jpg|jpeg|gif)$/', $path)) {
return;
}

// 路由
if ($path === '/' || $path === '/index.php') {
showHome();
} elseif ($path === '/login' && $method === 'GET') {
showLoginForm();
} elseif ($path === '/login' && $method === 'POST') {
processLogin();
} elseif ($path === '/register' && $method === 'GET') {
showRegistrationForm();
} elseif ($path === '/register' && $method === 'POST') {
processRegistration();
} elseif (preg_match('/^\/post\/(\d+)$/', $path, $matches)) {
showPost($matches[1]);
} elseif ($path === '/create' && $method === 'GET') {
showCreateForm();
} elseif ($path === '/create' && $method === 'POST') {
processCreatePost();
} elseif ($path === '/search' && $method === 'GET') {
showSearchResults();
} elseif ($path === '/logout') {
processLogout();
} else {
show404();
}
}

// 8. 视图函数
function render($template, $data = []) {
extract($data);
include "views/$template.php";
}

function showHome() {
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$posts = Post::getAll($page);
$totalPosts = Post::getCount();
$totalPages = ceil($totalPosts / MAX_POSTS_PER_PAGE);

render('home', [
'title' => 'My Blog',
'posts' => $posts,
'currentPage' => $page,
'totalPages' => $totalPages,
'hasNextPage' => $page < $totalPages,
'hasPrevPage' => $page > 1
]);
}

function showLoginForm() {
$error = $_SESSION['login_error'] ?? null;
unset($_SESSION['login_error']);

render('login', [
'title' => 'Login',
'error' => $error
]);
}

function processLogin() {
$email = Utils::sanitizeInput($_POST['email'] ?? '');
$password = $_POST['password'] ?? '';

$user = User::authenticate($email, $password);

if ($user) {
session_start();
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['name'];
Utils::redirect('/');
} else {
session_start();
$_SESSION['login_error'] = "Invalid email or password";
Utils::redirect('/login');
}
}

function showRegistrationForm() {
$errors = $_SESSION['registration_errors'] ?? [];
$formData = $_SESSION['form_data'] ?? [];
unset($_SESSION['registration_errors'], $_SESSION['form_data']);

render('register', [
'title' => 'Register',
'errors' => $errors,
'formData' => $formData
]);
}

function processRegistration() {
$name = Utils::sanitizeInput($_POST['name'] ?? '');
$email = Utils::sanitizeInput($_POST['email'] ?? '');
$password = $_POST['password'] ?? '';
$confirmPassword = $_POST['confirm_password'] ?? '';

$errors = [];
$formData = [
'name' => $name,
'email' => $email
];

if (empty($name)) {
$errors[] = "Name is required";
}

if (empty($email)) {
$errors[] = "Email is required";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "Invalid email format";
}

if (empty($password)) {
$errors[] = "Password is required";
} elseif (strlen($password) < 8) {
$errors[] = "Password must be at least 8 characters";
}

if ($password !== $confirmPassword) {
$errors[] = "Passwords do not match";
}

if (empty($errors)) {
try {
$user = new User($name, $email, $password);
$user->save();
Utils::redirect('/login');
} catch (Exception $e) {
$errors[] = "Registration failed: " . $e->getMessage();
}
}

session_start();
$_SESSION['registration_errors'] = $errors;
$_SESSION['form_data'] = $formData;
Utils::redirect('/register');
}

function showPost($id) {
$post = Post::getById($id);

if (!$post) {
show404();
return;
}

// 使用静态缓存获取作者
$author = Utils::cached("user_{$post['author_id']}", function() use ($post) {
return User::getById($post['author_id']);
});

render('post', [
'title' => $post['title'],
'post' => $post,
'author' => $author
]);
}

function showCreateForm() {
session_start();

if (!isset($_SESSION['user_id'])) {
Utils::redirect('/login');
return;
}

$errors = $_SESSION['post_errors'] ?? [];
$formData = $_SESSION['post_data'] ?? [];
unset($_SESSION['post_errors'], $_SESSION['post_data']);

render('create', [
'title' => 'Create New Post',
'errors' => $errors,
'formData' => $formData
]);
}

function processCreatePost() {
session_start();

if (!isset($_SESSION['user_id'])) {
Utils::redirect('/login');
return;
}

$title = Utils::sanitizeInput($_POST['title'] ?? '');
$content = $_POST['content'] ?? '';

$errors = [];
$formData = [
'title' => $title,
'content' => $content
];

if (empty($title)) {
$errors[] = "Title is required";
}

if (empty($content)) {
$errors[] = "Content is required";
}

if (empty($errors)) {
try {
$post = new Post($title, $content, $_SESSION['user_id']);
$post->save();
Utils::redirect('/');
} catch (Exception $e) {
$errors[] = "Error creating post: " . $e->getMessage();
}
}

$_SESSION['post_errors'] = $errors;
$_SESSION['post_data'] = $formData;
Utils::redirect('/create');
}

function showSearchResults() {
$query = Utils::sanitizeInput($_GET['q'] ?? '');

if (empty($query)) {
Utils::redirect('/');
return;
}

// 缓存搜索结果
$searchResults = Utils::cached("search_$query", function() use ($query) {
return Post::search($query);
});

render('search', [
'title' => "Search Results for '$query'",
'query' => $query,
'results' => $searchResults
]);
}

function processLogout() {
session_start();
session_destroy();
Utils::redirect('/');
}

function show404() {
http_response_code(404);
render('404', ['title' => 'Page Not Found']);
}

// 9. 初始化
session_start();

// 10. 创建数据库表(如果不存在)
function initializeDatabase() {
$db = Database::getInstance()->getConnection();

// 创建用户表
$createUsersTable = "CREATE TABLE IF NOT EXISTS users (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)";
$db->exec($createUsersTable);

// 创建文章表
$createPostsTable = "CREATE TABLE IF NOT EXISTS posts (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
author_id INT(6) UNSIGNED NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE CASCADE
)";
$db->exec($createPostsTable);
}

// 11. 启动应用
initializeDatabase();
handleRequest();

这个综合示例展示了:

  • 命名空间和类组织:使用命名空间组织代码,提高可维护性
  • 静态方法和成员:使用静态方法实现工具类、单例模式和缓存
  • 数据库连接和操作:使用PDO实现安全的数据库操作
  • 用户认证和会话管理:实现登录、注册和会话管理
  • 表单处理和验证:验证用户输入,处理表单错误
  • 路由和控制器逻辑:基于URL和HTTP方法处理请求
  • 视图渲染:分离业务逻辑和展示逻辑
  • 错误处理:捕获和处理异常,提供友好的错误页面
  • 安全措施:输入清理、密码哈希、防止SQL注入
  • 缓存机制:使用静态属性实现简单的缓存
  • 分页功能:实现文章分页显示
  • 搜索功能:实现全文搜索
  • 单例模式:使用静态实例确保数据库连接唯一性
  • 静态工具类:提供各种工具方法,如输入清理、重定向等
  • 对象关系映射:将数据库记录映射为对象
  • 事务处理:确保数据一致性
  • 代码复用:使用静态方法减少代码重复