第十三章-PHP MySQL扩展

第十三章-PHP与MySQL

一,连接数据库

1. 使用 MySQLi(面向对象方式)

<?php
// 数据库参数
$host = 'localhost';
$username = 'root';
$password = '';
$database = 'test_db';// 创建连接
$conn = new mysqli($host, $username, $password, $database);// 检查连接是否成功
if ($conn->connect_error) {die("连接失败: " . $conn->connect_error);
}echo "数据库连接成功!";// 执行查询示例
$sql = "SELECT id, name FROM users";
$result = $conn->query($sql);if ($result->num_rows > 0) {while ($row = $result->fetch_assoc()) {echo "ID: " . $row["id"] . ",姓名: " . $row["name"];}
} else {echo "没有查询到数据";
}// 关闭连接
$conn->close();
?>

2. 使用 MySQLi(过程化方式)

<?php
$host = 'localhost';
$username = 'root';
$password = '';
$database = 'test_db';// 创建连接
$conn = mysqli_connect($host, $username, $password, $database);// 检查连接
if (!$conn) {die("连接失败: " . mysqli_connect_error());
}echo "数据库连接成功!";// 执行查询示例
$sql = "SELECT id, name FROM users";
$result = mysqli_query($conn, $sql);if (mysqli_num_rows($result) > 0) {while ($row = mysqli_fetch_assoc($result)) {echo "ID: " . $row["id"] . ",姓名: " . $row["name"];}
}// 关闭连接
mysqli_close($conn);
?>

3. 使用 PDO(支持多种数据库)

<?php
$host = 'localhost';
$database = 'test_db';
$username = 'root';
$password = '';try {// 创建 PDO 连接$conn = new PDO("mysql:host=$host;dbname=$database", $username, $password);// 设置错误模式为异常捕获$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);echo "数据库连接成功!";// 执行查询示例(使用预处理语句防注入)$sql = "SELECT id, name FROM users";$stmt = $conn->prepare($sql);$stmt->execute();// 获取结果$result = $stmt->fetchAll(PDO::FETCH_ASSOC);foreach ($result as $row) {echo "ID: " . $row["id"] . ",姓名: " . $row["name"];}} catch (PDOException $e) {die("连接失败: " . $e->getMessage());
}// 关闭连接(PDO 自动管理)
$conn = null;
?>

关键注意事项

  1. 防止 SQL 注入

    • 使用预处理语句(如 $stmt->prepare() + bindParamexecute([参数]))。

    • 示例(PDO 预处理):

      $stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (:name, :email)");
      $stmt->bindParam(':name', $name);
      $stmt->bindParam(':email', $email);
      $stmt->execute();
      
  2. 错误处理

    • MySQLi 使用 $conn->connect_errormysqli_connect_error()
    • PDO 使用异常捕获(try...catch + setAttribute)。
  3. 关闭连接

    • MySQLi:$conn->close()mysqli_close($conn)
    • PDO:$conn = null

常见问题

  • 连接失败可能原因

    1. 用户名/密码错误
    2. 数据库未启动
    3. 防火墙阻止连接
    4. PHP 未启用 MySQLi/PDO 扩展(检查 php.ini
  • 启用扩展
    php.ini 中取消注释:

    ;extension=mysqli
    ;extension=pdo_mysql
    

    重启 Web 服务器生效。


二、增删改查操作实现

1. 增加数据(Create)

MySQLi 预处理插入
// 准备预处理语句
$stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email); // "ss" 表示两个字符串参数// 设置参数并执行
$name = "张三";
$email = "zhangsan@example.com";
$stmt->execute();echo "插入成功,ID: " . $stmt->insert_id;
$stmt->close();
PDO 预处理插入
try {$sql = "INSERT INTO users (name, email) VALUES (:name, :email)";$stmt = $conn->prepare($sql);// 绑定参数并执行$stmt->execute([':name' => '李四',':email' => 'lisi@example.com']);echo "插入成功,ID: " . $conn->lastInsertId();
} catch (PDOException $e) {echo "错误: " . $e->getMessage();
}

2. 查询数据(Read)

