前言
涵盖 PHP 零基础入门到企业级开发核心知识点,包含基础语法、面向对象、文件操作、异常处理、MySQL 操作、表单处理、MVC 架构、Session/Cookie、API 开发、主流框架使用十大模块。
环境:phpStudy、VSCode
第一章 PHP 基础语法(核心入门)
1.1 PHP 基础概述
PHP 是超文本预处理器,开源服务器端脚本语言,主要用于 Web 开发,可嵌入 HTML 中运行,文件后缀为.php,所有代码执行于服务器端。
基础代码结构:
php
<?php
// PHP单行注释
/*
多行注释
*/
echo 'Hello PHP'; // 输出语句
?>
1.2 变量
1.2.1 变量规则
- 变量以 $ 符号开头
- 首字母不能是数字,只能是字母、下划线
- 区分大小写,
$name和$Name是两个变量 - 变量无需声明类型,自动适配数据类型
1.2.2 变量类型与可变变量
php
<?php
$name = '张三';
$age = 20;
// 可变变量:将字符串变量的值,作为新的变量名
$str = 'name';
echo $$str; // 等价于 $name,输出 张三
?>
1.3 数据类型
PHP 共 8 种数据类型,分为标量、复合、特殊类型。
1.3.1 标量类型/基本数据类型(4 种)
- 字符串 (string):文本数据,单双引号区别:双引号可解析变量,单引号纯文本
- 整型 (int):整数
- 浮点型 (float):小数
- 布尔型 (bool):true/false
1.3.2 复合类型/引用数据类型(2 种)
- 数组 (array):有序 / 无序键值对集合
- 对象 (object):面向对象实例
1.3.3 特殊类型(2 种)
- null:空值
- resource:资源类型(文件、数据库连接)
1.4 运算符
PHP 运算符用于执行变量与值之间的运算,共分为算术、赋值、比较、逻辑、三元等大类,以下为开发高频运算符的用法与实战案例。
1.4.1 算术运算符
用于数值计算,包含基础运算与自增自减运算。
| 运算符 | 说明 |
|---|---|
+ |
加法 |
- |
减法 |
* |
乘法 |
/ |
除法 |
% |
取余(模运算) |
++ |
自增 1 |
-- |
自减 1 |
代码案例:
php
<?php
$a = 10;
$b = 3;
// 基础算术运算
echo '加法:'.($a + $b).'<br/>'; // 输出13
echo '减法:'.($a - $b).'<br/>'; // 输出7
echo '乘法:'.($a * $b).'<br/>'; // 输出30
echo '除法:'.($a / $b).'<br/>'; // 输出3.333...
echo '取余:'.($a % $b).'<br/>'; // 输出1
// 自增自减:前置与后置的核心区别
$i = 5;
echo '后置自增:'.$i++.'<br/>'; // 先输出5,执行后$i变为6
echo '自增后的值:'.$i.'<br/>'; // 输出6
$j = 5;
echo '前置自增:'.++$j.'<br/>'; // 先自增为6,再输出6
?>
1.4.2 赋值运算符
用于给变量赋值,支持运算与赋值合并,简化代码。
| 运算符 | 说明 | 等价写法 |
|---|---|---|
= |
基础赋值 | $a = 10 |
+= |
加后赋值 | $a += $b 等价于 $a = $a + $b |
-= |
减后赋值 | $a -= $b 等价于 $a = $a - $b |
.= |
字符串拼接后赋值 | $a .= $b 等价于 $a = $a . $b |
代码案例:
php
<?php
$num = 10;
$num += 5;
echo $num; // 输出15
$str = 'Hello';
$str .= ' PHP'; // 拼接字符串
echo $str; // 输出Hello PHP
?>
1.4.3 比较运算符
用于判断两个值的大小、相等关系,返回布尔值true/false,是条件判断的核心。
| 运算符 | 说明 |
|---|---|
== |
值相等(自动类型转换后比较) |
=== |
全等(值 + 数据类型都相等) |
!= |
值不相等 |
!== |
不全等 |
>、<、>=、<= |
大小比较 |
高频考点:== 与 === 的核心区别
==只比较值,会自动转换数据类型;===同时比较值和类型,判断更严谨,企业开发优先使用===。
代码案例:
php
<?php
$a = 10;
$b = '10';
// == 只比较值,字符串自动转为数字
var_dump($a == $b); // bool(true)
// === 同时比较值+类型,类型不同直接不相等
var_dump($a === $b); // bool(false)
var_dump($a > 5); // bool(true)
?>
1.4.4 逻辑运算符
用于组合多个条件判断,实现复杂条件逻辑,自带短路特性可提升性能。
| 运算符 | 说明 |
|---|---|
&&(逻辑与) |
所有条件都为 true,结果才为 true;短路特性:前面条件为 false,后面代码不执行 |
| ` | |
!(逻辑非) |
取反,true 变 false,false 变 true |
代码案例(短路特性演示):
php
<?php
$a = 5;
// &&短路:前面条件为false,后面的$a++不会执行
if($a > 10 && $a++){
echo '条件成立';
}
echo $a; // 输出5,证明后面的自增未执行
// ||短路:前面条件为true,后面的$a++不会执行
if($a > 0 || $a++){
echo '条件成立';
}
echo $a; // 还是5,证明后面的自增未执行
?>
1.4.5 三元运算符
简化if-else的写法,适合简单的二分支判断。 语法:条件 ? 成立结果 : 不成立结果
php
<?php
$age = 20;
// 基础用法
$status = $age >= 18 ? '成年' : '未成年';
echo $status; // 成年
// 嵌套用法(不推荐多层嵌套,影响可读性)
$score = 85;
$level = $score >= 90 ? '优秀' : ($score >= 60 ? '及格' : '不及格');
echo $level; // 及格
?>
1.5 流程控制语句
1.5.1 条件语句
if / else if / else
php
<?php
$score = 85;
if($score >= 90){
// 分数大于等于90,判定优秀
echo '优秀';
}elseif($score >= 60){
// 分数60-89之间,判定及格
echo '及格';
}else{
// 分数小于60,判定不及格
echo '不及格';
}
?>
switch 分支语句
php
<?php
$week = 1;
// 根据变量值匹配对应分支
switch($week){
case 1: echo '周一'; break; // 匹配成功,输出并终止分支
case 2: echo '周二'; break;
default: echo '未知星期'; // 所有分支不匹配时默认执行
}
?>
1.5.2 循环语句
PHP 常用四种循环:for、while、do-while、foreach,四种循环场景不同
1.for 循环(固定次数循环)
适用场景:已知循环次数的场景,结构:初始化条件;循环条件;迭代更新
php
<?php
// 循环输出1-5数字
for($i=1;$i<=5;$i++){
echo '当前数字:'.$i.'<br/>';
}
?>
2.while 循环(先判断、后执行)
适用场景:未知循环次数,先判断条件,条件成立再执行循环体,可能一次都不执行
php
<?php
$i = 1; // 初始化变量
while($i<=3){ // 循环条件:小于等于3执行
echo 'while循环:'.$i.'<br/>';
$i++; // 自增迭代,避免死循环
}
?>
3.do-while 循环(先执行、后判断)
核心特点:无论条件是否成立,循环体至少执行一次,和 while 最大区别就是执行顺序不同。
php
<?php
$i = 5;
// 先执行一次代码,再判断条件
do{
echo 'do-while循环:'.$i.'<br/>';
$i++;
}while($i<=3); // 条件不成立,循环终止
// 运行结果:只会输出一次,完美体现至少执行一次的特性
?>
4.foreach 循环(数组 / 对象循环)
核心作用 :专门用于遍历数组、对象,无需手动定义循环条件,自动适配数组长度,是 PHP 开发最常用的循环。 两种语法格式:仅取值、键值同步获取
php
<?php
// 1.基础用法:只获取数组值
$indexArr = [10,20,30,40];
foreach($indexArr as $val){
echo '数组值:'.$val.'<br/>';
}
// 2.进阶用法:同时获取键名和键值(开发高频)
$assocArr = ['name'=>'张三','age'=>20,'sex'=>'男'];
foreach($assocArr as $key=>$val){
echo '键名:'.$key.',对应值:'.$val.'<br/>';
}
// 3.遍历多维数组(实战常用)
$multiArr = [
['id'=>1,'title'=>'PHP基础'],
['id'=>2,'title'=>'面向对象']
];
foreach($multiArr as $item){
echo 'ID:'.$item['id'].',标题:'.$item['title'].'<br/>';
}
?>
1.6 字符串操作
PHP 内置大量字符串处理函数,开发高频使用。
php
<?php
$str = 'php Study';
// 1.strlen():获取字符串长度(字节数,中文占3字节)
echo '字符串长度:'.strlen($str).'<br/>';
// 2.strtolower():字符串全部转小写
echo '全小写:'.strtolower($str).'<br/>';
// 3.strtoupper():字符串全部转大写
echo '全大写:'.strtoupper($str).'<br/>';
// 4.substr():字符串截取(参数:字符串、起始位置、截取长度)
echo '截取前3位:'.substr($str,0,3).'<br/>';
// 5.str_replace():字符串替换(参数:被替换内容、替换内容、原字符串)
echo '字符替换:'.str_replace('php','Java',$str).'<br/>';
// 6.explode():字符串分割为数组(按指定分隔符切割)
echo '字符串分割:';print_r(explode(' ',$str));echo '<br/>';
// 7.trim():去除首尾空格(表单校验高频用法)
$testStr = ' 测试空格 ';
echo '去除空格后:'.trim($testStr).'<br/>';
// 8.strpos():查找字符位置
echo 'php所在位置:'.strpos($str,'php');
?>
1.7 数组操作
数组是 PHP 开发核心数据结构,可存储任意类型数据,分为索引数组、关联数组、多维数组,下面分层详解定义、特性、实战案例、使用场景。
1.7.1 数组分类、特性与完整案例
1. 索引数组(默认数字下标)
键名为系统自动分配的数字(从 0 开始递增),适用于有序列表数据,如商品列表、序号数据。
php
<?php
// 方式1:简化定义
$indexArr1 = ['苹果','香蕉','橙子'];
// 方式2:标准定义
$indexArr2 = array(1,2,3,4,5);
// 主动指定数字下标(自定义索引)
$indexArr3 = [2=>'张三',3=>'李四',5=>'王五'];
// 访问索引数组数据
echo $indexArr1[0]; // 输出:苹果
echo $indexArr3[2]; // 输出:张三
// 遍历索引数组
foreach($indexArr1 as $val){
echo '水果:'.$val.'<br/>';
}
?>
2. 关联数组(自定义字符串下标)
手动设置字符串键名,键值一一对应,适用于键值明确的数据,如用户信息、配置参数、表单数据,是开发最常用的数组。
php
<?php
// 定义用户信息关联数组
$user = [
'username' => '张三',
'age' => 22,
'sex' => '男',
'phone' => '13800138000'
];
// 单独获取指定字段数据
echo '用户名:'.$user['username'].'<br/>';
echo '年龄:'.$user['age'].'<br/>';
// 遍历关联数组
foreach($user as $key=>$val){
echo $key.':'.$val.'<br/>';
}
?>
3. 多维数组(数组嵌套数组)
一维数组中嵌套多个数组,用于存储批量结构化数据,如博客列表、用户列表、商品列表,后端接口返回数据基本都是多维数组。
php
<?php
// 二维数组:博客列表数据
$blogList = [
['id'=>1,'title'=>'PHP基础语法','view'=>100],
['id'=>2,'title'=>'面向对象实战','view'=>200],
['id'=>3,'title'=>'MVC框架开发','view'=>300]
];
// 访问单条数据
echo '第一篇博客标题:'.$blogList[0]['title'];
// 遍历多维数组(实战通用写法)
foreach($blogList as $blog){
echo 'ID:'.$blog['id'].',标题:'.$blog['title'].',浏览量:'.$blog['view'].'<br/>';
}
?>
1.7.2 数组常用函数
php
<?php
$arr = [1,2,3,4,5];
// 1.count():获取数组长度/元素个数,常用于判断数组是否为空
echo '数组元素个数:'.count($arr).'<br/>';
// 2.array_push():数组尾部追加元素,适用于动态新增数据
array_push($arr,6,7);
echo '追加后数组:';print_r($arr);echo '<br/>';
// 3.array_pop():删除数组最后一个元素,无需指定下标
array_pop($arr);
echo '删除尾部元素后:';print_r($arr);echo '<br/>';
// 4.array_merge():合并多个数组,常用于数据拼接
$arr2 = [8,9,10];
$newArr = array_merge($arr,$arr2);
echo '数组合并结果:';print_r($newArr);echo '<br/>';
// 5.in_array():判断元素是否存在数组中,返回布尔值,常用于数据校验
$isExist = in_array(3,$arr);
echo '3是否存在数组中:';var_dump($isExist);echo '<br/>';
// 6.array_keys():获取数组所有键名
echo '数组所有键名:';print_r(array_keys($arr));echo '<br/>';
// 7.array_values():获取数组所有值(重置索引)
echo '数组所有值:';print_r(array_values($arr));echo '<br/>';
// 8.unset():删除指定数组元素,可删除单个/多个元素
unset($arr[0]);
echo '删除第一个元素后:';print_r($arr);
?>
1.7.3 数组核心知识点总结与拓展
- 数组选型建议:
- 有序列表、序号数据使用索引数组
- 键值明确的配置、用户信息使用关联数组
- 批量结构化数据、数据库结果集使用二维数组
- 开发注意事项:
- 索引数组默认从 0 开始,未指定下标时自动递增
- 关联数组键名重复时,后面的值会覆盖前面的值
- 数组可混合存储任意类型数据,不强制类型统一
- 拓展提示:
- 实际开发中数据库查询结果均为二维关联数组,是最常用的数组形式
- 数组操作函数优先使用 PHP 内置函数,性能远高于手动循环处理
第二章 PHP 面向对象编程(OOP)
2.1 面向对象核心概念
面向对象是一种编程思想,将事务抽象为类 ,通过对象调用属性和方法,核心特性:封装、继承、多态。
2.2 类与对象
- 类:模板,抽象的概念
- 对象:类的实例,具体的实体
- 属性:类的变量(特征)
- 方法:类的函数(行为)
php
<?php
// 定义人类模板(类)
class Person{
// 成员属性(类的特征):公共属性,外部可访问
public $name;
public $age;
// 成员方法(类的行为)
public function say(){
// $this 代表当前对象,调用自身属性
echo '我是'.$this->name.',今年'.$this->age.'岁';
}
}
// 实例化对象(根据模板创建具体实体)
$p = new Person();
// 给对象属性赋值
$p->name = '李四';
$p->age = 22;
// 调用对象方法
$p->say();
?>
2.3 访问修饰符(封装特性核心)
访问修饰符用于控制类中属性、方法的访问权限,是面向对象封装特性的核心实现,共 3 种权限级别。
| 修饰符 | 权限范围 | 本类内访问 | 子类内访问 | 类外部访问 |
|---|---|---|---|---|
public(公共) |
完全公开 | ✅ | ✅ | ✅ |
protected(受保护) |
本类 + 子类可访问 | ✅ | ✅ | ❌ |
private(私有) |
仅本类可访问 | ✅ | ❌ | ❌ |
代码案例:权限边界演示
php
<?php
// 父类
class Person{
public $name = '张三'; // 公共属性
protected $age = 22; // 受保护属性
private $password = '123'; // 私有属性
// 测试:本类内访问
public function testInner(){
echo $this->name; // ✅ 正常访问
echo $this->age; // ✅ 正常访问
echo $this->password; // ✅ 正常访问
}
}
// 子类
class Student extends Person{
// 测试:子类内访问
public function testSub(){
echo $this->name; // ✅ 公共属性可访问
echo $this->age; // ✅ 受保护属性可访问
echo $this->password; // ❌ 报错,私有属性子类不可访问
}
}
// 测试:类外部访问
$p = new Person();
echo $p->name; // ✅ 公共属性外部可访问
echo $p->age; // ❌ 报错,受保护属性外部不可访问
echo $p->password; // ❌ 报错,私有属性外部不可访问
?>
开发规范:属性尽量设置为
protected/private,通过public方法对外提供操作入口,实现封装,避免外部直接修改属性导致数据异常。
2.4 构造方法与析构方法
php
<?php
class Person{
// 构造方法:实例化对象时【自动执行】,用于初始化属性
public function __construct($name,$age){
$this->name = $name;
$this->age = $age;
echo '对象初始化成功<br/>';
}
// 析构方法:对象销毁、程序结束时【自动执行】,用于释放资源
public function __destruct(){
echo '对象销毁,资源释放完毕';
}
}
// 实例化时直接传参,无需单独赋值
$p = new Person('王五',25);
?>
2.5 继承
使用 extends 实现继承,子类复用父类属性和方法,支持单继承。
php
<?php
// 父类:通用动物类(公共属性/方法)
class Animal{
// 公共方法:所有动物都具备进食行为
public function eat(){
echo '动物会进食<br/>';
}
}
// 子类:狗狗类,继承Animal父类(复用父类代码,拓展自身功能)
class Dog extends Animal{
// 子类独有方法
public function bark(){
echo '狗狗会汪汪叫';
}
}
// 实例化子类对象
$dog = new Dog();
$dog->eat(); // 继承父类方法,直接复用
$dog->bark(); // 调用子类自有方法
?>
2.6 接口(interface)
接口是方法的规范,只定义方法名,不实现代码,使用 implements 实现接口,一个类可实现多个接口。
php
<?php
// 定义接口:行为规范(只定义方法名,不写实现逻辑)
interface Study{
// 接口方法必须是公共、无实现体
public function learn();
}
// 类实现接口:必须重写接口中所有方法
class Student implements Study{
// 实现接口规范的方法
public function learn(){
echo '学生正在认真学习';
}
}
// 实例化调用
$s = new Student();
$s->learn();
?>
2.7 静态属性与静态方法
static 修饰,无需实例化对象,直接类名调用。
php
<?php
class Test{
// 静态属性:属于类,不属于对象,全局共享
public static $num = 10;
// 静态方法:无需实例化对象,直接类名调用
public static function show(){
echo '这是静态方法';
}
}
// 静态属性调用:类名::静态属性
echo Test::$num;
// 静态方法调用:类名::静态方法
Test::show();
?>
第三章 PHP 本地文件操作
3.1 文件权限说明
Linux 系统文件权限分为读 ®、写 (w)、执行 (x),权限数字:r=4、w=2、x=1。
- 0777:最高权限,所有用户可读可写可执行
- 0644:文件默认权限,所有者读写,其他人只读
- 0755:文件夹默认权限
3.2 创建文件 / 文件夹
php
<?php
// 1.file_put_contents:快速创建空文件,文件不存在则创建,存在则清空内容
file_put_contents('test.txt','');
// 2.mkdir():创建文件夹
// 参数1:文件夹路径 参数2:权限 参数3:递归创建(支持多级目录)
mkdir('upload/images',0755,true);
?>
3.2.1 file_put_contents 与 fopen 的区别与选型
PHP 操作文件有两套主流方案,并非fopen不好,而是不同场景适用不同工具,简单场景file_put_contents开发效率更高。
表格
| 对比维度 | file_put_contents | fopen 系列函数 |
|---|---|---|
| 代码复杂度 | 一行代码完成读写,简洁高效 | 需要手动打开、操作、关闭句柄,步骤多 |
| 功能范围 | 仅支持整体写入、读取文件 | 支持逐行读写、指针定位、文件锁定等精细操作 |
| 性能 | 小文件性能高,大文件一次性读取内存占用大 | 支持分段操作,大文件性能更优,内存占用低 |
| 适用场景 | 小文件读写、日志写入、配置文件修改 | 大文件处理、逐行读取、自定义指针操作 |
为什么简单场景优先用 file_put_contents?
- 代码极简,无需手动管理文件句柄,避免忘记
fclose导致资源泄漏 - 内置
FILE_APPEND、LOCK_EX等常量,一行实现追加、文件独占锁定 - 90% 的业务场景都是小文件整体读写,
file_put_contents完全满足需求
补充:fopen 系列函数完整用法 fopen是底层文件操作函数,返回文件句柄,配合fwrite、fgets、fclose实现精细操作。
php
<?php
// 1.打开文件,模式:w写入、r读取、a追加
$fp = fopen('test.txt', 'w');
if(!$fp){
die('文件打开失败');
}
// 2.写入文件内容
fwrite($fp, 'fopen写入的内容');
// 3.必须手动关闭文件句柄,否则会造成资源泄漏
fclose($fp);
// 逐行读取文件演示
$fp = fopen('test.txt', 'r');
// 循环读取,直到文件末尾
while(!feof($fp)){
echo fgets($fp).'<br/>'; // 读取一行内容
}
fclose($fp);
?>
常用文件打开模式说明:
r:只读模式,文件指针在文件开头w:写入模式,清空文件内容,文件不存在则创建a:追加模式,文件指针在末尾,文件不存在则创建
3.3 文件写入 / 追加数据
php
<?php
// 覆盖写入:文件存在则清空原有内容,写入新内容
file_put_contents('test.txt','第一次写入内容');
// 追加写入:FILE_APPEND 常量,保留原有内容,在末尾新增
file_put_contents('test.txt','<br/>追加新内容',FILE_APPEND);
?>
3.4 读取文件内容
php
<?php
// file_get_contents:读取文件全部内容,适用于文本文件
// 无需打开关闭文件句柄,简洁高效
echo file_get_contents('test.txt');
?>
3.5 删除文件 / 文件夹
php
<?php
// unlink():删除文件,只能删除文件,不能删除文件夹
unlink('test.txt');
// rmdir():删除空文件夹,只能删除空目录
rmdir('upload');
?>
3.6 文件常用判断函数
php
<?php
is_file('test.txt'); // 判断路径是否为【文件】
is_dir('upload'); // 判断路径是否为【文件夹】
file_exists('test.txt'); // 判断文件/文件夹是否存在
filesize('test.txt'); // 获取文件大小(单位:字节)
?>
3.7 文件上传(Web 开发核心功能)
PHP 通过$_FILES全局变量接收上传文件,配合move_uploaded_file函数将服务器临时文件移动到目标目录,实现文件上传。
3.7.1 完整单文件上传案例
1. 前端上传表单(upload.html)
html
<!DOCTYPE html>
<html>
<body>
<!-- 必须设置enctype="multipart/form-data",否则无法传输文件 -->
<form method="post" action="upload.php" enctype="multipart/form-data">
选择文件:<input type="file" name="img">
<button type="submit">上传</button>
</form>
</body>
</html>
2. 后端上传处理(upload.php)
php
<?php
// 1.判断是否存在上传错误
if($_FILES['img']['error'] > 0){
die('上传错误,错误码:'.$_FILES['img']['error']);
}
// 2.配置上传规则
$allowType = ['image/jpeg','image/png','image/gif']; // 允许的文件MIME类型
$maxSize = 2 * 1024 * 1024; // 最大文件大小 2MB
$uploadDir = './upload/'; // 文件保存目录
// 3.校验文件类型
if(!in_array($_FILES['img']['type'], $allowType)){
die('文件类型不合法,仅支持jpg/png/gif格式');
}
// 4.校验文件大小
if($_FILES['img']['size'] > $maxSize){
die('文件过大,不能超过2MB');
}
// 5.生成唯一文件名(防止重名覆盖)
$ext = pathinfo($_FILES['img']['name'], PATHINFO_EXTENSION); // 获取文件后缀
$fileName = time().rand(1000,9999).'.'.$ext; // 时间戳+随机数命名
$savePath = $uploadDir.$fileName;
// 6.自动创建上传目录(不存在则递归创建)
if(!is_dir($uploadDir)){
mkdir($uploadDir, 0755, true);
}
// 7.移动临时文件到目标目录
if(move_uploaded_file($_FILES['img']['tmp_name'], $savePath)){
echo '上传成功,文件保存路径:'.$savePath;
}else{
echo '上传失败,请检查目录权限';
}
?>
3.7.2 $_FILES 参数说明
| 键名 | 说明 |
|---|---|
name |
上传文件的原始文件名 |
type |
文件的 MIME 类型(浏览器提供,可伪造,仅作初步校验) |
tmp_name |
服务器上的临时文件路径 |
error |
上传错误码,0 代表无错误 |
size |
文件大小,单位字节 |
第四章 PHP 异常处理
4.1 异常处理核心语法
try:捕获异常代码、throw:抛出异常、catch:处理异常、finally:最终执行(可选)
4.2 基础异常案例
php
<?php
try{
// 可能出现错误、需要捕获异常的代码
$num = 0;
if($num == 0){
// 手动抛出异常,主动触发错误
throw new Exception('除数不能为0,参数非法');
}
$res = 10 / $num;
}catch(Exception $e){
// 捕获try中抛出的异常,自定义处理逻辑
echo '错误信息:'.$e->getMessage(); // 获取错误描述
echo '<br/>错误行号:'.$e->getLine(); // 获取错误代码行号
}finally{
// 无论是否报错,最终都会执行的代码,常用于释放资源
echo '<br/>代码执行完毕,资源已回收';
}
?>
4.3 自定义异常类
php
<?php
// 自定义异常类,继承系统Exception异常类
class MyException extends Exception{
// 自定义错误输出方法
public function errorMsg(){
return '【自定义提示】错误:'.$this->getMessage();
}
}
try{
// 主动抛出自定义异常
throw new MyException('请求参数不能为空');
}catch(MyException $e){
// 捕获自定义异常,调用自定义方法输出信息
echo $e->errorMsg();
}
?>
第五章 PHP MySQLi 数据库操作
5.1 数据库连接
php
<?php
// 数据库配置参数(根据自己的环境修改)
$host = 'localhost'; // 数据库地址
$user = 'root'; // 数据库用户名
$pwd = 'root'; // 数据库密码
$dbname = 'test_db'; // 要连接的数据库名
// 创建数据库连接
$conn = mysqli_connect($host,$user,$pwd,$dbname);
// 校验连接是否成功
if(!$conn){
die('数据库连接失败:'.mysqli_connect_error());
}
// 设置数据库字符集,防止中文乱码
mysqli_set_charset($conn,'utf8');
echo '数据库连接成功';
?>
5.2 增删改查(CRUD)
5.2.1 新增数据
php
<?php
// 编写新增SQL语句
$sql = "insert into user(name,age) values('小明',20)";
// 执行SQL语句
$res = mysqli_query($conn,$sql);
// 判断执行结果
if($res){
// mysqli_insert_id():获取新增数据的自增ID
echo '新增成功,用户ID:'.mysqli_insert_id($conn);
}else{
// mysqli_error():获取数据库错误信息
echo '新增失败:'.mysqli_error($conn);
}
?>
5.2.2 查询数据
php
<?php
// 查询所有用户数据
$sql = "select * from user";
// 执行查询语句
$res = mysqli_query($conn,$sql);
// 循环遍历结果集,读取所有数据
// mysqli_fetch_assoc():逐条获取关联数组格式数据
while($row = mysqli_fetch_assoc($res)){
echo '用户名:'.$row['name'].',年龄:'.$row['age'].'<br/>';
}
?>
5.2.3 修改数据
php
<?php
// 条件更新数据:指定用户名修改年龄
$sql = "update user set age=21 where name='小明'";
// 执行更新语句
if(mysqli_query($conn,$sql)){
echo '数据修改成功';
}
?>
5.2.4 删除数据
php
<?php
// 条件删除数据:删除指定ID用户
$sql = "delete from user where id=1";
// 执行删除语句
if(mysqli_query($conn,$sql)){
echo '数据删除成功';
}
// 关闭数据库连接,释放资源
mysqli_close($conn);
?>
5.2.5 实战案例:用户登录功能
结合表单接收、数据库查询、会话管理,实现完整用户登录流程,是 Web 开发最核心的实战场景。
前置准备:创建用户表
CREATE TABLE `user` (
`id` int PRIMARY KEY AUTO_INCREMENT,
`username` varchar(50) NOT NULL UNIQUE COMMENT '用户名',
`password` varchar(32) NOT NULL COMMENT '密码(md5加密存储)'
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 插入测试账号
INSERT INTO `user`(`username`,`password`) VALUES ('admin',md5('123456'));
完整登录代码(login.php)
php+HTML
<?php
// 开启session,用于保存登录状态
session_start();
// 连接数据库
$conn = mysqli_connect('localhost','root','root','test_db');
mysqli_set_charset($conn,'utf8');
// 处理表单提交
if($_POST){
// 接收并过滤数据
$username = trim($_POST['username']);
$password = trim($_POST['password']);
// 非空校验
if(empty($username) || empty($password)){
die('<script>alert("用户名和密码不能为空");history.back()</script>');
}
// 转义SQL特殊字符,防止SQL注入攻击
$username = mysqli_real_escape_string($conn, $username);
// 查询用户
$sql = "select * from user where username = '$username' limit 1";
$res = mysqli_query($conn,$sql);
$user = mysqli_fetch_assoc($res);
// 校验账号密码
if($user && $user['password'] == md5($password)){
// 登录成功,将用户信息存入session
$_SESSION['user'] = $user;
echo '<script>alert("登录成功");location.href="index.php"</script>';
}else{
echo '<script>alert("用户名或密码错误");history.back()</script>';
}
}
?>
<!DOCTYPE html>
<html>
<body>
<form method="post" action="">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
<button type="submit">登录</button>
</form>
</body>
</html>
安全说明:使用
mysqli_real_escape_string转义 SQL 特殊字符,防止 SQL 注入攻击;密码使用 md5 加密存储,实际生产项目推荐使用更强的password_hash加密。
5.3 数据库事务
事务特性:ACID(原子性、一致性、隔离性、持久性),用于多 SQL 批量执行,要么全部成功,要么全部回滚。
php
<?php
// 关闭数据库自动提交,开启事务模式
mysqli_autocommit($conn,false);
try{
// 多条关联SQL语句,必须同时成功
$sql1 = "update user set age=22 where id=2";
$sql2 = "update user set age=23 where id=3";
mysqli_query($conn,$sql1);
mysqli_query($conn,$sql2);
// 所有语句执行无误,手动提交事务,数据永久生效
mysqli_commit($conn);
echo '事务执行成功,数据已更新';
}catch(Exception $e){
// 任意语句出错,回滚事务,所有操作撤销
mysqli_rollback($conn);
echo '事务执行失败,数据已回滚:'.$e->getMessage();
}
?>
第六章 PHP 表单接收与处理
6.1 表单提交方式
- GET:参数拼接在 URL,数据量小、不安全
- POST:参数请求体传递,数据量大、相对安全
6.2 完整表单案例
php+HTML
<!DOCTYPE html>
<html>
<body>
<!--
form表单:action为空表示提交到当前页面
method="post":POST提交方式,安全、无URL参数
-->
<form method="post" action="">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="pwd"><br/>
<button type="submit">提交</button>
</form>
<?php
// 判断是否有POST提交数据
if($_POST){
// 1.trim()去除首尾空格,避免空空格提交
$username = trim($_POST['username']);
$pwd = trim($_POST['pwd']);
// 2.基础非空校验
if(empty($username) || empty($pwd)){
echo '<p style="color:red">用户名密码不能为空</p>';
}else{
// 3.htmlspecialchars转义HTML,防止XSS攻击
echo '<p style="color:green">提交成功,用户名:'.htmlspecialchars($username).'</p>';
}
}
?>
</body>
</html>
6.3 表单安全处理(企业级必备)
表单接收用户输入数据,存在空提交、空格干扰、XSS 脚本攻击、SQL 注入等风险,必须做安全过滤处理。
表格
| 处理函数 | 作用 | 应用场景 |
|---|---|---|
trim() |
去除数据首尾空格 | 防止用户输入纯空格提交表单 |
empty() |
判断数据是否为空 | 拦截无效空数据 |
htmlspecialchars() |
转义 HTML、JS 特殊字符 | 杜绝 XSS 跨站脚本攻击 |
mysqli_real_escape_string() |
转义 SQL 特殊字符 | 防止 SQL 注入攻击 |
| 正则表达式 | 格式校验 | 手机号、邮箱、账号等格式合法性校验 |
6.3.1 XSS 攻击原理与防护详解
XSS(跨站脚本攻击)是 Web 最常见的安全漏洞,攻击者通过在表单、URL 中注入恶意 HTML/JS 代码,当用户访问页面时,恶意代码会在用户浏览器中执行,可实现盗取 Cookie、篡改页面、跳转钓鱼网站等危害。
1. XSS 攻击演示案例 不安全的写法(直接输出原生用户输入):
php
<?php
// 直接接收用户输入并输出,存在XSS漏洞
$content = $_GET['content'] ?? '';
echo $content; // 未做任何转义,恶意代码会被浏览器执行
?>
攻击测试: 访问 URL:test.php?content=<script>alert('XSS攻击成功')</script> 页面会弹出弹窗,证明恶意 JS 代码被成功执行;真实攻击场景中,攻击者可以通过该漏洞盗取用户登录态、伪造操作。
2. XSS 防护方案 使用htmlspecialchars()函数转义 HTML 特殊字符,将<、>、"等特殊字符转为 HTML 实体,浏览器只会将其作为普通文本渲染,不会解析为代码。
安全的写法:
php
<?php
$content = $_GET['content'] ?? '';
// 转义HTML特殊字符,彻底杜绝XSS
echo htmlspecialchars($content);
?>
防护效果: 同样的攻击 URL,恶意代码会被转义为<script>alert('XSS攻击成功')</script>,浏览器直接显示文本内容,不会执行 JS。
3. 核心防护原则
- 所有用户输入、数据库读取的数据,输出到 HTML 页面时,必须经过
htmlspecialchars转义 - 永远不要信任用户提交的数据,所有输入都必须经过校验、过滤、转义
第七章 MVC 架构与博客系统实战
7.1 MVC 与三层架构区别
7.1.1 核心维度对比表
| 对比维度 | 三层架构 | MVC 架构 |
|---|---|---|
| 核心分层 | 表现层(UI)业务层(BLL/Service)数据访问层(DAL/DAO) | 模型(Model)视图(View)控制器(Controller) |
| 执行流程 | 请求 → 表现层接收 → 业务层处理逻辑 → 数据层操作数据库 → 逐层返回结果 | 请求 → 控制器接收请求 → 调用模型处理数据 → 控制器加载视图 → 视图渲染返回 |
| 核心定位 | 代码功能分层思想,按代码职责划分层级,解决业务与数据耦合问题 | 项目架构模式,按请求处理流程划分角色,解决页面展示与业务逻辑耦合问题 |
| 层级关系 | 上下层强依赖,上层只能调用下层 | 控制器居中调度,模型与视图不直接交互,松耦合 |
| 适用场景 | 后端业务逻辑复杂的系统、后端服务项目 | Web 交互多的项目、前后端结合的网站系统 |
7.1.2 架构流程图(直观对比)
三层架构:垂直分层,自上而下调用
┌─────────────┐
│ 表现层 UI │ 接收用户请求、渲染页面、展示数据
└──────┬──────┘
↓
┌─────────────┐
│ 业务层 BLL │ 处理业务规则、逻辑计算、流程控制
└──────┬──────┘
↓
┌─────────────┐
│ 数据层 DAL │ 纯数据库增删改查,无业务逻辑
└─────────────┘
MVC 架构:请求驱动,控制器统一调度
用户请求
↓
┌─────────────────────┐
│ 控制器 Controller │ 参数校验、请求分发、调度模型和视图
└───┬─────────────┬───┘
↓ ↑
┌───────┐ ┌───────┐
│ Model │ │ View │
│ 模型 │ →→→ │ 视图 │
│数据处理│ │页面渲染│
└───────┘ └───────┘
7.1.3 总结与实际应用
- 两者并非对立关系:企业级项目通常组合使用,MVC 作为整体项目架构,Model 层内部再划分业务层、数据层(三层架构)
- 划分角度不同:三层是按功能职责 划分,MVC 是按请求处理流程划分
- 解决的问题不同:三层解决业务逻辑与数据操作耦合,MVC 解决前端页面与后端逻辑耦合
7.2 自定义简易 MVC 框架
7.2.1 框架目录结构
mvc/
├── index.php 入口文件
├── Controller/ 控制器目录
│ └── IndexController.php
├── Model/ 模型目录
│ └── UserModel.php
├── View/ 视图目录
│ └── index.html
└── Common/ 公共函数目录
7.2.2 入口文件 index.php(路由分发)
php
<?php
// 简易路由解析:接收URL参数,定位控制器和方法
// c=控制器名 a=方法名
$c = $_GET['c'] ?? 'Index'; // 默认Index控制器
$a = $_GET['a'] ?? 'index'; // 默认index方法
// 拼接控制器类名和文件路径
$controllerName = $c.'Controller';
$controllerFile = './Controller/'.$controllerName.'.php';
// 判断控制器文件是否存在
if(file_exists($controllerFile)){
require_once $controllerFile; // 引入控制器文件
$controller = new $controllerName(); // 实例化控制器
$controller->$a(); // 动态调用对应方法
}else{
die('错误:控制器文件不存在,URL路由错误');
}
?>
7.2.3 控制器 IndexController.php
php
<?php
// 首页控制器
class IndexController{
// 默认首页方法
public function index(){
// 加载前端视图页面
require_once './View/index.html';
}
// 测试路由访问方法
public function test(){
echo 'MVC控制器访问成功,自定义方法执行完毕';
}
}
?>
7.2.4 视图 index.html
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>简易MVC框架</title>
</head>
<body>
<h1>PHP自定义MVC框架运行成功</h1>
</body>
</html>
7.3 基于 MVC 实现极简博客系统
7.3.1 功能模块
博客列表、博客新增、博客详情、博客删除
7.3.2 数据库表 blog
CREATE TABLE `blog` (
`id` int PRIMARY KEY AUTO_INCREMENT,
`title` varchar(100) NOT NULL COMMENT '博客标题',
`content` text NOT NULL COMMENT '博客内容',
`create_time` int NOT NULL COMMENT '发布时间'
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
7.3.3 博客模型 BlogModel.php
php
<?php
// 博客模型:专注数据层,负责数据库增删改查
class BlogModel{
private $conn; // 数据库连接资源
// 构造方法:初始化数据库连接
public function __construct(){
$this->conn = mysqli_connect('localhost','root','root','test_db');
mysqli_set_charset($this->conn,'utf8');
}
// 获取所有博客列表
public function getList(){
$sql = "select * from blog order by create_time desc";
$res = mysqli_query($this->conn,$sql);
$list = [];
// 循环组装二维数组数据
while($row = mysqli_fetch_assoc($res)){
$list[] = $row;
}
return $list;
}
// 新增博客数据
public function add($title,$content){
$time = time(); // 获取当前时间戳
$sql = "insert into blog(title,content,create_time) values('$title','$content',$time)";
return mysqli_query($this->conn,$sql);
}
// 删除指定博客
public function del($id){
$sql = "delete from blog where id=$id";
return mysqli_query($this->conn,$sql);
}
}
?>
7.3.4 博客控制器 BlogController.php
php
<?php
// 博客控制器:专注业务逻辑,调度模型和视图
require_once './Model/BlogModel.php';
class BlogController{
// 博客列表页
public function index(){
$blog = new BlogModel(); // 实例化模型
$list = $blog->getList(); // 调用模型获取数据
require_once './View/blog_list.html'; // 加载视图展示数据
}
// 新增博客(展示表单+提交数据)
public function add(){
// 判断是否为表单提交
if($_POST){
$title = trim($_POST['title']);
$content = trim($_POST['content']);
// 简单数据校验
if(empty($title) || empty($content)){
echo '标题和内容不能为空!';
exit;
}
$blog = new BlogModel();
// 调用模型新增数据
if($blog->add($title,$content)){
// 新增成功,跳转列表页
header('location:index.php?c=Blog&a=index');
}else{
echo '博客发布失败';
}
}
// 加载新增表单页面
require_once './View/blog_add.html';
}
// 删除博客
public function del(){
$id = intval($_GET['id']); // 强制转为数字,防止SQL注入
$blog = new BlogModel();
$blog->del($id);
// 删除后跳转列表页
header('location:index.php?c=Blog&a=index');
}
}
?>
7.3.5 博客视图(列表 + 新增页面)
1. 博客列表视图 View/blog_list.html
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>博客列表</title>
</head>
<body>
<h2>博客文章列表</h2>
<a href="index.php?c=Blog&a=add">新增博客</a>
<ul>
<?php foreach($list as $v): ?>
<li>
<h3><?php echo $v['title']; ?></h3>
<p><?php echo $v['content']; ?></p>
<a href="index.php?c=Blog&a=del&id=<?php echo $v['id']; ?>" onclick="return confirm('确定删除?')">删除</a>
</li>
<?php endforeach; ?>
</ul>
</body>
</html>
2. 博客新增视图 View/blog_add.html
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>新增博客</title>
</head>
<body>
<h2>发布新博客</h2>
<form method="post" action="">
<p>标题:<input type="text" name="title" placeholder="请输入博客标题"></p>
<p>内容:<textarea name="content" rows="5" cols="30" placeholder="请输入博客内容"></textarea></p>
<p><button type="submit">提交发布</button></p>
</form>
<a href="index.php?c=Blog&a=index">返回列表</a>
</body>
</html>
第八章 Session 与 Cookie
8.1 Cookie(客户端存储)
存储在浏览器本地,非安全、存储量小、可长期保存。
8.1.1 Cookie 操作
php
<?php
// 1.setcookie(键名,值,过期时间)
// time()+3600 表示1小时后过期,时间戳单位:秒
setcookie('username','张三',time()+3600);
// 2.获取Cookie数据,判断是否存在
$username = $_COOKIE['username'] ?? '';
echo '读取Cookie用户名:'.$username;
// 3.删除Cookie:设置过期时间为过去时间,浏览器自动清除
setcookie('username','',time()-100);
?>
8.2 Session(服务端存储)
存储在服务器,安全、用于用户登录验证、会话保持,依赖 Cookie。
8.2.1 Session 操作
php
<?php
// 开启session(必须顶部第一行)
session_start();
// 赋值
$_SESSION['user'] = '管理员';
// 获取
echo $_SESSION['user'];
// 删除单个session
unset($_SESSION['user']);
// 清空所有session
session_destroy();
?>
8.3 Cookie 与 Session 区别
- 存储位置:Cookie 客户端、Session 服务端
- 安全性:Session 更高
- 生命周期:Cookie 可永久、Session 默认浏览器关闭失效
- 存储大小:Cookie 有限制,Session 无限制
第九章 PHP API 接口开发
9.1 API 开发规范
前后端分离核心,统一返回JSON 格式,定义状态码、提示信息、数据。
9.2 通用 API 接口模板(企业级封装)
前后端分离项目必备标准化接口模板,统一返回格式、状态码规范,兼容绝大多数业务场景,自带中文不乱码、错误捕获、数据封装能力,可直接复用至实战项目。
php
<?php
// 设置响应头,指定返回JSON格式、UTF8编码
header('Content-Type:application/json;charset=utf-8');
/**
* 统一API返回封装函数
* @param int $code 状态码 200成功 400参数错误 401未授权 500服务器错误
* @param string $msg 提示信息
* @param array $data 返回数据
* @return void
*/
function returnJson($code=200,$msg='请求成功',$data=[]){
// 转为JSON并禁止Unicode转义,中文正常显示
exit(json_encode([
'code'=>$code,
'msg'=>$msg,
'data'=>$data
],JSON_UNESCAPED_UNICODE));
}
// 模拟接口业务:查询博客列表
$list = [
['id'=>1,'title'=>'PHP基础开发','author'=>'老师'],
['id'=>2,'title'=>'MVC框架实战','author'=>'学员']
];
// 调用封装方法返回数据
returnJson(200,'博客数据获取成功',$list);
?>
9.3 接口跨域完整解决方案
前后端分离项目中,前端域名、端口与后端不一致会触发跨域报错,以下为 PHP 后端通用跨域处理代码,支持 OPTIONS 预请求、全域名访问、常用请求方式放行,适配浏览器所有请求场景。
php
<?php
// 解决前端跨域请求问题(前后端分离项目必备完整代码)
// 放行所有来源域名,生产环境可指定具体域名,提升安全性
header('Access-Control-Allow-Origin:*');
// 允许前端常用请求方式
header('Access-Control-Allow-Methods:GET,POST,PUT,DELETE,OPTIONS');
// 允许前端自定义请求头(Token、自定义参数必备)
header('Access-Control-Allow-Headers:Content-Type,Token,Authorization,X-Requested-With');
// 缓存预请求,减少重复校验,提升接口性能
header('Access-Control-Max-Age:86400');
// 拦截OPTIONS预请求,直接返回成功,无需进入业务逻辑
if($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
exit('ok');
}
?>
9.4 接口 Token 鉴权(完整实战落地)
Token 鉴权是接口安全核心机制,替代传统 Session,适配分布式、前后端分离、小程序 / APP 请求场景。核心流程:用户登录校验成功生成唯一 Token → 前端存储 Token → 每次接口请求携带 Token → 后端统一校验合法性,拦截非法请求。
以下为可直接落地的完整代码,包含登录生成 Token、全局鉴权中间件、统一返回格式:
php+HTML
<?php
header('Content-Type:application/json;charset=utf-8');
// 解决跨域
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Methods:GET,POST,OPTIONS');
header('Access-Control-Allow-Headers:Content-Type,Token');
if($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
exit('ok');
}
session_start();
/**
* 统一API返回封装
*/
function returnJson($code=200,$msg='成功',$data=[]){
exit(json_encode([
'code'=>$code,
'msg'=>$msg,
'data'=>$data
],JSON_UNESCAPED_UNICODE));
}
/**
* Token鉴权中间件
* 除登录接口外,所有接口先执行鉴权
*/
function checkToken(){
// 获取请求头中的Token
$headers = getallheaders();
$token = $headers['Token'] ?? '';
// 校验Token有效性
if(empty($token) || $token !== ($_SESSION['api_token'] ?? '')){
returnJson(401,'未授权,请先登录');
}
}
// 登录接口:生成Token
function login(){
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
// 模拟账号校验,实际项目查询数据库
if($username === 'admin' && $password === '123456'){
// 生成唯一Token
$token = md5($username.time().rand(1000,9999));
$_SESSION['api_token'] = $token;
returnJson(200,'登录成功',['token'=>$token]);
}else{
returnJson(400,'账号密码错误');
}
}
// 需要鉴权的业务接口
function getUserInfo(){
checkToken(); // 执行鉴权
// 模拟返回用户数据
returnJson(200,'获取成功',[
'id'=>1,
'username'=>'admin',
'role'=>'管理员'
]);
}
?>
第十章 PHP 主流框架实战落地
10.1 主流框架介绍
- ThinkPHP:国产轻量框架、上手简单、中小企业首选
- Laravel:国外优雅框架、功能强大、适合大型项目
- Yii:高性能框架,适合高并发项目
10.2 ThinkPHP6 安装与使用(详细步骤)
10.2.1 环境要求
PHP7.1+、Composer 依赖管理工具、开启 PDO 扩展
10.2.2 安装命令
全局安装 Composer 后,在项目根目录执行:
composer create-project topthink/think tp6
10.2.3 启动项目
进入项目目录,执行命令启动内置开发服务器:
php think run
默认访问地址:http://127.0.0.1:8000
10.2.4 目录核心结构
app:应用目录(控制器、模型、视图)config:配置文件(数据库、路由等)public:网站根目录、入口文件route:路由定义目录
10.2.5 控制器创建与访问
控制器文件路径:app/index/controller/Index.php
php
<?php
// 命名空间:区分不同模块同名类,框架核心特性
namespace app\index\controller;
class Index
{
// 首页访问方法
public function index()
{
return 'ThinkPHP6 框架运行成功!';
}
}
?>
10.2.6 数据库配置与查询
- 修改
config/database.php配置数据库账号、密码、数据库名、端口。 - 数据库查询实战案例:
php
<?php
namespace app\index\controller;
// 引入数据库操作类
use think\Db;
class Blog
{
// 查询博客列表
public function list()
{
// ORM查询blog表所有数据
$list = Db::name('blog')->select();
// 以JSON格式返回接口数据
return json($list);
}
}
?>
10.3 Laravel 框架快速使用
Laravel 主打优雅的 ORM 数据库模型、路由管理、中间件、权限验证、队列、缓存等企业级高级功能,代码规范度极高,适合大型商业项目、高复杂度前后端分离项目开发,是国外主流 PHP 框架。
10.3.1 环境与安装前置要求
PHP7.3+、Composer、开启 fileinfo 扩展、匹配系统权限,适配 Windows/Linux/Mac 系统
10.3.2 完整安装启动命令
# 1.通过Composer安装Laravel最新版本框架
composer create-project laravel/laravel laravel-demo
# 2.进入项目根目录
cd laravel-demo
# 3.启动Laravel内置开发服务器
php artisan serve
# 4.默认访问地址:http://127.0.0.1:8000
10.3.3 基础控制器实战案例
控制器文件路径:app/Http/Controllers/IndexController.php
php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
// 首页控制器
class IndexController extends Controller
{
// 首页访问方法
public function index()
{
return 'Laravel 框架运行成功!企业级项目开发就绪';
}
// 测试接口方法
public function test()
{
return response()->json([
'code' => 200,
'msg' => 'Laravel接口请求成功',
'data' => ['version' => '最新版']
],200,[],JSON_UNESCAPED_UNICODE);
}
}
?>
10.3.4 数据库配置与 ORM 查询案例
修改项目根目录.env文件,配置数据库信息:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=test_db
DB_USERNAME=root
DB_PASSWORD=root
数据库查询实战案例:
php
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
class BlogController extends Controller
{
// 查询博客列表数据
public function list()
{
// ORM原生查询,简洁高效
$list = DB::table('blog')->orderBy('create_time','desc')->get();
return response()->json([
'code' => 200,
'msg' => '数据查询成功',
'data' => $list
],200,[],JSON_UNESCAPED_UNICODE);
}
}
?>