PHP 面试题
1. 反转字符串
编写一个函数来反转字符串。
function reverseString($str) {
return strrev($str);
}
echo reverseString("hello"); // 输出: olleh
2. 检查回文字符串
判断一个字符串是否是回文。
function isPalindrome($str) {
$reversed = strrev($str);
return $str === $reversed;
}
echo isPalindrome("madam") ? "Yes" : "No"; // 输出: Yes
3. 计算数组的平均值
编写一个函数,计算数组的平均值。
function calculateAverage($arr) {
return array_sum($arr) / count($arr);
}
echo calculateAverage([10, 20, 30, 40]); // 输出: 25
4. 斐波那契数列
打印前 10 个斐波那契数列。
function fibonacci($n) {
$fib = [0, 1];
for ($i = 2; $i < $n; $i++) {
$fib[] = $fib[$i - 1] + $fib[$i - 2];
}
return $fib;
}
print_r(fibonacci(10));
5. 判断素数
编写一个函数检查一个数字是否是素数。
function isPrime($num) {
if ($num <= 1) return false;
if ($num == 2) return true;
for ($i = 2; $i <= sqrt($num); $i++) {
if ($num % $i == 0) return false;
}
return true;
}
echo isPrime(7) ? "Yes" : "No"; // 输出: Yes
6. 统计字符串中单词的出现次数
计算每个单词在字符串中出现的次数。
function wordCount($str) {
$words = str_word_count($str, 1);
return array_count_values($words);
}
print_r(wordCount("hello world hello PHP"));
Array
(
[hello] => 2
[world] => 1
[PHP] => 1
)
7. 排序数组
用 PHP 内置函数对数组排序。
function sortArray($arr) {
sort($arr);
return $arr;
}
print_r(sortArray([5, 2, 9, 1, 5, 6]));
Array
(
[0] => 1
[1] => 2
[2] => 5
[3] => 5
[4] => 6
[5] => 9
)
function sortArrayReverse($arr) {
rsort($arr); // 对数组进行降序排序
return $arr;
}
print_r(sortArrayReverse([5, 2, 9, 1, 5, 6]));
Array
(
[0] => 9
[1] => 6
[2] => 5
[3] => 5
[4] => 2
[5] => 1
)
8. 实现基本的登录验证
检查用户名和密码是否匹配。
function login($username, $password) {
$Username = "admin";
$Password = "1234";
return $username === $storedUsername && $password === $storedPassword;
}
echo login("admin", "1234") ? "Login successful" : "Invalid credentials";
9. 计算阶乘
编写一个函数计算一个数字的阶乘。
function factorial($n) {
return $n == 0 ? 1 : $n * factorial($n - 1);
}
echo factorial(5); // 输出: 120
10. 检查数组中是否有重复项
编写一个函数检查数组中是否有重复的值。
function hasDuplicates($arr) {
return count($arr) !== count(array_unique($arr));
}
echo hasDuplicates([1, 2, 3, 4, 4]) ? "Yes" : "No"; // 输出: Yes
=========
1. PHP 连接 MySQL 数据库
写一个简单的 PHP 脚本连接到 MySQL 数据库并检查连接是否成功。
$servername = "localhost";
$username = "root";
$password = "";
$database = "test_db";
$conn = new mysqli($servername, $username, $password, $database);
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
} else {
echo "连接成功!";
}
$conn->close();
2. 插入数据到 MySQL 表中
编写一个函数,用于向 MySQL 表中插入数据。
function insertData($name, $email) {
$conn = new mysqli("localhost", "root", "", "test_db");
if ($conn->connect_error) die("连接失败: " . $conn->connect_error);
$sql = "INSERT INTO users (name, email) VALUES ('$name', '$email')";
if ($conn->query($sql) === TRUE) {
echo "数据插入成功";
} else {
echo "错误: " . $conn->error;
}
$conn->close();
}
insertData("John Doe", "john@example.com");
function insertData($name, $email) {
// 创建连接
$conn = new mysqli("localhost", "root", "", "test_db");
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
// 使用准备语句插入数据
$stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
// 绑定参数
$stmt->bind_param("ss", $name, $email); // "ss" 表示两个字符串类型参数
// 执行语句
if ($stmt->execute()) {
echo "数据插入成功";
} else {
echo "错误: " . $stmt->error;
}
// 关闭连接和语句
$stmt->close();
$conn->close();
}
// 调用函数插入数据
insertData("John Doe", "john@example.com");
3. 从 MySQL 数据库中获取数据
编写一个脚本从数据库中读取数据并显示。
$conn = new mysqli("localhost", "root", "", "test_db");
if ($conn->connect_error) die("连接失败: " . $conn->connect_error);
$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"] . " - Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
}
} else {
echo "没有数据";
}
$conn->close();
function getUserData($name, $email) {
$conn = new mysqli("localhost", "root", "", "test_db");
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
// 使用准备语句避免 SQL 注入
$stmt = $conn->prepare("SELECT id, name, email FROM users WHERE name = ? AND email = ?");
if ($stmt === false) {
die("准备语句创建失败: " . $conn->error);
}
// 绑定参数
$stmt->bind_param("ss", $name, $email); // 绑定两个字符串类型的参数
// 执行查询
$stmt->execute();
// 获取结果
$result = $stmt->get_result();
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "ID: " . $row["id"] . " - Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
}
} else {
echo "没有数据";
}
// 关闭连接和语句
$stmt->close();
$conn->close();
}
// 假设用户输入的查询条件
$name = "John Doe";
$email = "john@example.com";
getUserData($name, $email);
每次调用 fetch_assoc()
,会向下移动到结果集的下一行。
常与 while
循环配合使用,用于遍历查询结果。
示例:
$sql = "SELECT * FROM users";
$result = $conn->query($sql);
echo "共有 " . $result->num_rows . " 条记录";
如果 users
表中有 5 条记录,输出:
共有 5 条记录
4. 更新数据库中的数据
写一个函数更新用户的 email 信息。
function updateEmail($id, $newEmail) {
$conn = new mysqli("localhost", "root", "", "test_db");
if ($conn->connect_error) die("连接失败: " . $conn->connect_error);
$sql = "UPDATE users SET email='$newEmail' WHERE id=$id";
if ($conn->query($sql) === TRUE) {
echo "数据更新成功";
} else {
echo "更新失败: " . $conn->error;
}
$conn->close();
}
updateEmail(1, "newemail@example.com");
5. 删除数据库中的数据
编写一个函数删除指定的用户。
function deleteUser($id) {
$conn = new mysqli("localhost", "root", "", "test_db");
if ($conn->connect_error) die("连接失败: " . $conn->connect_error);
$sql = "DELETE FROM users WHERE id=$id";
if ($conn->query($sql) === TRUE) {
echo "用户删除成功";
} else {
echo "删除失败: " . $conn->error;
}
$conn->close();
}
deleteUser(2);
6. 预处理语句防止 SQL 注入
用 prepare
和 bind_param
防止 SQL 注入。
function safeInsert($name, $email) {
$conn = new mysqli("localhost", "root", "", "test_db");
if ($conn->connect_error) die("连接失败: " . $conn->connect_error);
$stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email);
if ($stmt->execute()) {
echo "安全插入成功";
} else {
echo "插入失败: " . $stmt->error;
}
$stmt->close();
$conn->close();
}
safeInsert("Alice", "alice@example.com");
准备语句 (prepare()
):
- 使用 SQL 语句模板,创建一个预处理语句对象。
- 这个过程只是将 SQL 语句发送到 MySQL 服务器,并进行语法分析。
绑定参数 (bind_param()
):
- 使用
bind_param()
方法将实际的参数(如变量)绑定到 SQL 语句中的占位符(?
)上。 - 在执行之前,必须绑定所有参数。
通过 execute()
执行准备好的 SQL 语句,并将绑定的参数传递给 SQL 语句。
常用的类型字符
字符 | 数据类型 | 示例 |
---|---|---|
i | 整数(int ) | 42 , -1 |
d | 双精度浮点数 | 3.14 , 2.718 |
s | 字符串(string ) | "hello" , "abc" |
b | 二进制数据 | binary data |
示例:根据不同类型绑定参数
假设我们有一个表 users
,包含以下字段:
id
(整数)name
(字符串)salary
(浮点数)
我们可以这样绑定参数:
$stmt = $conn->prepare("INSERT INTO users (id, name, salary) VALUES (?, ?, ?)");
$stmt->bind_param("isd", $id, $name, $salary);
// 参数赋值
$id = 1; // 整数 -> "i"
$name = "Alice"; // 字符串 -> "s"
$salary = 5000.50;// 浮点数 -> "d"
// 执行插入
$stmt->execute();
7. 分页查询
实现分页查询从数据库中获取数据。
function getPaginatedData($page, $itemsPerPage) {
$conn = new mysqli("localhost", "root", "", "test_db");
if ($conn->connect_error) die("连接失败: " . $conn->connect_error);
$offset = ($page - 1) * $itemsPerPage;
$sql = "SELECT * FROM users LIMIT $itemsPerPage OFFSET $offset";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "ID: " . $row["id"] . " - Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
}
} else {
echo "没有更多数据";
}
$conn->close();
}
getPaginatedData(1, 5);
8. 获取总记录数
查询表中总共有多少条记录。
function getTotalCount() {
$conn = new mysqli("localhost", "root", "", "test_db");
if ($conn->connect_error) die("连接失败: " . $conn->connect_error);
$sql = "SELECT COUNT(*) AS total FROM users";
$result = $conn->query($sql);
$row = $result->fetch_assoc();
echo "总记录数: " . $row['total'];
$conn->close();
}
getTotalCount();
9. 事务处理
实现一个简单的事务操作。
$conn = new mysqli("localhost", "root", "", "test_db");
if ($conn->connect_error) die("连接失败: " . $conn->connect_error);
$conn->autocommit(FALSE);
try {
$conn->query("UPDATE users SET email='test1@example.com' WHERE id=1");
$conn->query("UPDATE users SET email='test2@example.com' WHERE id=2");
$conn->commit();
echo "事务完成";
} catch (Exception $e) {
$conn->rollback();
echo "事务回滚: " . $e->getMessage();
}
$conn->close();
autocommit(FALSE)
是 PHP 的 MySQLi 类提供的方法,用来关闭数据库连接的自动提交功能。默认情况下,每个 SQL 语句在执行后会立即提交(即自动提交)。关闭自动提交后,可以手动控制事务的提交和回滚。
commit()
是 MySQLi 中用于 提交事务 的方法。它的作用是 保存 自 begin
或 start
开始的所有数据库操作(如 UPDATE
、INSERT
等)。
为什么需要 commit()
?
当你在 MySQL 中使用事务时,你并不直接提交每一条 SQL 语句,而是先将它们保留在一个临时状态。只有当你调用 commit()
时,数据库才会正式保存这些更改。如果在 commit()
之前出现错误,你可以通过 rollback()
来撤销(回滚)所有更改。
commit()
提交当前事务,将所有更改永久保存。
rollback()
用于回滚事务,将更改撤销。
query()
只是执行单个 SQL 语句,并不会管理事务的提交和回滚。
使用事务可以确保多个 SQL 操作要么全部成功,要么全部失败,从而保证数据一致性。
10. **错误日志记录 ** x
编写一个简单的错误日志记录系统。
function logError($message) {
$file = 'error_log.txt';
file_put_contents($file, date("Y-m-d H:i:s") . " - $message\n", FILE_APPEND);
}
try {
$conn = new mysqli("localhost", "root", "", "test_db");
if ($conn->connect_error) throw new Exception("连接失败: " . $conn->connect_error);
// 其他数据库操作...
} catch (Exception $e) {
logError($e->getMessage());
echo "错误已记录到日志";
}
如何使用 query
query
是执行 SQL 查询的最基础方法,可以用于执行 增删改查(CRUD)操作。
1. SELECT 查询
$sql = "SELECT * FROM users";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// 遍历查询结果
while ($row = $result->fetch_assoc()) {
echo "用户ID: " . $row["id"] . " - 名字: " . $row["name"] . "<br>";
}
} else {
echo "没有找到记录";
}
-
解释
:
- 使用
query()
执行SELECT
查询。 - 返回的
$result
是一个mysqli_result
对象。 - 使用
$result->num_rows
检查是否有结果。 - 使用
$result->fetch_assoc()
获取每行数据作为关联数组。
- 使用
2. INSERT 查询
$sql = "INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com')";
if ($conn->query($sql) === true) {
echo "新记录插入成功";
} else {
echo "插入失败: " . $conn->error;
}
-
解释
:
- 执行
INSERT
查询。 - 如果成功,
query()
返回true
。 - 如果失败,返回
false
,可以通过$conn->error
获取详细错误信息。
- 执行
3. UPDATE 查询
$sql = "UPDATE users SET name = 'Bob' WHERE id = 1";
if ($conn->query($sql) === true) {
echo "记录更新成功";
} else {
echo "更新失败: " . $conn->error;
}
4. DELETE 查询
$sql = "DELETE FROM users WHERE id = 1";
if ($conn->query($sql) === true) {
echo "记录删除成功";
} else {
echo "删除失败: " . $conn->error;
}
常见问题
-
SQL 注入风险: 如果直接在
$sql
中拼接用户输入,可能会导致 SQL 注入攻击。建议使用prepared statements
(预处理语句)代替。不安全示例:
$username = $_POST['username'];
$sql = "SELECT * FROM users WHERE name = '$username'";安全示例(使用 prepared statements):
$stmt = $conn->prepare("SELECT * FROM users WHERE name = ?");
$stmt->bind_param("s", $_POST['username']);
$stmt->execute();完整代码:
1. HTML 表单(
index.html
或form.html
)<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>查询用户</title>
</head>
<body>
<h2>查询用户信息</h2>
<form action="search_user.php" method="POST">
<label for="username">用户名:</label>
<input type="text" name="username" id="username" required>
<input type="submit" value="查询">
</form>
</body>
</html>2. PHP 代码(
search_user.php
)<?php
function getUserByUsername($username) {
// 创建数据库连接
$conn = new mysqli("localhost", "root", "", "test_db");
// 检查连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
// 使用预处理语句避免 SQL 注入
$stmt = $conn->prepare("SELECT * FROM users WHERE name = ?");
$stmt->bind_param("s", $username); // "s" 表示参数是字符串类型
// 执行查询
$stmt->execute();
// 获取查询结果
$result = $stmt->get_result();
// 检查是否有结果
if ($result->num_rows > 0) {
// 输出查询结果
while ($row = $result->fetch_assoc()) {
echo "ID: " . $row["id"] . " - Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
}
} else {
echo "没有找到用户。";
}
// 关闭连接
$stmt->close();
$conn->close();
}
// 检查表单是否通过 POST 提交数据
if (isset($_POST['username'])) {
$username = $_POST['username']; // 获取用户名
getUserByUsername($username); // 调用函数查询并显示结果
}
?>1. 创建表(Create Table)
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100)
); -
错误处理: 始终检查查询是否成功:
if ($conn->query($sql) === false) {
echo "错误: " . $conn->error;
} -
查询结果为空:
SELECT
查询可能返回空结果集,需通过$result->num_rows
检查。
=================
1. 检查数组是否是关联数组
编写一个函数,检查一个数组是关联数组还是索引数组。
function isAssociativeArray($array) {
return array_keys($array) !== range(0, count($array) - 1);
}
echo isAssociativeArray(["a" => 1, "b" => 2]) ? "关联数组" : "索引数组";
2. 比较两个数组的差异
用 PHP 函数找出两个数组之间的差异。
array_diff()
函数用来比较两个数组,并返回第一个数组中存在,而第二个数组中没有的元素
function getArrayDifference($array1, $array2) {
return array_diff($array1, $array2);
}
print_r(getArrayDifference([1, 2, 3], [2, 3, 4])); // 输出: [1]
3. 计算数组的交集
获取两个数组的交集。
function getArrayIntersection($array1, $array2) {
return array_intersect($array1, $array2);
}
print_r(getArrayIntersection([1, 2, 3], [2, 3, 4])); // 输出: [2, 3]
4. 生成随机字符串
生成一个长度为 N 的随机字符串。
function generateRandomString($length = 8) {
return substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, $length);
}
echo generateRandomString(10);
5. 实现文件上传功能
如何在 PHP 中处理文件上传?
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$targetDir = "uploads/";
$targetFile = $targetDir . basename($_FILES["fileToUpload"]["name"]);
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $targetFile)) {
echo "文件上传成功: " . $targetFile;
} else {
echo "文件上传失败";
}
}
HTML 表单:
<form action="" method="POST" enctype="multipart/form-data">
<input type="file" name="fileToUpload">
<input type="submit" value="上传">
</form>
6. PHP 的 Cookie 和 Session 区别
- Cookie: 存储在客户端 (浏览器),用于小量数据的持久存储,随着每个请求发送到服务器。
- Session: 存储在服务器,用于用户的临时数据存储,只在用户活动期间有效。
简单代码示例:
// 设置 Cookie
setcookie("user", "John", time() + (86400 * 30), "/");
// 设置 Session
session_start();
$_SESSION["user"] = "John";
session_start();
if (isset($_SESSION["user"])) {
echo "用户是:" . $_SESSION["user"]; // 输出:用户是:John
echo "角色是:" . $_SESSION["role"]; // 输出:角色是:admin
} else {
echo "Session 数据不存在。";
}
session_start();
unset($_SESSION["user"]); // 删除 "user" 键
session_destroy(); // 销毁 Session 数据
7. 计算两个日期的差
计算两个日期之间的天数。
function dateDifference($date1, $date2) {
$datetime1 = new DateTime($date1);
$datetime2 = new DateTime($date2);
$interval = $datetime1->diff($datetime2);
return $interval->days;
}
echo dateDifference("2024-12-20", "2025-01-01"); // 输出: 12
8. 动态调用函数
使用变量函数动态调用。
function sayHello() {
return "Hello, World!";
}
$functionName = "sayHello";
echo $functionName(); // 输出: Hello, World!
9. 通过接口实现多态
用 PHP 接口实现多态特性。
interface Animal {
public function sound();
}
class Dog implements Animal {
public function sound() {
return "Bark";
}
}
class Cat implements Animal {
public function sound() {
return "Meow";
}
}
function makeSound(Animal $animal) {
echo $animal->sound();
}
makeSound(new Dog()); // 输出: Bark
makeSound(new Cat()); // 输出: Meow
10. 计算数组中每个值出现的次数
统计数组中每个值出现的次数。
function countValues($array) {
return array_count_values($array);
}
print_r(countValues(["apple", "banana", "apple", "orange", "banana"]));
11. 过滤数组中的空值
使用 array_filter
去除数组中的空值。
function removeEmptyValues($array) {
return array_filter($array);
}
print_r(removeEmptyValues(["apple", "", null, "banana", 0, false, "orange"]));
12. **PHP 自动加载类 ** x
通过 spl_autoload_register
实现自动加载。
spl_autoload_register(function ($class) {
include $class . ".php";
});
// 假设有文件 Dog.php,内含 Dog 类
$dog = new Dog();
13. PHP 中的异常处理
使用 try-catch 捕获异常。
try {
throw new Exception("发生错误");
} catch (Exception $e) {
echo "捕获异常: " . $e->getMessage();
}
14. 检测字符串是否包含某个子字符串
检查字符串中是否存在子字符串。
function contains($haystack, $needle) {
return strpos($haystack, $needle) !== false;
}
echo contains("hello world", "world") ? "包含" : "不包含";