MySQLi 查询并遍历结果
$sql = "SELECT id, name, email FROM users";
$result = $conn->query($sql);if ($result->num_rows > 0) {while ($row = $result->fetch_assoc()) {echo "ID: {$row['id']}, 姓名: {$row['name']}, 邮箱: {$row['email']}<br>";}
} else {echo "没有数据";
}
$result->free(); // 释放结果集
PDO 查询并遍历结果
try {$stmt = $conn->query("SELECT id, name, email FROM users");$results = $stmt->fetchAll(PDO::FETCH_ASSOC);foreach ($results as $row) {echo "ID: {$row['id']}, 姓名: {$row['name']}, 邮箱: {$row['email']}<br>";}
} catch (PDOException $e) {echo "错误: " . $e->getMessage();
}

3. 更新数据(Update)

MySQLi 预处理更新
$stmt = $conn->prepare("UPDATE users SET email = ? WHERE id = ?");
$stmt->bind_param("si", $email, $id); // "si" 表示字符串和整数$email = "new_email@example.com";
$id = 1;
$stmt->execute();echo "更新了 {$stmt->affected_rows} 条记录";
$stmt->close();
PDO 预处理更新
try {$sql = "UPDATE users SET email = :email WHERE id = :id";$stmt = $conn->prepare($sql);$stmt->execute([':email' => 'updated@example.com',':id' => 1]);echo "更新了 {$stmt->rowCount()} 条记录";
} catch (PDOException $e) {echo "错误: " . $e->getMessage();
}

4. 删除数据(Delete)

MySQLi 预处理删除
$stmt = $conn->prepare("DELETE FROM users WHERE id = ?");
$stmt->bind_param("i", $id); // "i" 表示整数$id = 2;
$stmt->execute();echo "删除了 {$stmt->affected_rows} 条记录";
$stmt->close();
PDO 预处理删除
try {$sql = "DELETE FROM users WHERE id = :id";$stmt = $conn->prepare($sql);$stmt->execute([':id' => 3]);echo "删除了 {$stmt->rowCount()} 条记录";
} catch (PDOException $e) {echo "错误: " . $e->getMessage();
}

5.安全与最佳实践

  1. 始终使用预处理语句

    • 避免 SQL 注入攻击,禁止直接拼接用户输入到 SQL 中。
  2. 错误处理

    • MySQLi 检查 $conn->error,PDO 使用 try...catch 捕获异常。
  3. 关闭连接

    // MySQLi
    $conn->close();// PDO
    $conn = null;
    
  4. 验证输入数据

    • 使用 filter_var() 验证邮箱、URL 等格式。
    • 检查数值范围(如 $id > 0)。

6.完整流程图

1. 连接数据库 → 2. 准备SQL语句 → 3. 绑定参数 → 4. 执行操作 → 5. 处理结果 → 6. 关闭连接

7.扩展建议

  • 使用 ORM 框架
    如 Laravel 的 Eloquent 或 Doctrine,简化数据库操作。

  • 事务处理
    对于多个关联操作,使用事务保证数据一致性:

    // PDO 事务示例
    $conn->beginTransaction();
    try {$conn->exec("UPDATE account SET balance = balance - 100 WHERE id = 1");$conn->exec("UPDATE account SET balance = balance + 100 WHERE id = 2");$conn->commit();
    } catch (Exception $e) {$conn->rollBack();echo "事务失败: " . $e->getMessage();
    }
    

三,网站查询操作

一,OOP 写法

OOP(面向对象编程,Object-Oriented Programming) 是一种程序设计思想和方法,它把数据对数据的操作组织成对象(Object),通过对象之间的交互来完成程序设计。

OOP 的核心概念
  1. 类(Class)
    • 类是对象的蓝图或模板,定义了对象的属性(数据)**和**方法(操作)
    • 比如:“狗”可以是一个类,它有颜色、品种这些属性,还有叫、跑这些方法。
  2. 对象(Object)
    • 对象是类的实例,是具体存在的个体。
    • 比如:“小黑”是一只狗,它是“狗”类的一个对象。
  3. 封装(Encapsulation)
    • 把数据和操作数据的方法打包在一起,对外隐藏内部细节,只暴露必要的接口。
    • 好处是保护数据安全,减少外部干扰。
  4. 继承(Inheritance)
    • 子类可以继承父类的属性和方法,复用代码,还可以扩展或修改已有功能。
    • 比如,“哈士奇”类可以继承“狗”类的基本特性,再加上自己的特性。
  5. 多态(Polymorphism)
    • 同一种方法在不同对象上可以有不同表现
    • 比如,不同动物的“叫”方法,狗叫“汪汪”,猫叫“喵喵”,但都可以统一调用“叫”这个动作。
