PHP 教程
PHP(Hypertext Preprocessor,超文本预处理器)是一种流行的服务端脚本语言,特别适合 Web 开发。PHP 代码在服务器上执行,生成 HTML 返回浏览器。全球大量网站(包括 WordPress)使用 PHP 构建。
PHP 的特点
| 特点 | 说明 |
|---|---|
| 易上手 | 语法类似 C 语言,学习门槛低 |
| 部署简单 | 与 Apache/Nginx + MySQL 天然配合 |
| 生态丰富 | WordPress、Laravel、ThinkPHP 等 |
| 跨平台 | Windows/Linux/macOS 均可运行 |
<?php
echo "Hello, World!";
?>.php 结尾,代码写在 <?php ... ?> 标签中。PHP 简介
PHP 由 Rasmus Lerdorf 于 1994 年创建,最初是个人主页工具(Personal Home Page),后演变为 "PHP: Hypertext Preprocessor"。如今 PHP 8.x 是主流版本,性能与语法均有大幅提升。
PHP 能做什么
| 应用 | 说明 |
|---|---|
| 动态网站 | 电商、博客、门户、论坛 |
| API 服务 | RESTful 接口、微服务 |
| 命令行工具 | CLI 脚本、定时任务 |
| 桌面应用 | PHP-GTK 等扩展 |
运行原理
浏览器请求 .php 文件 → Web 服务器(如 Nginx)调用 PHP 解释器执行 → 执行结果(通常是 HTML)返回浏览器。PHP 代码在服务器端执行,客户端看不到源码。
PHP 安装
在 Windows/Linux/macOS 上安装 PHP 有多种方式:
Windows(XAMPP 一键包,推荐新手)
# 下载 XAMPP 并安装
# 内含 Apache + PHP + MySQL,双击启动即可
# 网站根目录: C:/xampp/htdocs/Linux(apt/yum)
# Ubuntu/Debian
sudo apt update
sudo apt install -y php php-mysql apache2
# CentOS/RHEL
sudo yum install -y php php-mysqlnd httpd
# 验证
php -vmacOS(Homebrew)
brew install php
php -vPHP 语法
PHP 基础语法:脚本以 <?php 开始,以 ?> 结束(文件末尾可省略),语句以分号结尾:
<?php
// 单行注释
# 也是单行注释
/* 多行
注释 */
// 输出
echo "Hello PHP<br>";
print "使用 print 输出";
// 变量以 $ 开头
$name = "小明";
echo $name;
?>| 语法要点 | 说明 |
|---|---|
| 大小写 | 变量名区分大小写,函数名不区分 |
| 分号 | 每条语句以 ; 结尾 |
| 注释 | //、#、/* */ |
| 标签 | 结束 |
?>,避免输出多余空白字符。PHP 变量
PHP 变量以 $ 开头,无需声明类型(弱类型):
<?php
$name = "张三"; // 字符串
$age = 25; // 整数
$price = 99.9; // 浮点数
$isVip = true; // 布尔
$tags = ["php", "web"]; // 数组
// 变量作用域
function test() {
global $age; // 使用全局变量
static $count = 0; // 静态变量(函数调用间保持)
$count++;
echo $count;
}
test(); // 1
test(); // 2
// 变量引用
$b = &$age; // $b 引用 $age
$b = 30; // $age 也变为 30
?>PHP echo/print
echo 与 print 是最常用的输出语句:
| 区别 | echo | |
|---|---|---|
| 返回值 | 无 | 返回 1(可用作表达式) |
| 多参数 | 支持 echo $a, $b | 只支持一个参数 |
| 速度 | 稍快 | 稍慢 |
<?php
// echo 输出多个值
echo "Hello", " ", "World", "<br>";
// 输出变量
$name = "李四";
echo "你好,$name<br>"; // 双引号内变量会解析
echo '你好,$name<br>'; // 单引号内不解析
// 字符串拼接用 .
echo "Hello" . " " . "World" . "<br>";
// print 作为表达式
$result = print "测试";
echo "<br>返回值: " . $result; // 1
?>PHP EOF(heredoc)
EOF(heredoc)语法用于输出多行文本,尤其适合 HTML 混编:
<?php
$name = "王五";
// Heredoc:<<<EOF ... EOF 之间原样输出,变量会解析
$html = <<<EOF
<div class="card">
<h3>欢迎 $name</h3>
<p>这是一段多行文本</p>
</div>
EOF;
echo $html;
// Nowdoc:<<<'EOF' ... EOF 不解析变量(单引号)
$sql = <<<'SQL'
SELECT * FROM users WHERE name = '$name';
SQL;
echo $sql;
?>PHP 数据类型
PHP 支持的数据类型:
| 类型 | 说明 | 示例 |
|---|---|---|
| string | 字符串 | "hello" |
| int | 整数 | 42 |
| float | 浮点数 | 3.14 |
| bool | 布尔 | true/false |
| array | 数组 | [1,2,3] |
| object | 对象 | new Class() |
| null | 空值 | null |
| resource | 资源 | 文件句柄 |
<?php
// 获取变量类型
$v = "hello";
var_dump($v); // string(5) "hello"
$n = 42;
var_dump($n); // int(42)
$arr = [1, 2, 3];
var_dump($arr);
// 类型判断
echo is_string($v) ? "是字符串" : "不是"; // 是字符串
echo is_numeric("123") ? "是数字" : "否"; // 是数字
?>var_dump() 是调试神器,能同时显示类型与值。PHP 类型比较
PHP 弱类型导致类型比较需要格外小心:
<?php
// 松散比较 == :只比较值,会做类型转换
var_dump(0 == "abc"); // true(PHP7 后 false)
var_dump(0 == false); // true
var_dump("10" == 10); // true
// 严格比较 === :值和类型都相同才 true
var_dump("10" === 10); // false
var_dump(0 === false); // false
// 建议:始终用 === / !==
$input = "100";
if ($input === 100) {
echo "严格相等";
} else {
echo "类型不同";
}
?>== 比较 0、""、null、false 时很容易踩坑,安全开发建议一律使用 ===。PHP 常量
常量用 define() 或 const 定义,定义后不可修改:
<?php
// 方式一:define(函数方式,可在任意位置)
define("SITE_NAME", "我的网站");
define("DB_HOST", "localhost", true); // 第三个参数 true = 不区分大小写
// 方式二:const(编译期,类中也可用)
const VERSION = "1.0.0";
echo SITE_NAME; // 我的网站
echo db_host; // localhost(不区分大小写)
// 预定义常量
echo PHP_VERSION; // PHP 版本
echo PHP_OS; // 操作系统
echo __LINE__; // 当前行号(魔术常量)
echo __FILE__; // 当前文件路径
echo __DIR__; // 当前目录
?>PHP 字符串
PHP 字符串操作非常丰富:
<?php
$str = "Hello, World!";
// 长度
echo strlen($str); // 13(中文字符用 mb_strlen)
// 查找
echo strpos($str, "World"); // 7(找不到返回 false)
// 截取
echo substr($str, 7, 5); // World
echo substr($str, -6); // World!
// 替换
echo str_replace("World", "PHP", $str); // Hello, PHP!
// 大小写
echo strtoupper($str); // HELLO, WORLD!
echo strtolower($str); // hello, world!
// 分割与拼接
$arr = explode(",", $str); // ["Hello", " World!"]
echo implode("-", $arr); // Hello- World!
// 去空格
echo trim(" hi "); // hi
// 中文处理(mb_ 前缀)
echo mb_strlen("你好世界"); // 4
?>mb_ 前缀版本(如 mb_strlen、mb_substr),避免乱码。PHP 运算符
PHP 运算符一览:
| 类别 | 运算符 |
|---|---|
| 算术 | + - * / % **(幂) |
| 赋值 | = += -= *= /= .=(字符串拼接赋值) |
| 比较 | == === != !== > < >= <= <=> |
| 逻辑 | && || ! and or xor |
| 位运算 | & | ^ ~ << >> |
| 递增递减 | ++ -- |
| 三元 | ? : 和 ?:(空合并)和 ?? |
<?php
// 算术与赋值
$a = 10;
$a += 5; // 15
$s = "Hello";
$s .= " World"; // Hello World
// 比较
var_dump(10 <=> 20); // -1(太空船运算符)
// 空合并运算符:左边存在且非 null 则取左,否则右
$name = $user['name'] ?? "匿名";
echo $name; // 匿名
// 三元
$age = 18;
echo $age >= 18 ? "成年" : "未成年";
?>?? 空合并运算符是 PHP 7+ 的福音,可优雅替代 isset() 判断。PHP If...Else
if...else 条件控制:
<?php
$score = 85;
if ($score >= 90) {
echo "优秀";
} elseif ($score >= 60) {
echo "及格";
} else {
echo "不及格";
}
// 简写(模板中常用)
$status = ($score >= 60) ? "通过" : "未通过";
// 替代语法:冒号 + endif(适合嵌入 HTML)
if ($score >= 60): ?>
<p>恭喜通过!</p>
<?php else: ?>
<p>继续努力</p>
<?php endif; ?>
?>if: ... endif; 替代语法可读性更好。PHP Switch
switch 用于多分支判断:
<?php
$day = "Monday";
switch ($day) {
case "Saturday":
case "Sunday":
echo "周末";
break;
case "Friday":
echo "周五";
break;
default:
echo "工作日";
}
// PHP 8+ 可以用 match(更现代)
$result = match ($day) {
"Saturday", "Sunday" => "周末",
"Friday" => "周五",
default => "工作日",
};
echo $result;
?>match 表达式比 switch 更简洁,且无需 break,推荐使用。PHP 数组
数组是 PHP 最核心的数据结构(实际是有序映射):
<?php
// 索引数组
$colors = ["red", "green", "blue"];
echo $colors[0]; // red
$colors[] = "yellow"; // 追加
// 关联数组
$user = [
"name" => "张三",
"age" => 25,
"city" => "北京"
];
echo $user["name"]; // 张三
// 遍历
foreach ($colors as $c) {
echo "$c ";
}
foreach ($user as $key => $value) {
echo "$key: $value<br>";
}
// 常用函数
count($colors); // 元素个数
array_key_exists("age", $user); // true
in_array("red", $colors); // true
array_push($colors, "black"); // 末尾追加
array_pop($colors); // 弹出末尾
array_merge($colors, ["pink"]); // 合并
array_unique($colors); // 去重
?>PHP 数组排序
数组排序函数族:
<?php
$nums = [3, 1, 4, 1, 5, 9];
sort($nums); // 升序(值排序,重建索引)
rsort($nums); // 降序
$fruits = ["apple" => 3, "banana" => 1, "cherry" => 2];
asort($fruits); // 按值升序,保持键关联
ksort($fruits); // 按键升序
arsort($fruits); // 按值降序
krsort($fruits); // 按键降序
// 自定义排序
usort($nums, function($a, $b) {
return $b - $a; // 降序
});
// 字符串排序(自然排序)
$files = ["file10.txt", "file2.txt", "file1.txt"];
natsort($files);
print_r($files);
?>sort() 等函数直接修改原数组并返回布尔值,不是返回新数组。PHP 超级全局变量
超级全局变量是 PHP 内置的全局数组,贯穿整个脚本:
| 变量 | 说明 |
|---|---|
| $GLOBALS | 所有全局变量 |
| $_SERVER | 服务器与请求信息 |
| $_GET | URL 查询参数 |
| $_POST | 表单 POST 数据 |
| $_REQUEST | GET + POST + Cookie |
| $_SESSION | 会话数据 |
| $_COOKIE | Cookie 数据 |
| $_FILES | 文件上传信息 |
| $_ENV | 环境变量 |
<?php
echo $_SERVER['REMOTE_ADDR']; // 客户端 IP
echo $_SERVER['REQUEST_URI']; // 请求路径
echo $_SERVER['HTTP_USER_AGENT']; // 浏览器 UA
echo $_SERVER['REQUEST_METHOD']; // GET / POST
?>PHP While 循环
while 循环:
<?php
// while:先判断再执行
$i = 1;
while ($i <= 5) {
echo $i . " ";
$i++;
}
// 输出: 1 2 3 4 5
// do...while:先执行再判断(至少执行一次)
$j = 1;
do {
echo $j . " ";
$j++;
} while ($j <= 3);
// 输出: 1 2 3
// 读取文件内容
$file = fopen("data.txt", "r");
while (!feof($file)) {
echo fgets($file);
}
fclose($file);
?>PHP For 循环
for / foreach 循环:
<?php
// for:已知次数
for ($i = 0; $i < 5; $i++) {
echo $i . " ";
}
// 输出: 0 1 2 3 4
// foreach:遍历数组(最常用)
$fruits = ["苹果", "香蕉", "橙子"];
foreach ($fruits as $fruit) {
echo $fruit . " ";
}
// 带键遍历
$user = ["name" => "张三", "age" => 25];
foreach ($user as $key => $value) {
echo "$key=$value ";
}
// break / continue
for ($i = 1; $i <= 10; $i++) {
if ($i % 2 == 0) continue; // 跳过偶数
if ($i > 7) break; // 大于 7 停止
echo $i . " "; // 1 3 5 7
}
?>foreach,比 for+索引更简洁安全。PHP 函数
函数封装可复用逻辑:
<?php
// 定义函数
function greet($name) {
return "你好,$name";
}
echo greet("小明"); // 你好,小明
// 默认参数
function area($w, $h = 10) {
return $w * $h;
}
echo area(5); // 50
echo area(5, 20); // 100
// 类型声明(PHP 7+)
function add(int $a, int $b): int {
return $a + $b;
}
// 可变参数
function sum(...$nums) {
return array_sum($nums);
}
echo sum(1, 2, 3, 4); // 10
// 匿名函数(闭包)
$double = function($x) { return $x * 2; };
echo $double(5); // 10
// 箭头函数(PHP 7.4+)
$triple = fn($x) => $x * 3;
echo $triple(3); // 9
?>PHP 魔术常量
魔术常量随代码位置变化而变化:
| 常量 | 含义 |
|---|---|
| __LINE__ | 当前行号 |
| __FILE__ | 当前文件完整路径 |
| __DIR__ | 当前文件所在目录 |
| __FUNCTION__ | 当前函数名 |
| __CLASS__ | 当前类名 |
| __METHOD__ | 当前方法名(含类名) |
| __NAMESPACE__ | 当前命名空间 |
| __TRAIT__ | 当前 Trait 名 |
<?php
echo __LINE__; // 当前行
echo __FILE__; // /path/to/file.php
echo __DIR__; // /path/to
function test() {
echo __FUNCTION__; // test
}
test();
// 常见用途:定位文件路径
require_once __DIR__ . '/config.php';
?>__DIR__ . "/xxx.php" 是 include 文件时最稳妥的路径写法。PHP 表单
PHP 表单处理:用 $_GET 或 $_POST 接收用户输入:
<?php
// 判断请求方式
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$name = $_POST["name"];
echo "你好,$name";
}
?>
<form method="post" action="">
<input type="text" name="name" required>
<input type="submit" value="提交">
</form>| 方法 | 场景 | 特点 |
|---|---|---|
| GET | 搜索、跳转参数 | 数据在 URL 中,可分享、可缓存 |
| POST | 登录、提交表单 | 数据在请求体,安全、可传大内容 |
PHP 表单验证
表单验证是安全与体验的关键:
<?php
$errors = [];
$name = $email = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 必填校验
if (empty($_POST["name"])) {
$errors[] = "姓名必填";
} else {
$name = htmlspecialchars($_POST["name"]); // 防 XSS
}
// 邮箱格式校验
if (empty($_POST["email"])) {
$errors[] = "邮箱必填";
} elseif (!filter_var($_POST["email"], FILTER_VALIDATE_EMAIL)) {
$errors[] = "邮箱格式不正确";
} else {
$email = $_POST["email"];
}
}
if (!empty($errors)) {
foreach ($errors as $e) echo "<p style='color:red'>$e</p>";
} else {
echo "验证通过!";
}
?>htmlspecialchars() 是防止 XSS 攻击的基本手段,输出用户输入前必用。PHP 表单 - 必需字段
表单必需字段的完整校验流程:
<?php
$required = ["name", "email", "phone"];
$errors = [];
foreach ($required as $field) {
if (empty($_POST[$field])) {
$errors[$field] = "请填写 $field";
}
}
// 逐字段提示
if (!empty($errors)) {
foreach ($errors as $field => $msg) {
echo "<p style='color:red'>$msg</p>";
}
} else {
// 处理合法数据
echo "所有字段已填写,处理业务逻辑...";
}
?>
<form method="post">
姓名: <input type="text" name="name"><br>
邮箱: <input type="text" name="email"><br>
电话: <input type="text" name="phone"><br>
<input type="submit">
</form>required 属性只是体验优化,服务端校验才是安全底线。PHP 表单 - 验证邮件和URL
验证邮件与 URL:
<?php
// 验证邮箱
$email = "test@example.com";
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "邮箱合法";
} else {
echo "邮箱不合法";
}
// 验证 URL
$url = "https://www.example.com/page?id=1";
if (filter_var($url, FILTER_VALIDATE_URL)) {
echo "URL 合法";
}
// 正则验证(更严格)
if (preg_match("/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/", $email)) {
echo "邮箱格式正确";
}
// 手机号(中国大陆)
$phone = "13800138000";
if (preg_match("/^1[3-9]\d{9}$/", $phone)) {
echo "手机号合法";
}
?>filter_var 内置了常见格式校验,优先使用;复杂的用 preg_match 正则。PHP 完整表单实例
一个完整表单实例(含验证与回显):
<?php
$name = $email = "";
$nameErr = $emailErr = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 姓名
if (empty($_POST["name"])) {
$nameErr = "姓名必填";
} else {
$name = htmlspecialchars($_POST["name"]);
if (!preg_match("/^[a-zA-Z\x{4e00}-\x{9fa5} ]+$/u", $name)) {
$nameErr = "姓名只能包含字母和中文";
}
}
// 邮箱
if (empty($_POST["email"])) {
$emailErr = "邮箱必填";
} else {
$email = $_POST["email"];
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = "邮箱格式错误";
}
}
// 全部通过才处理
if (empty($nameErr) && empty($emailErr)) {
echo "提交成功:$name ($email)";
}
}
?>
<form method="post">
<p>姓名: <input type="text" name="name" value="<?php echo $name; ?>">
<span style="color:red"><?php echo $nameErr; ?></span></p>
<p>邮箱: <input type="text" name="email" value="<?php echo $email; ?>">
<span style="color:red"><?php echo $emailErr; ?></span></p>
<input type="submit">
</form>PHP $_GET 变量
$_GET 获取 URL 查询参数:
<?php
// URL: page.php?id=10&category=books
echo $_GET["id"]; // 10
echo $_GET["category"]; // books
// 安全获取(带默认值)
$id = isset($_GET["id"]) ? (int)$_GET["id"] : 0;
echo $id;
// PHP 7+ 简写
$id = (int)($_GET["id"] ?? 0);
// 遍历所有 GET 参数
foreach ($_GET as $key => $value) {
echo "$key = $value<br>";
}
?>
<a href="list.php?page=2&size=20">下一页</a>(int) 可防注入;敏感数据不要放 URL。PHP $_POST 变量
$_POST 获取表单 POST 数据:
<?php
// 表单 method="post" 提交的数据
$username = $_POST["username"] ?? "";
$password = $_POST["password"] ?? "";
// 简单登录验证(演示,生产用 password_hash)
if ($username === "admin" && $password === "123456") {
echo "登录成功";
// header("Location: dashboard.php"); 跳转
} else {
echo "账号或密码错误";
}
?>
<form method="post">
用户名: <input type="text" name="username"><br>
密码: <input type="password" name="password"><br>
<input type="submit" value="登录">
</form>password_hash() 加密存储、password_verify() 校验。PHP 多维数组
多维数组:数组的元素还是数组:
<?php
// 二维数组(表格数据)
$students = [
["name" => "张三", "score" => 90],
["name" => "李四", "score" => 75],
["name" => "王五", "score" => 88],
];
// 访问
echo $students[0]["name"]; // 张三
echo $students[1]["score"]; // 75
// 遍历
foreach ($students as $i => $s) {
echo ($i+1) . ". " . $s["name"] . " - " . $s["score"] . "<br>";
}
// 多维索引数组(矩阵)
$matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
echo $matrix[1][2]; // 6
?>PHP 日期
日期与时间:
<?php
// 当前时间戳(秒)
echo time();
// 格式化日期
echo date("Y-m-d H:i:s"); // 2026-08-12 10:30:00
echo date("Y年m月d日"); // 2026年08月12日
echo date("l"); // 星期几(英文)
// 指定日期
echo date("Y-m-d", strtotime("2026-01-01"));
echo date("Y-m-d", strtotime("+1 week"));
echo date("Y-m-d", strtotime("next Monday"));
// 时区设置
date_default_timezone_set("Asia/Shanghai");
echo date("Y-m-d H:i:s");
// 时间戳转日期
$ts = mktime(10, 30, 0, 8, 12, 2026);
echo date("Y-m-d H:i:s", $ts);
?>date_default_timezone_set("Asia/Shanghai"),否则时间差 8 小时。PHP 包含
包含文件(include/require)实现代码复用:
<?php
// include:文件不存在只警告,继续执行
include "header.php";
// require:文件不存在致命错误,停止执行
require "config.php";
// include_once / require_once:防止重复包含
require_once "config.php";
// 常用结构
// config.php —— 数据库配置
// header.php —— 公共头部
// footer.php —— 公共尾部
// functions.php —— 公共函数
?>
<html>
<body>
<?php include "header.php"; ?>
<p>页面主体</p>
<?php include "footer.php"; ?>
</body>
</html>require_once;模板片段用 include。PHP 文件
文件操作:
<?php
// 读取整个文件
$content = file_get_contents("data.txt");
echo $content;
// 写入文件(覆盖)
file_put_contents("out.txt", "Hello PHP");
// 追加写入
file_put_contents("log.txt", date("Y-m-d H:i:s") . "\n", FILE_APPEND);
// 逐行读取大文件
$fp = fopen("big.log", "r");
while (($line = fgets($fp)) !== false) {
echo $line;
}
fclose($fp);
// 检查文件
if (file_exists("data.txt")) {
echo filesize("data.txt"); // 字节
echo filemtime("data.txt"); // 修改时间
}
// 目录操作
mkdir("uploads"); // 建目录
$files = scandir("uploads"); // 列目录
unlink("out.txt"); // 删除文件
?>PHP 文件上传
文件上传:
<?php
// 表单: <form method="post" enctype="multipart/form-data">
if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_FILES["file"])) {
$file = $_FILES["file"];
// 错误检查
if ($file["error"] !== UPLOAD_ERR_OK) {
die("上传失败,错误码: " . $file["error"]);
}
// 大小限制(2MB)
if ($file["size"] > 2 * 1024 * 1024) {
die("文件超过 2MB");
}
// 类型白名单
$allowed = ["image/jpeg", "image/png", "image/gif"];
if (!in_array($file["type"], $allowed)) {
die("只允许图片");
}
// 生成唯一文件名防覆盖
$ext = pathinfo($file["name"], PATHINFO_EXTENSION);
$newName = date("YmdHis") . "_" . uniqid() . "." . $ext;
move_uploaded_file($file["tmp_name"], "uploads/" . $newName);
echo "上传成功: $newName";
}
?>
<form method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit">
</form>PHP Cookie
Cookie 是存在浏览器的小数据,用于记住用户状态:
<?php
// 设置 Cookie(必须在任何输出之前)
setcookie("username", "zhangsan", time() + 3600, "/");
setcookie("theme", "dark", time() + 86400 * 30, "/");
// 读取 Cookie
if (isset($_COOKIE["username"])) {
echo "欢迎回来," . $_COOKIE["username"];
}
// 删除 Cookie(设置过期时间为过去)
setcookie("username", "", time() - 3600, "/");
// 数组型 Cookie
setcookie("user[name]", "张三");
setcookie("user[age]", "25");
echo $_COOKIE["user"]["name"];
?>PHP Session
Session(会话)在服务器保存用户状态,比 Cookie 安全:
<?php
// 启动会话(必须在任何输出之前)
session_start();
// 存入会话
$_SESSION["user_id"] = 42;
$_SESSION["username"] = "zhangsan";
$_SESSION["is_login"] = true;
// 读取
if (isset($_SESSION["is_login"])) {
echo "已登录: " . $_SESSION["username"];
}
// 删除单个
unset($_SESSION["username"]);
// 清空并销毁会话
session_unset();
session_destroy();
// 购物车示例
$_SESSION["cart"] = [
["id" => 1, "name" => "商品A", "qty" => 2],
["id" => 2, "name" => "商品B", "qty" => 1],
];
?>PHP E-mail
发送 E-mail(mail 函数):
<?php
// 基础邮件
$to = "user@example.com";
$subject = "注册确认";
$message = "欢迎注册!请点击链接激活账号。";
$headers = "From: no-reply@example.com\r\n";
$headers .= "Content-Type: text/plain; charset=utf-8\r\n";
if (mail($to, $subject, $message, $headers)) {
echo "邮件已发送";
} else {
echo "发送失败";
}
// HTML 邮件
$html = "<html><body><h1>你好</h1><p>HTML 内容</p></body></html>";
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=utf-8\r\n";
mail($to, $subject, $html, $headers);
?>mail() 依赖服务器 SMTP 配置,容易被判定为垃圾邮件。生产推荐 PHPMailer/SwiftMailer + SMTP 认证。PHP 安全 E-mail
安全 E-mail(防注入与垃圾邮件滥用):
<?php
// 1. 校验收件人
$to = filter_var($_POST["to"], FILTER_VALIDATE_EMAIL);
if (!$to) die("收件人邮箱不合法");
// 2. 清洗邮件头(防 Header Injection)
function cleanHeader($str) {
return str_replace(["
", "
"], "", $str);
}
$name = cleanHeader($_POST["name"]);
$from = "=?UTF-8?B?" . base64_encode($name) . "?= <no-reply@example.com>";
// 3. 邮件内容转义
$message = htmlspecialchars($_POST["message"], ENT_QUOTES, "UTF-8");
// 4. 添加验证码防滥用
if (session_id() == "" || $_POST["code"] != $_SESSION["code"]) {
die("验证码错误");
}
// 5. 频率限制(简单防刷)
$key = "send_" . $_SERVER["REMOTE_ADDR"];
$count = $_SESSION[$key] ?? 0;
if ($count > 5) die("发送太频繁");
$_SESSION[$key] = $count + 1;
?>PHP Error
错误处理(Error):
<?php
// 1. 错误报告级别
error_reporting(E_ALL); // 显示所有错误
ini_set("display_errors", "1"); // 开发环境显示
// 2. 自定义错误处理
function myErrorHandler($errno, $errstr, $errfile, $errline) {
error_log("[$errno] $errstr in $errfile:$errline"); // 写日志
echo "出错了,请稍后再试";
return true; // 阻止默认处理
}
set_error_handler("myErrorHandler");
// 3. 触发一个错误
echo $undefinedVar;
// 4. 错误抑制符 @(不推荐滥用)
$result = @file_get_contents("not_exist.txt");
?>display_errors,开启 log_errors,避免把报错暴露给用户。PHP Exception
异常处理(Exception)是面向对象的错误机制:
<?php
// 抛出自定义异常
function divide($a, $b) {
if ($b == 0) {
throw new Exception("除数不能为零");
}
return $a / $b;
}
try {
echo divide(10, 0);
} catch (Exception $e) {
echo "捕获异常: " . $e->getMessage();
echo "文件: " . $e->getFile() . ":" . $e->getLine();
} finally {
echo "<br>无论是否异常都会执行(如关闭连接)";
}
// 自定义异常类
class ValidateException extends Exception {}
try {
$age = -5;
if ($age < 0) {
throw new ValidateException("年龄不能为负");
}
} catch (ValidateException $e) {
echo "校验失败: " . $e->getMessage();
} catch (Exception $e) {
echo "其他错误: " . $e->getMessage();
}
?>PHP 过滤器
过滤器(Filter)用于验证和清洗外部输入:
<?php
// 验证
$email = "test@example.com";
var_dump(filter_var($email, FILTER_VALIDATE_EMAIL)); // 邮箱
var_dump(filter_var("123", FILTER_VALIDATE_INT)); // 整数
var_dump(filter_var("1.5", FILTER_VALIDATE_FLOAT)); // 浮点
var_dump(filter_var("https://a.com", FILTER_VALIDATE_URL)); // URL
var_dump(filter_var("192.168.1.1", FILTER_VALIDATE_IP)); // IP
// 清洗(移除非法字符)
echo filter_var("<b>bold</b>", FILTER_SANITIZE_STRING); // bold
echo filter_var("a@b@c", FILTER_SANITIZE_EMAIL); // abc
// 过滤整个数组(表单场景)
$data = filter_var_array($_POST, [
"email" => FILTER_VALIDATE_EMAIL,
"age" => FILTER_VALIDATE_INT,
"name" => FILTER_SANITIZE_STRING
], false);
?>PHP 高级过滤器
高级过滤器:自定义选项与标志位:
<?php
// 整数范围验证
$age = filter_var("25", FILTER_VALIDATE_INT, [
"options" => [
"min_range" => 18,
"max_range" => 60
]
]);
var_dump($age); // 25(范围外返回 false)
// 正则过滤器
$phone = filter_var("13800138000", FILTER_VALIDATE_REGEXP, [
"options" => ["regexp" => "/^1[3-9]\d{9}$/"]
]);
var_dump($phone);
// 带标志位(FILTER_FLAG_*)
filter_var("http://example.com", FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED);
// 数组过滤 + 默认值
$input = [
"id" => "42abc",
"score" => "88"
];
$result = filter_var_array($input, [
"id" => ["filter" => FILTER_VALIDATE_INT],
"score" => [
"filter" => FILTER_VALIDATE_INT,
"options" => ["default" => 0]
]
], false);
print_r($result);
?>options 可配置范围/正则/默认值,一个 filter_var 顶一整套 if 判断。PHP JSON
JSON 编解码(前后端数据交换的基石):
<?php
// 数组 -> JSON
$data = [
"name" => "张三",
"age" => 25,
"tags" => ["php", "web"],
"active" => true
];
$json = json_encode($data, JSON_UNESCAPED_UNICODE);
echo $json; // {"name":"张三","age":25,...}
// JSON -> 数组
$arr = json_decode($json, true); // true = 关联数组
echo $arr["name"]; // 张三
// JSON -> 对象
$obj = json_decode($json);
echo $obj->age; // 25
// 错误处理
$bad = json_decode('{invalid json}');
if (json_last_error() !== JSON_ERROR_NONE) {
echo "JSON 解析失败: " . json_last_error_msg();
}
// 返回 JSON API
header("Content-Type: application/json; charset=utf-8");
echo json_encode(["status" => "ok", "data" => $data]);
?>JSON_UNESCAPED_UNICODE,避免 \uXXXX 转义。PHP 7 新特性
PHP 7/8 新特性:
| 版本 | 特性 |
|---|---|
| 7.0 | 标量类型声明、太空船运算符 <=>、?? 空合并 |
| 7.1 | 可空类型 ?int、void 返回类型 |
| 7.2 | object 类型、参数类型拓宽 |
| 7.3 | 灵活 Heredoc、is_countable() |
| 7.4 | 箭头函数 fn、类型属性、预加载 |
| 8.0 | 命名参数、match、构造器属性提升、联合类型 |
| 8.1 | 枚举 enum、只读属性、Fibers |
| 8.2 | 只读类、DNF 类型 |
<?php
// PHP 8:命名参数
function createUser($name, $role = "user", $active = true) {}
createUser(name: "张三", active: false);
// PHP 8:构造器属性提升
class User {
public function __construct(
public string $name,
public int $age = 0
) {}
}
$u = new User("李四", 30);
echo $u->name;
// PHP 8.1:枚举
enum Status: string {
case Pending = "pending";
case Paid = "paid";
}
echo Status::Paid->value; // paid
?>PHP MySQL 简介
PHP 与 MySQL 结合的简介:
<?php
// 两种主流方式
// 1. MySQLi(面向过程/面向对象)
// 2. PDO(推荐:支持多种数据库 + 预处理防注入)
// PDO 连接
try {
$pdo = new PDO(
"mysql:host=localhost;dbname=shop;charset=utf8mb4",
"root",
"password",
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
echo "连接成功";
} catch (PDOException $e) {
die("连接失败: " . $e->getMessage());
}
?>| 对比 | MySQLi | PDO |
|---|---|---|
| 支持的数据库 | 仅 MySQL | MySQL/PG/SQLite 等 |
| 预处理 | 支持 | 支持(推荐) |
| 面向对象 | 支持 | 支持 |
PHP MySQL 连接
PHP MySQL 连接(PDO 方式):
<?php
// 面向对象风格连接
$host = "localhost";
$db = "shop";
$user = "root";
$pass = "password";
try {
$dsn = "mysql:host=$host;dbname=$db;charset=utf8mb4";
$pdo = new PDO($dsn, $user, $pass);
// 设置错误模式为异常
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "数据库连接成功";
} catch (PDOException $e) {
die("连接失败: " . $e->getMessage());
}
// 关闭连接(赋 null)
$pdo = null;
?>PHP MySQL 创建数据库
创建数据库与数据表:
<?php
$pdo = new PDO("mysql:host=localhost", "root", "password");
// 创建数据库
$pdo->exec("CREATE DATABASE IF NOT EXISTS shop CHARACTER SET utf8mb4");
// 选择数据库
$pdo->exec("USE shop");
// 创建表
$pdo->exec("CREATE TABLE IF NOT EXISTS products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
price DECIMAL(10,2) NOT NULL DEFAULT 0,
stock INT NOT NULL DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
echo "数据表创建成功";
?>PHP MySQL 插入数据
插入数据(预处理防注入):
<?php
$pdo = new PDO("mysql:host=localhost;dbname=shop;charset=utf8mb4", "root", "password");
// 单条插入
$stmt = $pdo->prepare(
"INSERT INTO products (name, price, stock) VALUES (?, ?, ?)"
);
$stmt->execute(["手机", 2999.00, 100]);
// 用命名参数
$stmt = $pdo->prepare(
"INSERT INTO products (name, price, stock) VALUES (:name, :price, :stock)"
);
$stmt->execute([
":name" => "耳机",
":price" => 199.00,
":stock" => 500
]);
// 获取自增 ID
echo "新商品 ID: " . $pdo->lastInsertId();
// 批量插入
$pdo->beginTransaction();
$stmt = $pdo->prepare("INSERT INTO products (name, price) VALUES (?, ?)");
foreach ([["商品A", 10], ["商品B", 20]] as $row) {
$stmt->execute($row);
}
$pdo->commit(); // 或 rollback()
?>PHP MySQL 读取数据
读取数据:
<?php
$pdo = new PDO("mysql:host=localhost;dbname=shop;charset=utf8mb4", "root", "password");
// 查询全部
$stmt = $pdo->query("SELECT * FROM products");
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
echo $row["name"] . " - " . $row["price"] . "<br>";
}
// 条件查询
$stmt = $pdo->prepare("SELECT * FROM products WHERE price > ?");
$stmt->execute([100]);
$rows = $stmt->fetchAll();
// 取单行
$stmt = $pdo->prepare("SELECT * FROM products WHERE id = ?");
$stmt->execute([1]);
$product = $stmt->fetch(PDO::FETCH_ASSOC);
echo $product["name"] ?? "不存在";
// 统计
$count = $pdo->query("SELECT COUNT(*) FROM products")->fetchColumn();
echo "共 $count 件商品";
// 遍历游标(大结果集省内存)
$stmt = $pdo->query("SELECT * FROM products");
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo $row["name"] . "<br>";
}
?>PDO::FETCH_ASSOC 返回关联数组(列名作键),最常用。PHP MySQL Where
WHERE 条件:
<?php
$pdo = new PDO("mysql:host=localhost;dbname=shop;charset=utf8mb4", "root", "password");
// 基本条件
$stmt = $pdo->prepare("SELECT * FROM products WHERE stock > ?");
$stmt->execute([0]);
// 多条件
$stmt = $pdo->prepare(
"SELECT * FROM products WHERE price BETWEEN ? AND ? AND stock > ?"
);
$stmt->execute([100, 500, 0]);
// LIKE 模糊查询(注意 % 通配符)
$stmt = $pdo->prepare("SELECT * FROM products WHERE name LIKE ?");
$stmt->execute(["%手机%"]);
// IN
$stmt = $pdo->prepare("SELECT * FROM products WHERE id IN (?, ?, ?)");
$stmt->execute([1, 2, 3]);
// 动态条件拼装(安全做法:条件数组 + 参数数组)
$where = [];
$params = [];
if (!empty($_GET["min_price"])) {
$where[] = "price >= ?";
$params[] = (float)$_GET["min_price"];
}
$sql = "SELECT * FROM products";
if ($where) $sql .= " WHERE " . implode(" AND ", $where);
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$rows = $stmt->fetchAll();
?>%、_ 需转义,否则通配符会被用户利用。PHP MySQL Order By
ORDER BY 排序:
<?php
$pdo = new PDO("mysql:host=localhost;dbname=shop;charset=utf8mb4", "root", "password");
// 基本排序
$rows = $pdo->query(
"SELECT * FROM products ORDER BY price DESC"
)->fetchAll();
// 多字段排序
$rows = $pdo->query(
"SELECT * FROM products ORDER BY stock DESC, price ASC"
)->fetchAll();
// 字段白名单(防注入)
$allowed = ["price", "stock", "created_at"];
$sort = $_GET["sort"] ?? "price";
if (!in_array($sort, $allowed)) $sort = "price";
$dir = ($_GET["dir"] ?? "asc") === "desc" ? "DESC" : "ASC";
$rows = $pdo->query(
"SELECT * FROM products ORDER BY $sort $dir"
)->fetchAll();
// 分页
$page = max(1, (int)($_GET["page"] ?? 1));
$size = 20;
$offset = ($page - 1) * $size;
$stmt = $pdo->prepare(
"SELECT * FROM products ORDER BY id DESC LIMIT ? OFFSET ?"
);
$stmt->execute([$size, $offset]);
$rows = $stmt->fetchAll();
?>PHP MySQL Update
UPDATE 更新数据:
<?php
$pdo = new PDO("mysql:host=localhost;dbname=shop;charset=utf8mb4", "root", "password");
// 基本更新
$stmt = $pdo->prepare(
"UPDATE products SET price = ?, stock = ? WHERE id = ?"
);
$stmt->execute([2599.00, 80, 1]);
echo "影响行数: " . $stmt->rowCount();
// 更新多个字段
$stmt = $pdo->prepare(
"UPDATE products SET name = :name, price = :price WHERE id = :id"
);
$stmt->execute([
":name" => "新款手机",
":price" => 3299.00,
":id" => 1
]);
// 自增更新(库存扣减)
$stmt = $pdo->prepare(
"UPDATE products SET stock = stock - ? WHERE id = ? AND stock >= ?"
);
$stmt->execute([1, 1, 1]); // 防止超卖
if ($stmt->rowCount() === 0) {
echo "库存不足";
}
?>PHP MySQL Delete
DELETE 删除数据:
<?php
$pdo = new PDO("mysql:host=localhost;dbname=shop;charset=utf8mb4", "root", "password");
// 单条删除
$stmt = $pdo->prepare("DELETE FROM products WHERE id = ?");
$stmt->execute([1]);
echo "删除 " . $stmt->rowCount() . " 行";
// 条件批量删除
$stmt = $pdo->prepare("DELETE FROM products WHERE stock = ? AND price < ?");
$stmt->execute([0, 10]);
// 清空表(保留结构)
$pdo->exec("TRUNCATE TABLE products");
// 软删除(推荐:逻辑删除而非物理删除)
$stmt = $pdo->prepare("UPDATE products SET deleted_at = NOW() WHERE id = ?");
$stmt->execute([5]);
// 查询时过滤: WHERE deleted_at IS NULL
?>PHP ODBC
ODBC(开放数据库连接)让 PHP 连接不同数据库(Access/SQL Server 等):
<?php
// 启用 odbc 扩展
// 连接 ODBC 数据源(DSN)
$conn = odbc_connect("MyDSN", "user", "password");
if (!$conn) {
die("ODBC 连接失败: " . odbc_error());
}
// 查询
$result = odbc_exec($conn, "SELECT * FROM customers");
while ($row = odbc_fetch_array($result)) {
echo $row["name"] . "<br>";
}
// 带参数查询
$stmt = odbc_prepare($conn, "SELECT * FROM customers WHERE id = ?");
odbc_execute($stmt, [42]);
while ($row = odbc_fetch_array($stmt)) {
print_r($row);
}
// 关闭
odbc_close($conn);
?>XML Expat Parser
XML Expat Parser 是基于事件的 XML 解析器,边读边回调,内存占用低:
<?php
// 创建解析器
$parser = xml_parser_create();
// 设置元素回调
function startElement($parser, $name, $attrs) {
echo "开始标签: $name<br>";
}
function endElement($parser, $name) {
echo "结束标签: $name<br>";
}
function charData($parser, $data) {
if (trim($data)) echo "内容: $data<br>";
}
xml_set_element_handler($parser, "startElement", "endElement");
xml_set_character_data_handler($parser, "charData");
// 解析 XML
$xml = "<book><title>PHP 教程</title><price>59</price></book>";
xml_parse($parser, $xml);
// 释放
xml_parser_free($parser);
?>XML DOM
XML DOM 把整个 XML 加载为对象树,支持随机访问与修改:
<?php
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="1">
<title>PHP 教程</title>
<price>59</price>
</book>
<book id="2">
<title>MySQL 教程</title>
<price>49</price>
</book>
</books>
XML;
// 加载
$dom = new DOMDocument();
$dom->loadXML($xml);
// 查询
$books = $dom->getElementsByTagName("book");
foreach ($books as $book) {
$title = $book->getElementsByTagName("title")->item(0)->nodeValue;
echo "书名: $title<br>";
}
// 修改
$books->item(0)->getElementsByTagName("price")->item(0)->nodeValue = "69";
echo $dom->saveXML();
// 从文件加载
// $dom->load("books.xml");
// $dom->save("books_new.xml");
?>XML SimpleXML
XML SimpleXML 是最简单的 XML 处理方式,把 XML 转成对象/数组:
<?php
$xml = <<<XML
<books>
<book>
<title>PHP 教程</title>
<price>59</price>
<author>张三</author>
</book>
</books>
XML;
// 加载
$books = simplexml_load_string($xml);
// 从文件: simplexml_load_file("books.xml")
// 访问(对象属性)
echo $books->book->title; // PHP 教程
echo $books->book->price; // 59
// 遍历
foreach ($books->book as $book) {
echo $book->title . " - " . $book->price . "<br>";
}
// 转数组
$arr = json_decode(json_encode($books), true);
print_r($arr);
// 添加节点
$newBook = $books->addChild("book");
$newBook->addChild("title", "Redis 教程");
$newBook->addChild("price", "39");
echo $books->asXML();
?>AJAX 简介
AJAX(Asynchronous JavaScript And XML)让网页无刷新与服务器通信:
// 前端:发送 AJAX 请求
function loadData() {
var xhr = new XMLHttpRequest();
xhr.open("GET", "data.php", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
document.getElementById("result").innerHTML = xhr.responseText;
}
};
xhr.send();
}<?php
// 后端 data.php:返回数据
header("Content-Type: text/plain; charset=utf-8");
echo "这是 AJAX 返回的数据:" . date("H:i:s");
?>fetch() 或 axios 替代 XMLHttpRequest,但原理相同。AJAX PHP
AJAX + PHP 完整交互示例:
<!-- 前端 index.html -->
<input type="text" id="name" placeholder="输入姓名">
<button>发送</button>
<div id="result"></div>
<script>
function send() {
var name = document.getElementById("name").value;
var xhr = new XMLHttpRequest();
xhr.open("POST", "server.php", true);
xhr.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
document.getElementById("result").innerHTML =
xhr.responseText;
}
};
xhr.send("name=" + encodeURIComponent(name));
}
</script><?php
// 后端 server.php
$name = htmlspecialchars($_POST["name"] ?? "");
echo "你好,$name!服务器时间是 " . date("H:i:s");
?>AJAX 数据库
AJAX + 数据库:无刷新查询数据:
<!-- 前端:输入关键字实时查商品 -->
<input type="text" id="kw">
<ul id="list"></ul>
<script>
function search() {
var kw = document.getElementById("kw").value;
var xhr = new XMLHttpRequest();
xhr.open("GET", "search.php?kw=" + encodeURIComponent(kw), true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
document.getElementById("list").innerHTML = xhr.responseText;
}
};
xhr.send();
}
</script><?php
// 后端 search.php
$pdo = new PDO("mysql:host=localhost;dbname=shop;charset=utf8mb4",
"root", "password");
$kw = "%" . ($_GET["kw"] ?? "") . "%";
$stmt = $pdo->prepare(
"SELECT name, price FROM products WHERE name LIKE ? LIMIT 10"
);
$stmt->execute([$kw]);
foreach ($stmt->fetchAll() as $row) {
echo "<li>" . htmlspecialchars($row["name"])
. " - ¥" . $row["price"] . "</li>";
}
?>AJAX XML
AJAX + XML:解析 XML 响应:
<!-- 前端 -->
<button>加载 XML</button>
<div id="out"></div>
<script>
function loadXml() {
var xhr = new XMLHttpRequest();
xhr.open("GET", "data.php", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var xml = xhr.responseXML;
var titles = xml.getElementsByTagName("title");
var html = "";
for (var i = 0; i < titles.length; i++) {
html += "<p>" + titles[i].firstChild.nodeValue + "</p>";
}
document.getElementById("out").innerHTML = html;
}
};
xhr.send();
}
</script><?php
// 后端返回 XML
header("Content-Type: text/xml; charset=utf-8");
echo '<?xml version="1.0" encoding="UTF-8"?>';
echo '<books><book><title>PHP 教程</title></book><book><title>MySQL 教程</title></book></books>';
?>AJAX 实时搜索
AJAX 实时搜索(输入即搜,带防抖):
<!-- 前端 -->
<input type="text" id="search" placeholder="搜索商品...">
<div id="suggest"></div>
<script>
var timer;
document.getElementById("search").addEventListener("input", function() {
clearTimeout(timer); // 防抖:停止输入 300ms 后才请求
timer = setTimeout(function() {
var kw = document.getElementById("search").value;
if (kw.length < 1) return;
var xhr = new XMLHttpRequest();
xhr.open("GET", "suggest.php?q=" + encodeURIComponent(kw), true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
document.getElementById("suggest").innerHTML =
xhr.responseText;
}
};
xhr.send();
}, 300);
});
</script><?php
// 后端 suggest.php(返回 JSON)
$pdo = new PDO("mysql:host=localhost;dbname=shop;charset=utf8mb4",
"root", "password");
$kw = "%" . ($_GET["q"] ?? "") . "%";
$stmt = $pdo->prepare("SELECT name FROM products WHERE name LIKE ? LIMIT 5");
$stmt->execute([$kw]);
$names = $stmt->fetchAll(PDO::FETCH_COLUMN);
header("Content-Type: application/json; charset=utf-8");
echo json_encode($names, JSON_UNESCAPED_UNICODE);
?>AJAX RSS Reader
AJAX RSS Reader:读取并展示 RSS 订阅源:
<?php
// 后端 rss.php:抓取并解析 RSS
$rssUrl = $_GET["url"] ?? "https://example.com/feed.xml";
$xml = @simplexml_load_file($rssUrl);
if (!$xml) die("无法读取 RSS");
header("Content-Type: text/html; charset=utf-8");
foreach ($xml->channel->item as $item) {
echo "<div class='item'>";
echo "<h3><a href='" . htmlspecialchars($item->link)
. "' target='_blank'>" . htmlspecialchars($item->title) . "</a></h3>";
echo "<p>" . htmlspecialchars($item->pubDate) . "</p>";
echo "<p>" . strip_tags($item->description) . "</p>";
echo "</div>";
}
?><!-- 前端:AJAX 加载 RSS -->
<script>
fetch("rss.php?url=" + encodeURIComponent(
"https://example.com/feed.xml"))
.then(r => r.text())
.then(html => document.getElementById("rss").innerHTML = html);
</script>simplexml_load_file 会向外部 URL 发请求,生产环境务必限制来源并设置超时。AJAX 投票
AJAX 投票:无刷新投票:
<!-- 前端 -->
<button>👍 点赞</button>
<button>👎 点踩</button>
<span id="count">0</span>
<script>
function vote(type) {
var xhr = new XMLHttpRequest();
xhr.open("POST", "vote.php", true);
xhr.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
document.getElementById("count").innerHTML = xhr.responseText;
}
};
xhr.send("type=" + type);
}
</script><?php
// 后端 vote.php(原子自增)
$pdo = new PDO("mysql:host=localhost;dbname=site;charset=utf8mb4",
"root", "password");
$type = (int)($_POST["type"] ?? 0);
// 防刷:基于 IP + 时间(简化)
$ip = $_SERVER["REMOTE_ADDR"];
$stmt = $pdo->prepare(
"SELECT COUNT(*) FROM votes WHERE ip=? AND created_at > NOW() - INTERVAL 60 SECOND"
);
$stmt->execute([$ip]);
if ($stmt->fetchColumn() > 0) { echo "操作太频繁"; exit; }
// 原子更新
$pdo->prepare(
"INSERT INTO votes (type, ip) VALUES (?, ?)"
)->execute([$type, $ip]);
// 返回最新计数
echo $pdo->query("SELECT COUNT(*) FROM votes WHERE type=1")->fetchColumn();
?>PHP Array
PHP Array 数组函数专题:
<?php
$arr = ["a" => 1, "b" => 2, "c" => 3];
// 取键/值
print_r(array_keys($arr)); // [a, b, c]
print_r(array_values($arr)); // [1, 2, 3]
// 检查
array_key_exists("a", $arr); // true
in_array(2, $arr); // true
// 查找键
array_search(2, $arr); // "b"
// 过滤
$even = array_filter([1,2,3,4], fn($v) => $v % 2 == 0); // [2,4]
// 映射
$double = array_map(fn($v) => $v * 2, [1,2,3]); // [2,4,6]
// 归并
array_reduce([1,2,3,4], fn($carry, $v) => $carry + $v, 0); // 10
// 翻转键值
array_flip($arr); // [1 => "a", ...]
// 切片
array_slice([1,2,3,4,5], 1, 3); // [2,3,4]
// 差集/交集
array_diff([1,2,3], [2,3,4]); // [1]
array_intersect([1,2,3], [2,3,4]); // [2,3]
?>PHP Calendar
PHP Calendar 日历相关函数:
<?php
// 需要启用 calendar 扩展
// 某月天数
echo cal_days_in_month(CAL_GREGORIAN, 2, 2026); // 28
// 当前时间信息
$info = getdate();
print_r($info);
// ['year' => 2026, 'mon' => 8, 'mday' => 12, 'wday' => 3, ...]
// 判断闰年
echo (date("L") == 1) ? "今年是闰年" : "今年不是闰年";
// 儒略日转换
echo unixtojd(time()); // 转儒略日
echo jdtounix(2461280); // 儒略日转时间戳
// 日期差
$d1 = new DateTime("2026-01-01");
$d2 = new DateTime("2026-08-12");
$diff = $d1->diff($d2);
echo "相差 " . $diff->days . " 天";
?>PHP cURL
cURL 用于发起 HTTP 请求(调用 API、抓取网页):
<?php
// 初始化
$ch = curl_init();
// 基本 GET 请求
curl_setopt($ch, CURLOPT_URL, "https://api.example.com/data");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回字符串而非输出
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 超时
$response = curl_exec($ch);
curl_close($ch);
echo $response;
// POST + JSON
$ch = curl_init("https://api.example.com/login");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"username" => "admin",
"password" => "secret"
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
// 带 Header 的请求(Token 认证)
$ch = curl_init("https://api.example.com/user");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer your_token"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
echo curl_exec($ch);
curl_close($ch);
// 错误检查
if (curl_errno($ch)) {
echo "cURL 错误: " . curl_error($ch);
}
?>CURLOPT_SSL_VERIFYPEER = false(生产不建议)。PHP Date
PHP Date 日期函数专题:
<?php
// 格式化符号速查
echo date("Y-m-d"); // 2026-08-12
echo date("H:i:s"); // 10:30:00
echo date("Y/m/d H:i"); // 2026/08/12 10:30
echo date("D"); // Wed(星期简写)
echo date("N"); // 3(星期 1-7)
echo date("z"); // 一年中的第几天
// DateTime 面向对象
$dt = new DateTime();
echo $dt->format("Y-m-d H:i:s");
// 修改
$dt->modify("+1 day");
$dt->modify("-2 hours");
// 日期比较
$d1 = new DateTime("2026-01-01");
$d2 = new DateTime("2026-08-12");
var_dump($d2 > $d1); // true
// 时区
$dt->setTimezone(new DateTimeZone("Asia/Shanghai"));
echo $dt->format("Y-m-d H:i:s T");
// 周/月
echo date("W"); // 一年中的第几周
echo date("t"); // 当月天数
?>date() 受默认时区影响,入口处统一设置 date_default_timezone_set()。PHP Directory
PHP Directory 目录操作:
<?php
// 创建目录
mkdir("uploads/2026/08", 0777, true); // true = 递归创建
// 检查
is_dir("uploads"); // true
is_writable("uploads"); // 可写?
// 列出目录
$items = scandir("uploads");
foreach ($items as $item) {
if ($item == "." || $item == "..") continue;
echo $item . "<br>";
}
// 遍历(含子目录,递归)
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator("uploads")
);
foreach ($iterator as $file) {
if ($file->isFile()) {
echo $file->getPathname() . " ("
. $file->getSize() . "B)<br>";
}
}
// 删除目录(必须为空)
rmdir("uploads/empty_dir");
// 当前目录/切换
echo getcwd(); // 当前工作目录
chdir("/tmp");
?>PHP Filesystem
PHP Filesystem 文件系统函数专题:
<?php
// 路径处理
$path = "/var/www/site/index.php";
echo basename($path); // index.php
echo dirname($path); // /var/www/site
echo pathinfo($path, PATHINFO_EXTENSION); // php
print_r(pathinfo($path)); // 全部信息
// 文件信息
clearstatcache();
echo file_exists($path) ? "存在" : "不存在";
echo file_get_contents("test.txt");
// 复制/移动/删除
copy("a.txt", "b.txt");
rename("b.txt", "c.txt"); // 移动或重命名
unlink("c.txt"); // 删除
// 权限与时间
chmod("test.txt", 0644);
echo fileperms("test.txt");
echo date("Y-m-d", filemtime("test.txt"));
// 读取远程文件(需 allow_url_fopen)
$content = @file_get_contents("https://example.com");
if ($content !== false) echo substr($content, 0, 100);
?>clearstatcache() 刷新缓存,避免获取到旧状态。PHP Filter
PHP Filter 过滤器专题:
<?php
// 常用验证过滤器
$filters = [
"email" => FILTER_VALIDATE_EMAIL,
"int" => FILTER_VALIDATE_INT,
"float" => FILTER_VALIDATE_FLOAT,
"url" => FILTER_VALIDATE_URL,
"ip" => FILTER_VALIDATE_IP,
"bool" => FILTER_VALIDATE_BOOLEAN,
];
foreach ($filters as $name => $f) {
var_dump(filter_var("test@example.com", $f));
}
// 常用清洗过滤器
echo filter_var("<script>alert(1)</script>hello", FILTER_SANITIZE_STRING);
echo filter_var("hello world", FILTER_SANITIZE_ADD_SLASHES); // 加反斜杠
// 检查过滤器是否存在
var_dump(filter_has_var(INPUT_GET, "page"));
$page = filter_input(INPUT_GET, "page", FILTER_VALIDATE_INT);
echo $page;
// 全部过滤器列表
print_r(filter_list());
?>FILTER_SANITIZE_STRING 被弃用,改用 htmlspecialchars()。PHP FTP
PHP FTP 文件传输:
<?php
// 连接 FTP 服务器
$conn = ftp_connect("ftp.example.com") or die("无法连接");
$login = ftp_login($conn, "username", "password");
ftp_pasv($conn, true); // 开启被动模式
// 上传
if (ftp_put($conn, "remote/file.txt", "local/file.txt", FTP_BINARY)) {
echo "上传成功";
}
// 下载
if (ftp_get($conn, "local/file.txt", "remote/file.txt", FTP_BINARY)) {
echo "下载成功";
}
// 列出目录
$list = ftp_nlist($conn, "/public_html");
print_r($list);
// 创建/删除目录
ftp_mkdir($conn, "/public_html/newdir");
ftp_rmdir($conn, "/public_html/newdir");
// 重命名
ftp_rename($conn, "a.txt", "b.txt");
// 关闭
ftp_close($conn);
?>PHP HTTP
PHP HTTP:获取请求信息与发送响应:
<?php
// 请求头
$headers = getallheaders();
foreach ($headers as $k => $v) {
echo "$k: $v<br>";
}
// 请求方法
echo $_SERVER["REQUEST_METHOD"];
// 客户端信息
echo $_SERVER["HTTP_USER_AGENT"];
echo $_SERVER["REMOTE_ADDR"];
// 响应头
header("Content-Type: text/html; charset=utf-8");
header("X-Powered-By: PHP");
// 跳转
header("Location: https://example.com/");
exit;
// 缓存控制
header("Cache-Control: no-store");
// 下载文件
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename="file.pdf"");
readfile("file.pdf");
?>header() 必须在任何输出之前调用;跳转后记得 exit。PHP Libxml
PHP Libxml:底层 XML 库接口(SimpleXML/DOM 的基础):
<?php
// 设置 libxml 选项(全局)
libxml_use_internal_errors(true);
// 解析可能含错误的 XML
$xml = <<<XML
<book>
<title>PHP 教程</title>
<price>59</price>
XML; // 缺少闭合标签
$dom = new DOMDocument();
$loaded = $dom->loadXML($xml);
if (!$loaded) {
$errors = libxml_get_errors();
foreach ($errors as $err) {
echo "错误 L" . $err->line . ": " . $err->message . "<br>";
}
libxml_clear_errors();
}
// 防止 XXE 攻击(外部实体注入)
libxml_disable_entity_loader(true);
// 解析前调用,阻止外部实体读取本地文件
?>libxml_disable_entity_loader(true)。PHP Mail
PHP Mail 邮件相关函数:
<?php
// mail() 函数参数
// mail(收件人, 主题, 内容, 附加头)
$to = "user@example.com";
$subject = "=?UTF-8?B?" . base64_encode("测试邮件") . "?=";
$message = "你好,这是一封测试邮件。";
$headers = "From: no-reply@example.com\r\n";
$headers .= "Reply-To: support@example.com\r\n";
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
if (mail($to, $subject, $message, $headers)) {
echo "发送成功";
} else {
echo "发送失败";
}
// 检查 sendmail 路径
echo ini_get("sendmail_path");
echo ini_get("SMTP");
// 生产推荐:PHPMailer
// $mail = new PHPMailer(true);
// $mail->isSMTP();
// $mail->Host = "smtp.example.com";
// $mail->SMTPAuth = true;
// $mail->Username = "user";
// $mail->Password = "pass";
// $mail->setFrom("from@example.com");
// $mail->addAddress("to@example.com");
// $mail->isHTML(true);
// $mail->Subject = "测试";
// $mail->Body = "<b>HTML 内容</b>";
// $mail->send();
?>=?UTF-8?B?base64?= 编码,否则乱码。PHP Math
PHP Math 数学函数:
<?php
// 常用数学函数
echo abs(-5); // 5
echo ceil(4.1); // 5(向上取整)
echo floor(4.9); // 4(向下取整)
echo round(4.567, 2); // 4.57(四舍五入保留 2 位)
echo max(1, 5, 3); // 5
echo min(1, 5, 3); // 1
echo pow(2, 10); // 1024
echo sqrt(16); // 4
echo rand(1, 100); // 随机数
echo mt_rand(1, 100); // 更快更随机的随机数
echo pi(); // 3.14159...
echo deg2rad(180); // 3.14159(角度转弧度)
// 三角函数
echo sin(deg2rad(30)); // 0.5
echo cos(deg2rad(60)); // 0.5
echo tan(deg2rad(45)); // 1
// 进制转换
echo base_convert("ff", 16, 10); // 255
echo decbin(10); // 1010
echo hexdec("ff"); // 255
// 格式化数字
echo number_format(1234567.891, 2); // 1,234,567.89
?>round() 或 bcmath 扩展,避免浮点精度问题。PHP Misc
PHP Misc 杂项函数:
<?php
// 变量操作
$arr = ["a" => 1];
extract($arr); // 生成变量 $a = 1
compact("a"); // 反向:变量名 -> 数组
// 唯一 ID
echo uniqid(); // 5f8c9a1b2c3d4
echo uniqid("order_", true); // 前缀 + 更多熵
// 序列化
$data = ["name" => "张三", "age" => 25];
$str = serialize($data); // a:2:{s:4:"name";...}
$back = unserialize($str);
// 二进制安全字符串
echo bin2hex("Hello"); // 48656c6c6f
echo hex2bin("48656c6c6f"); // Hello
// 环境与执行
echo phpinfo(); // PHP 配置信息
echo getenv("HOME"); // 环境变量
echo php_uname(); // 系统信息
// 休眠
sleep(2); // 秒
usleep(500000); // 微秒
// 高精度时间
echo microtime(true);
?>unserialize() 处理不可信数据可能触发反序列化漏洞,务必只反序列化自己的数据。PHP MySQLi
PHP MySQLi 面向过程用法:
<?php
// 连接
$conn = mysqli_connect("localhost", "root", "password", "shop");
if (!$conn) {
die("连接失败: " . mysqli_connect_error());
}
mysqli_set_charset($conn, "utf8mb4");
// 查询
$result = mysqli_query($conn, "SELECT * FROM products");
while ($row = mysqli_fetch_assoc($result)) {
echo $row["name"] . " - " . $row["price"] . "<br>";
}
// 预处理(防注入)
$stmt = mysqli_prepare($conn, "SELECT * FROM products WHERE id = ?");
mysqli_stmt_bind_param($stmt, "i", $id);
$id = 1;
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_assoc($result);
// 插入
$stmt = mysqli_prepare($conn, "INSERT INTO products (name, price) VALUES (?, ?)");
mysqli_stmt_bind_param($stmt, "sd", $name, $price);
$name = "键盘"; $price = 99.9;
mysqli_stmt_execute($stmt);
echo "新 ID: " . mysqli_insert_id($conn);
// 关闭
mysqli_close($conn);
?>PHP SimpleXML
PHP SimpleXML 专题进阶:
<?php
// 命名空间处理
$xml = <<<XML
<feed xmlns:dc="http://purl.org/dc/elements/1.1/">
<item>
<title>文章标题</title>
<dc:creator>张三</dc:creator>
</item>
</feed>
XML;
$feed = simplexml_load_string($xml);
// 访问带命名空间的元素
$ns = $feed->getNamespaces(true);
$creator = $feed->item->children($ns["dc"])->creator;
echo $creator; // 张三
// XPath 查询
$items = $feed->xpath("//item/title");
foreach ($items as $t) echo $t . "<br>";
// 属性访问
$xml2 = '<book id="5" lang="zh">PHP 教程</book>';
$book = simplexml_load_string($xml2);
echo $book["id"]; // 5
echo $book["lang"]; // zh
// 判断与遍历
if ($book->count() > 0) echo "有子元素";
?>xpath() 是解析复杂 XML 的高效组合。PHP String
PHP String 字符串函数大全:
<?php
$s = "Hello, PHP World";
// 大小写
strtolower($s); strtoupper($s);
ucfirst("hello"); // Hello
ucwords("hello world"); // Hello World
// 填充与格式化
str_pad("5", 3, "0", STR_PAD_LEFT); // 005
str_repeat("-", 10); // ----------
printf("%s 有 %d 个苹果", "张三", 3);
// 搜索
strstr($s, "PHP"); // PHP World(从匹配开始)
strrpos($s, "o"); // 最后一次出现位置
substr_count($s, "o"); // 出现次数
// 比较
strcmp("a", "b"); // -1
strcasecmp("A", "a"); // 0(忽略大小写)
strncmp("abc", "abd", 2); // 0(前 2 字符相同)
// 反转/洗牌
strrev($s); // 反转
str_shuffle($s); // 随机打乱
// 转义与还原
htmlspecialchars("<b>bold</b>"); // <b>...
addslashes("It's"); // It\'s
stripslashes("It\'s");
// 去除
trim(" hi "); ltrim(" hi"); rtrim("hi ");
?>php.net/manual。PHP XML
PHP XML 全解析方式对比:
| 方式 | 特点 | 适用 |
|---|---|---|
| SimpleXML | 最简单,对象式 | 中小文件 |
| DOM | 完整树,可增删改 | 需要修改/随机访问 |
| Expat | 事件流式,省内存 | 超大文件 |
| XMLReader | 流式 + 可导航 | 大文件且需控制 |
| XPath | 查询语言 | 复杂定位 |
<?php
// XMLReader 流式解析大文件示例
$reader = new XMLReader();
$reader->open("big.xml");
while ($reader->read()) {
if ($reader->nodeType == XMLReader::ELEMENT
&& $reader->name == "item") {
// 读取整个 item 节点
$node = new SimpleXMLElement(
$reader->readOuterXml());
echo $node->title . "<br>";
}
}
$reader->close();
?>PHP Zip
PHP Zip 压缩与解压:
<?php
// 需要启用 zip 扩展
// 创建压缩包
$zip = new ZipArchive();
if ($zip->open("archive.zip", ZipArchive::CREATE) === true) {
$zip->addFile("file1.txt"); // 添加文件
$zip->addFile("file2.jpg", "images/"); // 添加到子目录
$zip->addFromString("readme.txt", "内容");
$zip->close();
echo "压缩完成";
}
// 解压
$zip = new ZipArchive();
if ($zip->open("archive.zip") === true) {
$zip->extractTo("output/"); // 解压到目录
$zip->close();
echo "解压完成";
}
// 读取包内列表
$zip = new ZipArchive();
$zip->open("archive.zip");
for ($i = 0; $i < $zip->numFiles; $i++) {
echo $zip->getNameIndex($i) . "<br>";
}
$zip->close();
// 递归压缩目录
function zipDir($dir, $zip, $prefix = "") {
$files = scandir($dir);
foreach ($files as $f) {
if ($f == "." || $f == "..") continue;
$path = "$dir/$f";
if (is_dir($path)) {
zipDir($path, $zip, "$prefix$f/");
} else {
$zip->addFile($path, "$prefix$f");
}
}
}
?>PHP Timezones
PHP Timezones 时区处理:
<?php
// 设置默认时区
date_default_timezone_set("Asia/Shanghai");
echo date("Y-m-d H:i:s");
// 获取当前时区
echo date_default_timezone_get(); // Asia/Shanghai
// 列出所有时区
$zones = timezone_identifiers_list();
echo count($zones); // 425 个
// 指定时区创建时间
$dt = new DateTime("now", new DateTimeZone("America/New_York"));
echo $dt->format("Y-m-d H:i:s T");
// 时区转换
$dt = new DateTime("2026-08-12 10:00:00",
new DateTimeZone("Asia/Shanghai"));
$dt->setTimezone(new DateTimeZone("UTC"));
echo $dt->format("Y-m-d H:i:s"); // 2026-08-12 02:00:00
// 常用中国时区
// Asia/Shanghai(北京时间,推荐)
// Asia/Chongqing、Asia/Harbin 已废弃合并
// 检查时区有效性
var_dump(timezone_open("Asia/Shanghai")); // object
var_dump(timezone_open("Invalid/Zone")); // false
?>PHP 图像处理
PHP 图像处理(GD 库):
<?php
// 需要启用 gd 扩展
// 创建图片
$img = imagecreatetruecolor(400, 200);
$white = imagecolorallocate($img, 255, 255, 255);
$black = imagecolorallocate($img, 0, 0, 0);
// 填充背景
imagefill($img, 0, 0, $white);
// 画文本
imagestring($img, 5, 50, 50, "Hello PHP", $black);
// 中文字体需要 imagettftext + TTF 字体文件
// 画线/矩形/圆
imageline($img, 0, 100, 400, 100, $black);
imagerectangle($img, 50, 50, 150, 150, $black);
imageellipse($img, 200, 100, 100, 50, $black);
// 输出为 PNG
header("Content-Type: image/png");
imagepng($img);
// 保存到文件
imagepng($img, "output.png");
// 释放内存
imagedestroy($img);
// 验证码生成(常用场景)
$w = 120; $h = 40;
$img = imagecreatetruecolor($w, $h);
$bg = imagecolorallocate($img, 240, 240, 240);
imagefill($img, 0, 0, $bg);
$code = substr(str_shuffle("ABCDEFGHJKLMNPQRSTUVWXYZ23456789"), 0, 4);
for ($i = 0; $i < 4; $i++) {
$color = imagecolorallocate($img, rand(0,150), rand(0,150), rand(0,150));
imagestring($img, 5, 15 + $i*25, 10, $code[$i], $color);
}
header("Content-Type: image/png");
imagepng($img);
imagedestroy($img);
?>PHP RESTful
PHP RESTful API 开发示例:
<?php
// 简单 RESTful 路由(不依赖框架)
header("Content-Type: application/json; charset=utf-8");
$method = $_SERVER["REQUEST_METHOD"];
$path = trim($_SERVER["REQUEST_URI"], "/");
$segments = explode("/", $path);
$resource = $segments[0] ?? "";
$id = $segments[1] ?? null;
// 数据库连接
$pdo = new PDO("mysql:host=localhost;dbname=shop;charset=utf8mb4",
"root", "password");
switch ("$method /$resource") {
case "GET /products": // 列表
$rows = $pdo->query("SELECT * FROM products")->fetchAll();
echo json_encode($rows);
break;
case "GET /products/$id": // 详情
$stmt = $pdo->prepare("SELECT * FROM products WHERE id=?");
$stmt->execute([$id]);
$row = $stmt->fetch();
echo json_encode($row ?: ["error" => "未找到"]);
break;
case "POST /products": // 创建
$data = json_decode(file_get_contents("php://input"), true);
$stmt = $pdo->prepare("INSERT INTO products (name, price) VALUES (?,?)");
$stmt->execute([$data["name"], $data["price"]]);
http_response_code(201);
echo json_encode(["id" => $pdo->lastInsertId()]);
break;
case "PUT /products/$id": // 更新
$data = json_decode(file_get_contents("php://input"), true);
$stmt = $pdo->prepare("UPDATE products SET name=?, price=? WHERE id=?");
$stmt->execute([$data["name"], $data["price"], $id]);
echo json_encode(["ok" => $stmt->rowCount() > 0]);
break;
case "DELETE /products/$id": // 删除
$stmt = $pdo->prepare("DELETE FROM products WHERE id=?");
$stmt->execute([$id]);
echo json_encode(["deleted" => $stmt->rowCount() > 0]);
break;
default:
http_response_code(404);
echo json_encode(["error" => "路由不存在"]);
}
?>PHP PCRE
PHP PCRE 正则表达式:
<?php
// 匹配
$pattern = "/^1[3-9]\d{9}$/";
$phone = "13800138000";
if (preg_match($pattern, $phone)) {
echo "手机号合法";
}
// 提取(捕获组)
preg_match("/(\d{4})-(\d{2})-(\d{2})/",
"日期: 2026-08-12", $matches);
print_r($matches); // [0]=完整 [1]=2026 [2]=08 [3]=12
// 全局匹配
preg_match_all("/\d+/", "a1b22c333", $nums);
print_r($nums[0]); // [1, 22, 333]
// 替换
echo preg_replace("/\s+/", " ", "多 个 空格"); // 多个 空格
// 分割
$parts = preg_split("/[,-]/", "a,b-c");
print_r($parts); // [a, b, c]
// 常用模式
// /^\w+$/ 字母数字下划线
// /^[a-zA-Z]+$/ 纯字母
// /^[\u4e00-\u9fa5]+$/u 纯中文(u 修饰符)
// /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ 邮箱
// /^https?:\/\// http/https 开头
// /\d{6}/ 6 位数字
?>u 修饰符;正则复杂时先在线测试再上线。PHP 可用的函数
PHP 可用的函数:内置函数体系概览:
| 分类 | 示例函数 |
|---|---|
| 字符串 | strlen、str_replace、substr、explode |
| 数组 | array_map、array_filter、array_merge |
| 数学 | abs、round、max、rand |
| 日期 | date、strtotime、DateTime |
| 文件 | file_get_contents、fopen、scandir |
| 数据库 | PDO、mysqli、sqlite |
| 网络 | curl、file_get_contents(URL) |
| JSON/序列化 | json_encode、serialize |
| 变量 | is_array、isset、empty、var_dump |
| 输出 | echo、print_r、printf |
<?php
// 函数信息查询
// 1. 查看某个函数是否可用
echo function_exists("array_map") ? "可用" : "不可用";
// 2. 获取函数帮助(CLI)
// php -r "echo phpversion();"
// 3. 列出已加载扩展
print_r(get_loaded_extensions());
// 4. 查看函数所属扩展
$ref = new ReflectionFunction("str_replace");
echo $ref->getExtensionName(); // Core
// 5. 判断函数调用耗时(微基准)
$start = microtime(true);
for ($i = 0; $i < 100000; $i++) in_array($i, [1,2,3]);
echo (microtime(true) - $start) . " 秒";
?>php.net/manual 的函数索引。PHP Zip File 函数
PHP Zip File 函数:ZipArchive 常用方法:
<?php
$zip = new ZipArchive();
// 打开/创建
$zip->open("test.zip", ZipArchive::CREATE | ZipArchive::OVERWRITE);
// 常用方法
$zip->addFile("a.txt"); // 添加文件
$zip->addFile("b.jpg", "img/b.jpg"); // 指定目录
$zip->addFromString("c.txt", "文本内容"); // 字符串添加
$zip->addEmptyDir("empty_dir"); // 空目录
// 属性
$zip->numFiles; // 文件数
$zip->status; // 状态码
$zip->filename; // 压缩包路径
// 解压操作
$zip->extractTo("out/"); // 全部解压
$zip->extractTo("out/", ["a.txt"]); // 指定文件
// 读取
$content = $zip->getFromName("c.txt"); // 读取内容
$stat = $zip->statName("a.txt"); // 文件信息
echo $stat["size"];
// 删除
$zip->deleteName("a.txt"); // 按名删除
$zip->deleteIndex(0); // 按索引删除
// 重命名
$zip->renameName("c.txt", "d.txt");
// 关闭(必须!)
$zip->close();
?>close(),否则文件损坏。