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 简介

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 与 JavaScript 不同:JS 在浏览器执行(前端),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 -v

macOS(Homebrew)

brew install php
php -v
✅ 建议
学习期推荐 XAMPP 或宝塔面板(自带 PHP 环境管理),快速启动无需手动配置。

PHP 语法

PHP 基础语法:脚本以 <?php 开始,以 ?> 结束(文件末尾可省略),语句以分号结尾:

<?php
// 单行注释
# 也是单行注释
/* 多行
   注释 */

// 输出
echo "Hello PHP<br>";
print "使用 print 输出";

// 变量以 $ 开头
$name = "小明";
echo $name;
?>
语法要点说明
大小写变量名区分大小写,函数名不区分
分号每条语句以 ; 结尾
注释//、#、/* */
标签 结束
⚠️ 注意
文件若只有 PHP 代码,建议省略结束标签 ?>,避免输出多余空白字符。

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 是最常用的输出语句:

区别echoprint
返回值无返回 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
?>
⚠️ 注意
双引号字符串会解析变量和转义符(\n、\t),单引号则原样输出,性能稍好。

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;
?>
✅ 建议
Heredoc 非常适合生成大段 HTML 模板;结束标识符必须顶格写,后面不能有空格。

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; ?>
?>
✅ 建议
在 HTML 模板中混编时,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;
?>
✅ 建议
PHP 8 的 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);           // 去重
?>
💡 提示
数组函数非常多(100+),按需查阅官方文档即可,不必死记。

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服务器与请求信息
$_GETURL 查询参数
$_POST表单 POST 数据
$_REQUESTGET + POST + Cookie
$_SESSION会话数据
$_COOKIECookie 数据
$_FILES文件上传信息
$_ENV环境变量
<?php
echo $_SERVER['REMOTE_ADDR'];  // 客户端 IP
echo $_SERVER['REQUEST_URI'];  // 请求路径
echo $_SERVER['HTTP_USER_AGENT'];  // 浏览器 UA
echo $_SERVER['REQUEST_METHOD'];  // GET / POST
?>
⚠️ 注意
$_GET/$_POST/$_REQUEST 是用户可控输入,使用前务必校验与过滤(防注入、防 XSS)。

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);
?>
✅ 建议
while 循环常用于不确定次数的场景(读文件、遍历数据库结果集)。

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登录、提交表单数据在请求体,安全、可传大内容
⚠️ 注意
涉及密码、订单等敏感数据一律用 POST,且必须配合 CSRF 防护。

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>
✅ 建议
HTML 端 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>
💡 提示
回显 value 时也要用 htmlspecialchars 防止 XSS;失败时保留用户已填内容,提升体验。

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>
⚠️ 注意
GET 参数是用户可控的:把 id 转成 (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
?>
💡 提示
数据库查询结果(PDO/mysqli fetchAll)通常就是二维数组,多维数组操作是 PHP 基本功。

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 文件上传

文件上传:

<?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"];
?>
⚠️ 注意
Cookie 存储在客户端,不要存放敏感信息;session_id 放 Cookie 也要设置 HttpOnly 防窃取。

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],
];
?>
✅ 建议
登录状态、购物车、验证码等"服务端状态"都用 Session;会话默认存文件,可配置为 Redis。

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;
?>
⚠️ 注意
邮件头注入(\r\n 拼接恶意头)是常见攻击,清洗换行符是底线。

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();
}
?>
✅ 建议
业务校验用自定义异常 + 多 catch 分支;Error(PHP 7+)与 Exception 分开处理。

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);
?>
✅ 建议
验证(VALIDATE)失败返回 false,清洗(SANITIZE)移除非法字符,两者结合使用。

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 记得加 JSON_UNESCAPED_UNICODE,避免 \uXXXX 转义。

PHP 7 新特性

PHP 7/8 新特性:

版本特性
7.0标量类型声明、太空船运算符 <=>、?? 空合并
7.1可空类型 ?int、void 返回类型
7.2object 类型、参数类型拓宽
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 8 性能比 PHP 7 提升显著(JIT),新项目建议直接上 PHP 8.x。

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());
}
?>
对比MySQLiPDO
支持的数据库仅 MySQLMySQL/PG/SQLite 等
预处理支持支持(推荐)
面向对象支持支持
✅ 建议
新项目一律用 PDO + 预处理语句,这是防 SQL 注入的最佳实践。

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;
?>
⚠️ 注意
数据库密码不要硬编码在页面中,建议放独立配置文件(如 config.php)并加入 .gitignore。

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 "数据表创建成功";
?>
💡 提示
生产环境表结构用 SQL 文件 + 迁移工具管理(如 Laravel Migration),而不是在 PHP 里建表。

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()
?>
⚠️ 注意
永远使用预处理语句 + 占位符拼接 SQL,绝不直接拼接用户输入(防注入)。

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();
?>
⚠️ 注意
LIKE 值中的 %、_ 需转义,否则通配符会被用户利用。

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();
?>
✅ 建议
排序字段来自用户输入时务必用白名单校验,防止 ORDER BY 注入。

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 "库存不足";
}
?>
⚠️ 注意
UPDATE 必须带 WHERE,否则全表更新!rowCount() 为 0 可能是值未变化而非失败。

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
?>
⚠️ 注意
DELETE 不可逆!重要数据建议软删除(加 deleted_at 字段),并做好备份。

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);
?>
💡 提示
ODBC 用于连接 SQL Server、Access 等非 MySQL 数据库;MySQL 场景优先用 PDO。

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);
?>
💡 提示
Expat 适合解析大文件(流式处理);小文件用 SimpleXML 更简单。

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");
?>
✅ 建议
DOM 把整棵树放内存,适合中小文件;大文件用 Expat 或 SimpleXML 迭代。

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();
?>
✅ 建议
SimpleXML 是 PHP 处理 XML 的首选:代码最少、最直观。

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 接收的数据同样需要校验与转义(防 XSS);跨域需配置 CORS。

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>";
}
?>
✅ 建议
生产环境建议返回 JSON 而非 HTML,前后端解耦更清晰。

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>';
?>
💡 提示
如今 JSON 已取代 XML 成为 AJAX 主流数据格式,XML 仅特定场景(如配置、RSS)使用。

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);
?>
✅ 建议
防抖(debounce)能大幅减少请求数;服务端加 LIMIT 与索引,保证响应速度。

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();
?>
✅ 建议
投票等写操作务必做防刷(IP/用户/时间窗口)与参数白名单。

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]
?>
💡 提示
array_map / array_filter / array_reduce 是函数式编程三件套,代码更简洁。

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 . " 天";
?>
✅ 建议
现代项目日期计算推荐 DateTime / Carbon 类,比日历函数更强大直观。

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);
}
?>
✅ 建议
抓取 HTTPS 站点若证书校验失败,可临时设置 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());
?>
💡 提示
PHP 8.1 起 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);
?>
⚠️ 注意
FTP 明文传输不安全,生产环境建议改用 SFTP(ssh2)或 FTPS。

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);
// 解析前调用,阻止外部实体读取本地文件
?>
⚠️ 注意
XXE 攻击可读取服务器文件!解析不可信 XML 前务必 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);
?>
💡 提示
MySQLi 也支持面向对象写法;与 PDO 相比仅支持 MySQL,但性能接近。

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 "有子元素";
?>
✅ 建议
SimpleXML 配合 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>");   // &lt;b&gt;...
addslashes("It's");     // It\'s
stripslashes("It\'s");

// 去除
trim(" hi "); ltrim(" hi"); rtrim("hi ");
?>
✅ 建议
字符串函数命名规律:str- 前缀 + 动词,按需查阅 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();
?>
💡 提示
选型原则:小文件 SimpleXML,大文件 XMLReader,需修改用 DOM。

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");
        }
    }
}
?>
✅ 建议
大文件压缩注意内存与超时;上传解压前先校验 ZipArchive 合法性与路径安全。

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
?>
⚠️ 注意
存储时间建议用 UTC(或时间戳),展示时再按用户时区转换,避免混乱。

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);
?>
💡 提示
GD 是 PHP 最常用的图像库;复杂图像处理可用 Imagick 扩展。

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" => "路由不存在"]);
}
?>
✅ 建议
生产项目推荐使用框架(Laravel/Slim/ThinkPHP)管理路由、中间件与参数校验,更安全规范。

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 内置 1000+ 函数,不必全记;遇到需求先查 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();
?>
💡 提示
所有 ZipArchive 操作完成后必须 close(),否则文件损坏。
第 1 / 87 节