$mysqli = new mysqli('localhost', 'dbuser', 'dbpass', 'dbname');
if ($mysqli->connect_errno) {throw new Exception('数据库连接失败:' . $mysqli->connect_error);
}
$mysqli->set_charset('utf8mb4');$sql = "SELECT id, username, email FROM users WHERE status = 1 AND is_deleted = 0 ORDER BY created_at DESC LIMIT 10";
$result = $mysqli->query($sql);if (!$result) {throw new Exception('查询失败:' . $mysqli->error);
}$data = [];
while ($row = $result->fetch_assoc()) {$data[] = $row;
}
$result->free();// 返回数据
return $data;
  • 必须判断连接和查询是否成功
  • 必须释放结果集
  • 查询多行,循环 fetch_assoc() 拼到数组里
  • 查询限制条件齐全:WHEREORDER BYLIMIT 都要标准化

二、参数化查询(防SQL注入)

生产环境绝对禁止拼接变量,必须用预处理。

示例:按用户名模糊搜索
$stmt = $mysqli->prepare("SELECT id, username, email FROM users WHERE username LIKE CONCAT('%', ?, '%') AND status = 1 LIMIT 20");
if (!$stmt) {throw new Exception('预处理失败:' . $mysqli->error);
}$keyword = 'alice'; // 搜索关键词
$stmt->bind_param('s', $keyword);
$stmt->execute();$result = $stmt->get_result();
$data = [];
while ($row = $result->fetch_assoc()) {$data[] = $row;
}
$stmt->close();return $data;
  • 预处理 (prepare + bind_param) 必须使用
  • 模糊搜索需要 CONCAT('%', ?, '%') 写法
  • 不要用变量直接拼接到 SQL 字符串里

三、查询单条记录

如果只查一行,可以直接用 fetch_assoc() 拿一次。

php复制编辑$stmt = $mysqli->prepare("SELECT id, username, email FROM users WHERE id = ?");
$stmt->bind_param('i', $user_id);
$stmt->execute();$result = $stmt->get_result();
$user = $result->fetch_assoc();
$stmt->close();// 检查是否查到
if (!$user) {throw new Exception('用户不存在');
}return $user;
  • fetch_assoc() 只取一行,后面不用循环
  • 查不到数据时要有异常/提示处理

四、分页查询(带总数)

分页查询是非常常见需求,要返回数据和总数。

$page = 1;
$page_size = 10;
$offset = ($page - 1) * $page_size;// 1. 查询数据
$stmt = $mysqli->prepare("SELECT id, username, email FROM users WHERE status = 1 LIMIT ?, ?");
$stmt->bind_param('ii', $offset, $page_size);
$stmt->execute();
$result = $stmt->get_result();
$list = [];
while ($row = $result->fetch_assoc()) {$list[] = $row;
}
$stmt->close();// 2. 查询总条数
$sql_total = "SELECT COUNT(*) AS total FROM users WHERE status = 1";
$res_total = $mysqli->query($sql_total);
$total_row = $res_total->fetch_assoc();
$total = (int)$total_row['total'];
$res_total->free();// 返回分页结果
return ['list'  => $list,'total' => $total
];
  • 分页必须返回数据列表 + 总条数
  • 分开两次查询更稳(一次查数据,一次查总数)

五、复杂条件动态查询(实战重点)

有些条件是用户输入的,要动态拼条件,但还要防注入。常规做法是动态构造 SQL + 参数绑定

$conditions = [];
$params = [];
$types = '';// 假设有用户搜索过滤
if (!empty($filter['username'])) {$conditions[] = "username LIKE CONCAT('%', ?, '%')";$params[] = $filter['username'];$types .= 's';
}
if (isset($filter['status'])) {$conditions[] = "status = ?";$params[] = (int)$filter['status'];$types .= 'i';
}$where = $conditions ? 'WHERE ' . implode(' AND ', $conditions) : '';$sql = "SELECT id, username, email FROM users $where ORDER BY created_at DESC LIMIT 20";
$stmt = $mysqli->prepare($sql);
if ($params) {$stmt->bind_param($types, ...$params);
}
$stmt->execute();
$result = $stmt->get_result();$data = [];
while ($row = $result->fetch_assoc()) {$data[] = $row;
}
$stmt->close();return $data;
  • 拼接 SQL 时 条件动态组装,值用绑定
  • 类型字符串 $types 也要跟着参数增长
  • 防止 SQL 注入,同时又灵活

总结

方面要点
查询数据query 或 prepare + get_result
查询多行while(fetch_assoc)
查询单行fetch_assoc 直接用
分页查询两次查询:数据和总数分开
防SQL注入预处理 + bind_param
动态条件组装 WHERE 和 参数,分离绑定
稳定性保障任何 query 或 prepare 后必须判断成功
字符集设置$mysqli->set_charset('utf8mb4') 避免乱码

四,相关函数

一,核心函数分类及用法

1. 连接与关闭
  • 创建连接

    // 面向对象
    $mysqli = new mysqli("localhost", "user", "password", "database", 3306);// 过程式
    $link = mysqli_connect("localhost", "user", "password", "database", 3306);
    
    • 失败行为:默认返回 false,但若启用 MYSQLI_REPORT_STRICT 模式,会抛出 mysqli_sql_exception
  • 检查连接错误

    // 面向对象
    if ($mysqli->connect_errno) {die("连接失败: " . $mysqli->connect_error);
    }// 过程式
    if (mysqli_connect_errno()) {die("连接失败: " . mysqli_connect_error());
    }
    
  • 关闭连接

    $mysqli->close();       // 面向对象
    mysqli_close($link);    // 过程式
    

2. 执行查询
  • 执行普通查询

    // 面向对象
    $result = $mysqli->query("SELECT * FROM users");
    // 过程式
    $result = mysqli_query($link, "SELECT * FROM users");
    
    • 返回值
      • 成功(SELECT/SHOW/DESCRIBE)返回 mysqli_result 对象。
      • 成功(INSERT/UPDATE/DELETE)返回 true
      • 失败返回 false(或抛出异常)。
  • 获取结果数据

    // 获取关联数组
    while ($row = $result->fetch_assoc()) {echo $row["name"];
    }// 或直接获取所有数据
    $data = $result->fetch_all(MYSQLI_ASSOC);
    

3. 预处理语句(防 SQL 注入)
  • 步骤prepare()bind_param()execute()get_result()

    $stmt = $mysqli->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
    $name = "Alice";
    $email = "alice@example.com";// 绑定参数(类型标识符:s=string, i=int, d=double, b=blob)
    $stmt->bind_param("ss", $name, $email);// 执行
    $stmt->execute();// 获取插入的 ID
    $inserted_id = $stmt->insert_id;// 关闭预处理语句
    $stmt->close();
    

4. 事务处理
  • 开启事务

    $mysqli->begin_transaction();try {$mysqli->query("UPDATE account SET balance = balance - 100 WHERE user_id = 1");$mysqli->query("UPDATE account SET balance = balance + 100 WHERE user_id = 2");$mysqli->commit(); // 提交事务
    } catch (mysqli_sql_exception $e) {$mysqli->rollback(); // 回滚echo "事务失败: " . $e->getMessage();
    }
    

5. 错误与异常处理
  • 启用严格异常模式

    $driver = new mysqli_driver();
    $driver->report_mode = MYSQLI_REPORT_STRICT | MYSQLI_REPORT_ERROR;
    
  • 捕获异常

    try {$mysqli->query("INVALID SQL");
    } catch (mysqli_sql_exception $e) {echo "错误信息: " . $e->getMessage();echo "错误代码: " . $e->getCode();
    }
    

二、PHP 8.0 关键变更与适配

1. 类型严格性
  • 参数类型检查
    例如 mysqli_query($link, 123) 中的第二个参数必须为字符串,否则抛出 TypeError

    // PHP 8.0 会报错,PHP 7.x 仅警告
    $mysqli->query(123); // 错误:参数必须为字符串
    
2. 弃用与移除
  • 弃用函数
    • mysqli::get_client_info()(无参数调用)需改为 mysqli_get_client_info()
  • 移除别名
    • mysqli_bind_param()mysqli_bind_result() 已移除,仅保留 mysqli_stmt_bind_param()

三、常用函数速查表

函数用途示例
mysqli_connect()建立数据库连接$link = mysqli_connect(...)
mysqli_query()执行 SQL 查询$result = mysqli_query($link, $sql)
mysqli_prepare()创建预处理语句$stmt = mysqli_prepare($link, $sql)
mysqli_stmt_bind_param()绑定预处理语句参数mysqli_stmt_bind_param($stmt, "si", ...)
mysqli_fetch_assoc()获取关联数组结果$row = mysqli_fetch_assoc($result)
mysqli_insert_id()获取最后插入的 ID$id = mysqli_insert_id($link)
mysqli_affected_rows()获取受影响的行数$count = mysqli_affected_rows($link)
mysqli_real_escape_string()转义字符串(用于非预处理语句)$safe = mysqli_real_escape_string($link, $input)

四、最佳实践

  1. 始终使用预处理语句:避免 SQL 注入,尤其是处理用户输入时。

  2. 启用异常模式

    $driver = new mysqli_driver();
    $driver->report_mode = MYSQLI_REPORT_STRICT | MYSQLI_REPORT_ERROR;
    
  3. 关闭调试信息:生产环境中隐藏数据库错误细节,记录到日志文件。

  4. 资源释放:及时关闭 mysqli_result 和预处理语句对象。


项目名称:学生信息管理系统

功能需求

  1. 查看学生列表
  2. 添加新学生
  3. 编辑学生信息
  4. 删除学生
  5. 简单的搜索功能

技术栈

  • 前端:HTML + Bootstrap 5(极简界面)
  • 后端:PHP 8.0+(面向过程编程)
  • 数据库:MySQL 5.7+
  • 安全:MySQLi 预处理语句、输入过滤

项目结构

/student_manager
├── index.php         # 显示学生列表
├── create.php        # 添加新学生
├── edit.php          # 编辑学生信息
├── delete.php        # 删除学生
├── config.php        # 数据库配置
└── style.css         # 简单样式

数据库设计

表名:students

CREATE TABLE students (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL,email VARCHAR(100) UNIQUE NOT NULL,age INT NOT NULL
);

核心代码实现

1. 数据库配置文件 (config.php)
<?php
// 数据库配置
$host = 'localhost';
$user = 'root';
$password = '123456';
$database = 'student_db';// 创建连接
$mysqli = new mysqli($host, $user, $password, $database);// 检查连接
if ($mysqli->connect_error) {die("连接失败: " . $mysqli->connect_error);
}// 设置字符集
$mysqli->set_charset('utf8mb4');
?>

2. 显示学生列表 (index.php)
<?php
include 'config.php';// 搜索功能
$search = $_GET['search'] ?? '';
$query = "SELECT * FROM students";
if (!empty($search)) {$query .= " WHERE name LIKE ?";$stmt = $mysqli->prepare($query);$search_term = "%$search%";$stmt->bind_param('s', $search_term);
} else {$stmt = $mysqli->prepare($query);
}$stmt->execute();
$result = $stmt->get_result();
?><!DOCTYPE html>
<html>
<head><title>学生管理系统</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5"><h2>学生列表</h2><!-- 搜索框 --><form class="mb-3"><input type="text" name="search" placeholder="输入姓名搜索" class="form-control"><button type="submit" class="btn btn-primary mt-2">搜索</button></form><!-- 添加学生链接 --><a href="create.php" class="btn btn-success mb-3">添加新学生</a><!-- 学生表格 --><table class="table table-striped"><thead><tr><th>ID</th><th>姓名</th><th>邮箱</th><th>年龄</th><th>操作</th></tr></thead><tbody><?php while ($row = $result->fetch_assoc()): ?><tr><td><?= htmlspecialchars($row['id']) ?></td><td><?= htmlspecialchars($row['name']) ?></td><td><?= htmlspecialchars($row['email']) ?></td><td><?= htmlspecialchars($row['age']) ?></td><td><a href="edit.php?id=<?= $row['id'] ?>" class="btn btn-warning btn-sm">编辑</a><a href="delete.php?id=<?= $row['id'] ?>" class="btn btn-danger btn-sm" onclick="return confirm('确认删除?')">删除</a></td></tr><?php endwhile; ?></tbody></table>
</div>
</body>
</html>

3. 添加学生 (create.php)
<?php
include 'config.php';if ($_SERVER['REQUEST_METHOD'] === 'POST') {$name = $_POST['name'];$email = $_POST['email'];$age = $_POST['age'];// 使用预处理语句防止SQL注入$stmt = $mysqli->prepare("INSERT INTO students (name, email, age) VALUES (?, ?, ?)");$stmt->bind_param('ssi', $name, $email, $age);if ($stmt->execute()) {header('Location: index.php'); // 添加成功跳转exit;} else {$error = "添加失败: " . $stmt->error;}
}
?><!DOCTYPE html>
<html>
<head><title>添加学生</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5"><h2>添加新学生</h2><?php if (!empty($error)): ?><div class="alert alert-danger"><?= $error ?></div><?php endif; ?><form method="POST"><div class="mb-3"><label class="form-label">姓名</label><input type="text" name="name" class="form-control" required></div><div class="mb-3"><label class="form-label">邮箱</label><input type="email" name="email" class="form-control" required></div><div class="mb-3"><label class="form-label">年龄</label><input type="number" name="age" class="form-control" required></div><button type="submit" class="btn btn-primary">提交</button></form>
</div>
</body>
</html>

4. 编辑学生 (edit.php)
<?php
include 'config.php';// 获取当前学生信息
$id = $_GET['id'];
$stmt = $mysqli->prepare("SELECT * FROM students WHERE id = ?");
$stmt->bind_param('i', $id);
$stmt->execute();
$student = $stmt->get_result()->fetch_assoc();if ($_SERVER['REQUEST_METHOD'] === 'POST') {$name = $_POST['name'];$email = $_POST['email'];$age = $_POST['age'];$stmt = $mysqli->prepare("UPDATE students SET name=?, email=?, age=? WHERE id=?");$stmt->bind_param('ssii', $name, $email, $age, $id);if ($stmt->execute()) {header('Location: index.php'); // 更新成功跳转exit;} else {$error = "更新失败: " . $stmt->error;}
}
?><!DOCTYPE html>
<html>
<head><title>编辑学生</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5"><h2>编辑学生信息</h2><?php if (!empty($error)): ?><div class="alert alert-danger"><?= $error ?></div><?php endif; ?><form method="POST"><div class="mb-3"><label class="form-label">姓名</label><input type="text" name="name" class="form-control" value="<?= htmlspecialchars($student['name']) ?>" required></div><div class="mb-3"><label class="form-label">邮箱</label><input type="email" name="email" class="form-control" value="<?= htmlspecialchars($student['email']) ?>" required></div><div class="mb-3"><label class="form-label">年龄</label><input type="number" name="age" class="form-control" value="<?= htmlspecialchars($student['age']) ?>" required></div><button type="submit" class="btn btn-primary">更新</button></form>
</div>
</body>
</html>

5. 删除学生 (delete.php)
<?php
include 'config.php';if (isset($_GET['id'])) {$id = $_GET['id'];$stmt = $mysqli->prepare("DELETE FROM students WHERE id = ?");$stmt->bind_param('i', $id);if ($stmt->execute()) {header('Location: index.php'); // 删除成功跳转} else {die("删除失败: " . $stmt->error);}
}
?>

安全措施

  1. SQL注入防护
    • 所有用户输入通过 prepare + bind_param 处理。
  2. XSS防护
    • 使用 htmlspecialchars() 转义所有动态输出。
  3. 数据验证
    • 前端使用 required 属性确保必填字段。
    • 后端检查 $_SERVER['REQUEST_METHOD'] 防止直接访问。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/903988.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【文献阅读】全球干旱地区植被突变的普遍性和驱动因素

一、研究背景 全球干旱区&#xff08;drylands&#xff09;覆盖了陆地面积的40%以上&#xff0c;承载了全球约三分之一人口&#xff0c;是生态系统脆弱性较高的区域。这些地区对气候变化和人类干扰尤其敏感。近年来&#xff0c;干旱区发生了大量植被突变现象&#xff0c;即生态…

【Vue3-Bug】中路由加载页面直接显示空白

Vue3中路由加载页面直接显示空白 没有子路由 路由定义不能重复&#xff0c;请自己查看数据在main.js(或者)mina.ts入口文件中&#xff0c;需要将router的注入到vue中的执行放在&#xff0c;vue挂在元素之前 // 顺序不能变 app.use(router) app.mount(#app)在App.vue中 // 在…

影楼精修-露齿笑算法解析

注意&#xff0c;为避免侵权&#xff0c;本文图片均为AIGC生成或网络公开数据&#xff1b; 像素蛋糕-露齿笑 在介绍本文之前&#xff0c;先说一下&#xff0c;其实露齿笑特效&#xff0c;并非像素蛋糕首创&#xff0c;早在几年前&#xff0c;face app就率先推出了这个效果&am…

关于Python:7. Python数据库操作

一、sqlite3&#xff08;轻量级本地数据库&#xff09; sqlite3 是 Python 内置的模块&#xff0c;用于操作 SQLite 数据库。 SQLite 是一个轻量级、零配置的关系型数据库系统&#xff0c;整个数据库保存在一个文件中&#xff0c;适合小型项目和本地存储。 SQLite 不需要安装…

c++互斥锁,竞争状态与临界区

竞争状态与临界区 1&#xff0c;基本互斥锁2&#xff0c;try_lock3&#xff0c;互斥锁存在的坑—线程抢占不到资源4&#xff0c;超时锁5&#xff0c;递归锁&#xff08;在一个线程内可以多次lock的锁&#xff09;recursive_mutex和recursive_timed_mutex用于业务组合6&#xff…

实战项目:基于控制台与数据库的图书管理系统开发指南

一、项目概述与设计思路 1.1 为什么选择图书管理系统 图书管理系统是学习编程的经典项目&#xff0c;它涵盖了&#xff1a; 控制台交互&#xff1a;学习用户输入输出处理 数据库操作&#xff1a;掌握CRUD核心功能 业务逻辑&#xff1a;理解实际应用场景 系统架构&#xff…

人工智能——层次聚类算法

目录 摘要 18 层次聚类 18.1 本章工作任务 18.2 本章技能目标 18.3 本章简介 18.4 编程实战 18.5 本章总结 18.6 本章作业 本章已完结&#xff01;&#xff01;&#xff01; 摘要 本章实现的工作是&#xff1a;首先导入20名学生的3科成绩&#xff0c;然后根据优先聚…

Linux中安装mysql8,转载及注意事项

一、先前往官网下载mysql8 下载地址&#xff1a; https://dev.mysql.com/downloads/选择Linux 二、删除Linux中的mysql&#xff08;如果有的话&#xff09;&#xff0c;上传安装包 1、先查看mysql是否存在&#xff0c;命令如下&#xff1a; rpm -qa|grep -i mysql如果使用这…

《算法导论(第4版)》阅读笔记:p4-p5

《算法导论(第4版)》学习第 3 天&#xff0c;p4-p5 总结&#xff0c;总计 2 页。 一、技术总结 1.instance Thus, given the input sequence h31; 41; 59; 26; 41; 58i, a correct sorting algorithm returns as output the sequence h26; 31; 41; 41; 58; 59i. Such an inp…

第十四篇:系统分析师第三遍——15章

目录 一、目标二、计划三、完成情况四、意外之喜(最少2点)1.计划内的明确认知和思想的提升标志2.计划外的具体事情提升内容和标志 五、总结六、后面准备怎么做&#xff1f; 一、目标 通过参加考试&#xff0c;训练学习能力&#xff0c;而非单纯以拿证为目的。 1.在复习过程中&…

Easy云盘总结篇-登录注册

**说在前面&#xff1a;该项目是跟着B站一位大佬写的&#xff0c;不分享源码&#xff0c;支持项目付费 ** 获取图形验证码 可以看到这里有2两种图形验证码&#xff0c;分为&#xff1a; type0&#xff1a;如上图下面那个&#xff0c;是完成操作后要进行注册的验证码 type1: 如…

【前端知识】Vue3状态组件Pinia详细介绍

Vue3状态组件Pinia详细介绍 关联知识 Pinia 组件介绍、核心原理及使用方式 Pinia 组件介绍 Pinia 是 Vue.js 的官方状态管理库&#xff0c;专为 Vue 3 设计&#xff0c;提供简洁的 API 和强大的 TypeScript 支持。其核心组件包括&#xff1a; • Store&#xff1a;状态存储容器…

mysql 云服务远程linux创建数据库

1. 本地使用已创建好的用户创建数据库出现问题 提示access deniey finalshell远程创建新用户 :~# mysql -u root -pR***34 > CREATE DATABASE r***e; > CREATE USER r**ue% IDENTIFIED BY Ry****34; > GRANT ALL PRIVILEGES ON ry_vue.* TO r***e%; > FLUSH PRI…

【“星瑞” O6 评测】 — CPU llama.cpp不同优化速度对比

前言 随着大模型应用场景的不断拓展&#xff0c;arm cpu 凭借其独特优势在大模型推理领域的重要性日益凸显。它在性能、功耗、架构适配等多方面发挥关键作用&#xff0c;推动大模型在不同场景落地 1. Kleidi AI 简介 Arm Kleidi 成为解决这些挑战的理想方案&#xff0c;它能…

wireshark抓包也能被篡改?

wireshark本身并不能修改数据包&#xff0c;但是tcprewrite 可以修改数据包&#xff0c;然后通过tcpreplay 进行重放&#xff0c;这个时候wireshark抓的包&#xff0c;就是被篡改后的pcap包了。 ailx10 网络安全优秀回答者 互联网行业 安全攻防员 去咨询 步骤一&#xff1a…

使用PyTorch进行热狗图像分类模型微调

本教程将演示如何使用PyTorch框架对预训练模型进行微调&#xff0c;实现热狗与非热狗图像的分类任务。我们将从数据准备开始&#xff0c;逐步完成数据加载、可视化等关键步骤。 1. 环境配置与库导入 %matplotlib inline import os import torch from torch import nn from d2l…

内容中台与企业内容管理核心差异剖析

功能定位与架构设计差异 在企业数字化进程中&#xff0c;内容中台与企业内容管理&#xff08;ECM&#xff09;的核心差异首先体现在功能定位层面。传统ECM系统以文档存储、版本控制及权限管理为核心&#xff0c;主要服务于企业内部知识库的静态管理需求&#xff0c;例如通过Ba…

使用PyMongo连接MongoDB的基本操作

MongoDB是由C语言编写的非关系型数据库&#xff0c;是一个基于分布式文件存储的开源数据库系统&#xff0c;其内容存储形式类似JSON对象&#xff0c;它的字段值可以包含其他文档、数组及文档数组。在这一节中&#xff0c;我们就来回顾Python 3下MongoDB的存储操作。 常用命令:…

第 12 届蓝桥杯 C++ 青少组中 / 高级组省赛 2021 年真题

一、选择题 第 1 题 题目&#xff1a;下列符号中哪个在 C 中表示行注释 ( )。 A. ! B. # C. ] D. // 正确答案&#xff1a;D 答案解析&#xff1a; 在 C 中&#xff0c;//用于单行注释&#xff08;行注释&#xff09;&#xff0c;从//开始到行末的内容会被编译器忽略。选项 A…

【python】【UV】一篇文章学完新一代 Python 环境与包管理器使用指南

&#x1f40d; UV&#xff1a;新一代 Python 环境与包管理器使用指南 一、UV 是什么&#xff1f; UV 是由 Astral 团队开发的高性能 Python 环境管理器&#xff0c;旨在统一替代 pyenv、pip、venv、pip-tools、pipenv 等工具。 1.1 UV 的主要功能 &#x1f680; 极速包安装&…