PHP Web 开发完整教程
目录
-
第一部分:基础入门
(图片来源网络,侵删)- 什么是 PHP?
- 环境搭建:LAMP/LNMP 栈
- 你的第一个 PHP 程序:
Hello, World! - PHP 基本语法
- 变量与数据类型
- 运算符
- 流程控制 (if/else, for, while, switch)
- 函数
- 数组
- 超全局变量 (
$_GET,$_POST,$_SERVER等)
-
第二部分:Web 开发核心
- 表单处理 (
GETvsPOST) - 处理用户输入与安全性初步 (XSS, SQL 注入简介)
- 会话管理 (
$_SESSION) - Cookie (
$_COOKIE) - 文件上传
- 错误与异常处理
- 表单处理 (
-
第三部分:数据库交互
- 数据库简介 (MySQL/MariaDB)
- SQL 基础 (增删改查)
- 使用 PHP 原生 MySQLi 扩展
- 使用 PDO (PHP Data Objects) - 推荐
- 预处理语句 - 防止 SQL 注入的关键
-
第四部分:进阶与面向对象
- 面向对象编程基础
- 命名空间
- 自动加载
- Composer - PHP 的依赖管理工具
- 常用第三方库介绍
-
第五部分:现代 PHP 开发
(图片来源网络,侵删)- MVC 设计模式
- 框架简介 (Laravel, Symfony)
- API 开发基础
- RESTful API 设计原则
-
第六部分:部署与最佳实践
- 项目结构
- 版本控制
- 安全最佳实践
- 部署到生产环境
- 持续学习与资源
第一部分:基础入门
什么是 PHP?
PHP (PHP: Hypertext Preprocessor) 是一种广泛使用的服务器端脚本语言,特别适合 Web 开发,它可以嵌入 HTML 中,也可以用于命令行脚本和桌面应用程序,其最大的特点是开源、免费、跨平台,并且拥有庞大的社区和丰富的框架生态。
环境搭建:LAMP/LNMP 栈
要在本地开发和运行 PHP,你需要一个本地服务器环境,最经典和方便的方案是使用集成环境包。
- LAMP: Linux (操作系统) + Apache (Web 服务器) + MySQL (数据库) + PHP
- LNMP: Linux + Nginx (Web 服务器) + MySQL + PHP
推荐工具:

- XAMPP (Windows, macOS, Linux): 最流行,包含 Apache, MySQL, PHP 和 Perl,一键安装,开箱即用。
- MAMP (macOS, Windows): 与 XAMPP 类似,界面更友好,适合 macOS 用户。
- Docker: 更专业和灵活的方案,通过容器化部署环境。
安装步骤 (以 XAMPP 为例):
- 从 XAMPP 官网 下载适合你操作系统的版本。
- 运行安装程序,按照提示完成安装。
- 安装完成后,启动 XAMPP Control Panel。
- 点击 "Apache" 和 "MySQL" 模块的 "Start" 按钮。
- 你的本地服务器已经运行了,将你的 PHP 项目文件放在 XAMPP 的
htdocs(或www) 文件夹中。 - 在浏览器中访问
http://localhost/你的项目文件夹名即可看到你的网站。
你的第一个 PHP 程序:Hello, World!
创建一个名为 index.php 的文件,放在 htdocs 文件夹下,内容如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">我的第一个 PHP 页面</title>
</head>
<body>
<h1>欢迎来到 PHP 世界!</h1>
<p>
<?php
// 这是 PHP 代码块
echo "Hello, World!"; // echo 是一个输出函数
?>
</p>
</body>
</html>
在浏览器中访问 http://localhost/index.php,你将看到 "Hello, World!" 被正确地渲染在 HTML 页面上。
关键点:
- PHP 代码必须被
<?php ... ?>标签包围。 - 每条 PHP 语句以分号
PHP 基本语法
- 注释:
- 单行注释:
// 这是单行注释 - 多行注释:
/* 这是多行注释 */
- 单行注释:
- 输出:
echo: 可以输出一个或多个字符串,速度稍快。print: 只能输出一个字符串,并始终返回 1。
变量与数据类型
PHP 是一种弱类型语言,你不需要在声明变量时指定其类型。
-
变量声明: 以 符号开头,后跟变量名。
$name = "张三"; $age = 25; $isStudent = true; $grades = [90, 88, 95];
-
主要数据类型:
string: 字符串,如"你好"integer: 整数,如123float/double: 浮点数,如14boolean: 布尔值,true或falsearray: 数组,如$gradesobject: 对象NULL: 表示没有值
运算符
- 算术运算符: , , , , (取模)
- 赋值运算符: , , ,
- 比较运算符: (等于), (绝对等于,值和类型都相等), ,
<>, ,>,<,>=,<= - 逻辑运算符:
and,or,xor, ,&&,
$x = 10;
$y = 20;
// 算术
$sum = $x + $y; // 30
// 比较
if ($x < $y) {
echo "x 小于 y";
}
// 逻辑
$age = 20;
if ($age > 18 && $age < 60) {
echo "成年人";
}
流程控制
-
if...else...elseif:$score = 85; if ($score >= 90) { echo "优秀"; } elseif ($score >= 60) { echo "及格"; } else { echo "不及格"; } -
for循环:for ($i = 0; $i < 5; $i++) { echo "数字是: $i <br>"; } -
while循环:$count = 0; while ($count < 5) { echo "Count: $count <br>"; $count++; } -
switch语句:$day = "Monday"; switch ($day) { case "Monday": echo "新的一周开始了"; break; case "Friday": echo "周末快到了"; break; default: echo "普通的一天"; }
函数
使用 function 关键字定义函数。
// 定义一个函数
function greet($name) {
return "你好, " . $name . "!";
}
// 调用函数
$message = greet("李四");
echo $message; // 输出: 你好, 李四!
数组
PHP 中的数组非常强大,可以同时作为关联数组和索引数组使用。
-
索引数组:
$fruits = ["苹果", "香蕉", "橙子"]; echo $fruits[0]; // 输出: 苹果
-
关联数组 (键值对):
$person = [ "name" => "王五", "age" => 30, "city" => "北京" ]; echo $person["name"]; // 输出: 王五 -
遍历数组:
// foreach 遍历关联数组 foreach ($person as $key => $value) { echo "$key: $value <br>"; } // foreach 遍历索引数组 foreach ($fruits as $fruit) { echo "$fruit <br>"; }
超全局变量
PHP 提供了一组特殊的变量,它们可以在脚本的任何地方访问。
$_GET: 通过 URL 参数传递的数据。$_POST: 通过 HTTP POST 请求提交的数据(如表单)。$_REQUEST:$_GET,$_POST,$_COOKIE的集合。$_SERVER: 包含服务器和执行环境信息的数组,如$_SERVER['PHP_SELF'],$_SERVER['SERVER_NAME']。$_SESSION: 用于在多个页面之间保存用户会话数据。$_COOKIE: 用于在用户计算机上存储数据。
第二部分:Web 开发核心
表单处理
创建一个 HTML 表单 (form.html):
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">登录表单</title>
</head>
<body>
<form action="login.php" method="POST">
<label for="username">用户名:</label>
<input type="text" id="username" name="username">
<br>
<label for="password">密码:</label>
<input type="password" id="password" name="password">
<br>
<button type="submit">登录</button>
</form>
</body>
</html>
创建一个 PHP 文件 (login.php) 来处理表单提交:
<?php
// 检查是否是通过 POST 方法提交的
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 获取表单数据
$username = $_POST['username'];
$password = $_POST['password'];
// 简单的验证逻辑 (实际应用中应该查询数据库)
if ($username == "admin" && $password == "123456") {
echo "登录成功!欢迎, " . htmlspecialchars($username);
} else {
echo "用户名或密码错误!";
}
} else {
// 如果不是 POST 请求,则重定向或显示错误
echo "非法访问!";
}
?>
GET vs POST:
GET: 数据通过 URL 传递,数据量小,不安全,可被缓存。search.php?q=php教程。POST: 数据在 HTTP 请求体中传递,数据量大,相对安全(但仍需加密),不可缓存,适用于提交表单、上传文件等。
处理用户输入与安全性初步
直接输出用户输入是极其危险的,会导致 XSS (跨站脚本攻击),必须对输出进行转义。
使用 htmlspecialchars() 函数可以将特殊字符转换为 HTML 实体。
$user_input = '<script>alert("你被攻击了!");</script>';
echo $user_input; // 危险!会执行脚本
echo htmlspecialchars($user_input); // 安全!会显示为文本: <script>...</script>
SQL 注入 是另一个巨大的安全威胁,当用户输入被直接拼接到 SQL 查询语句中时,攻击者可以执行恶意的 SQL 代码。解决方法永远是使用预处理语句,我们将在第三部分详细介绍。
会话管理 ($_SESSION)
$_SESSION 用于在用户访问网站的不同页面之间保持状态,例如登录状态。
使用步骤:
- 在页面最顶部启动会话:
session_start(); - 存储数据:
$_SESSION['username'] = "张三"; - 读取数据:
echo "欢迎回来, " . $_SESSION['username']; - 销毁会话:
session_destroy();(通常用于用户登出时)
示例 (session_start.php):
<?php // 必须在任何输出之前调用 session_start(); // 设置会话变量 $_SESSION['logged_in'] = true; $_SESSION['user_id'] = 123; echo "会话已设置。"; echo "<a href='session_read.php'>点击查看会话数据</a>"; ?>
示例 (session_read.php):
<?php
session_start();
if (isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === true) {
echo "用户ID: " . $_SESSION['user_id'] . "<br>";
echo "您已登录。";
echo "<a href='session_destroy.php'>点击登出</a>";
} else {
echo "您尚未登录。";
}
?>
Cookie ($_COOKIE)
Cookie 将数据存储在客户端(用户的浏览器),它比 Session 更持久,但安全性更低,因为用户可以查看和修改它。
设置 Cookie:
setcookie("username", "访客", time() + 86400 * 30, "/"); // 设置一个名为 username 的 cookie,有效期30天
echo "Cookie 已设置。";
读取 Cookie:
if (isset($_COOKIE['username'])) {
echo "欢迎回来, " . $_COOKIE['username'];
} else {
echo "欢迎新访客。";
}
文件上传
HTML 表单需要设置 enctype="multipart/form-data"。
HTML 表单 (upload.html):
<form action="upload.php" method="POST" enctype="multipart/form-data">
<input type="file" name="myfile">
<button type="submit">上传文件</button>
</form>
PHP 处理 (upload.php):
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 检查是否有文件上传
if (isset($_FILES['myfile']) && $_FILES['myfile']['error'] == 0) {
$fileTmpPath = $_FILES['myfile']['tmp_name'];
$fileName = $_FILES['myfile']['name'];
$fileSize = $_FILES['myfile']['size'];
$fileType = $_FILES['myfile']['type'];
// 定义上传目录
$uploadFileDir = './uploads/';
if (!is_dir($uploadFileDir)) {
mkdir($uploadFileDir, 0777, true);
}
$dest_path = $uploadFileDir . $fileName;
// 移动上传的文件
if (move_uploaded_file($fileTmpPath, $dest_path)) {
echo "文件 '$fileName' 上传成功!";
} else {
echo "文件上传失败。";
}
} else {
echo "没有文件被上传或上传出错。";
}
}
?>
第三部分:数据库交互
数据库简介 (MySQL/MariaDB)
MySQL 是世界上最流行的开源关系型数据库管理系统,MariaDB 是 MySQL 的一个分支,在很多 Linux 发行版中作为默认数据库。
你需要先在你的 XAMPP 环境中启动 MySQL 服务,并创建一个数据库。
SQL 基础
- 创建数据库:
CREATE DATABASE my_app;
- 选择数据库:
USE my_app;
- 创建表:
CREATE TABLE users ( id INT(11) AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(100) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); - 插入数据:
INSERT INTO users (username, email, password) VALUES ('testuser', 'test@example.com', 'hashed_password'); - 查询数据:
SELECT * FROM users; SELECT id, username FROM users WHERE id = 1;
- 更新数据:
UPDATE users SET email = 'new_email@example.com' WHERE id = 1;
- 删除数据:
DELETE FROM users WHERE id = 1;
使用 PHP 原生 MySQLi 扩展
MySQLi 是 "MySQL Improved" 的缩写,是 PHP 官方推荐的 MySQL 操作扩展。
连接数据库:
<?php
$servername = "localhost";
$username = "root"; // 默认用户名
$password = ""; // 默认密码 (XAMPP中通常为空)
$dbname = "my_app";
// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);
// 检查连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
echo "连接成功!";
?>
查询数据 (不安全,有 SQL 注入风险):
$sql = "SELECT id, username FROM users";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// 输出数据
while($row = $result->fetch_assoc()) {
echo "ID: " . $row["id"]. " - Name: " . $row["username"]. "<br>";
}
} else {
echo "0 结果";
}
$conn->close();
使用 PDO (PHP Data Objects) - 推荐
PDO 是一个更通用、更强大的数据库访问层,它支持多种数据库(MySQL, PostgreSQL, SQLite 等),并且是防止 SQL 注入的首选方式。
连接数据库:
<?php
$host = 'localhost';
$db = 'my_app';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 抛出异常
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 默认关联数组
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
echo "PDO 连接成功!";
?>
预处理语句 - 防止 SQL 注入的关键
预处理语句将 SQL 语句和数据分开处理,从而杜绝了 SQL 注入的可能。
插入数据示例 (安全):
// SQL 语句,使用 ? 作为占位符
$sql = "INSERT INTO users (username, email, password) VALUES (?, ?, ?)";
$stmt = $pdo->prepare($sql);
// 绑定参数并执行
$username = "new_user";
$email = "user@example.com";
$password_hash = password_hash("secret_password", PASSWORD_DEFAULT); // 始终对密码进行哈希!
$stmt->execute([$username, $email, $password_hash]);
echo "新记录插入成功!ID: " . $pdo->lastInsertId();
查询数据示例 (安全):
$sql = "SELECT * FROM users WHERE id = ?";
$stmt = $pdo->prepare($sql);
$user_id = 1;
$stmt->execute([$user_id]);
$user = $stmt->fetch(); // 获取一行
if ($user) {
echo "找到用户: " . $user['username'];
} else {
echo "未找到 ID 为 $user_id 的用户。}
第四部分:进阶与面向对象
面向对象编程基础
-
类 和 对象:
- 类: 是创建对象的蓝图,定义了属性和方法。
- 对象: 是类的实例。
class User { // 属性 public $name; public $email; // 构造函数 public function __construct($name, $email) { $this->name = $name; $this->email = $email; } // 方法 public function getProfile() { return "姓名: " . $this->name . ", 邮箱: " . $this->email; } } // 创建对象 (实例化) $user1 = new User("张三", "zhangsan@example.com"); echo $user1->getProfile(); // 输出: 姓名: 张三, 邮箱: zhangsan@example.com -
封装: 使用
public,protected,private访问修饰符来控制对类成员的访问。 -
继承: 使用
extends关键字,子类可以继承父类的属性和方法。 -
多态: 通过接口 和抽象类 实现。
命名空间
命名空间用于解决在大型项目中类名、函数名、常量名冲突的问题,它就像文件系统中的目录。
// 文件: MyProject/Database/Connection.php
namespace MyProject\Database;
class Connection {
public function connect() {
// ...
}
}
// 文件: index.php
require 'MyProject/Database/Connection.php';
use MyProject\Database\Connection as DB;
$conn = new DB();
$conn->connect();
自动加载
自动加载使得你可以在实例化一个类时,PHP 自动包含对应的类文件,而无需手动 require 或 include。
// 注册一个自动加载函数
spl_autoload_register(function ($class_name) {
// 将命名空间的 \ 替换为目录分隔符 /
$file = __DIR__ . '/' . str_replace('\\', '/', $class_name) . '.php';
if (file_exists($file)) {
require_once $file;
}
});
// 现在可以直接使用 MyProject\Database\Connection,PHP 会自动加载
$conn = new MyProject\Database\Connection();
Composer - PHP 的依赖管理工具
Composer 是 PHP 的包管理器,类似于 Node.js 的 npm 或 Python 的 pip,它允许你声明项目所依赖的库,并自动为你安装和管理它们。
安装 Composer: 从 getcomposer.org 下载并安装。
使用 Composer:
-
在项目根目录创建
composer.json文件:{ "require": { "monolog/monolog": "^2.0" } } -
在命令行中运行
composer install,Composer 会创建一个vendor目录,并下载所需的库。 -
在你的 PHP 文件顶部引入
autoload.php:require 'vendor/autoload.php'; // 现在可以使用 monolog 了 use Monolog\Logger; use Monolog\Handler\StreamHandler; $log = new Logger('name'); $log->pushHandler(new StreamHandler('app.log', Logger::WARNING)); $log->warning('This is a warning');
第五部分:现代 PHP 开发
MVC 设计模式
MVC (Model-View-Controller) 是一种软件设计模式,将应用程序分为三个部分,使代码更易于管理和维护。
- Model (模型): 负责数据和业务逻辑,与数据库交互,处理数据。
- View (视图): 负责展示,通常是 HTML 模板,显示从 Model 获取的数据。
- Controller (控制器): 负责协调,接收用户输入(来自 View),调用 Model 处理数据,然后选择一个 View 来显示结果。
简单流程: 用户请求 -> Controller -> Model (获取/保存数据) -> Controller -> View (渲染 HTML) -> 用户。
框架简介
框架提供了一套结构化的 MVC 架构和大量内置功能(如路由、ORM、认证等),让你可以专注于业务逻辑,而不是重复造轮子。
- Laravel: 目前最受欢迎的 PHP 框架,语法优雅,功能强大,社区活跃。强烈推荐初学者学习。
- Symfony: 一个成熟、灵活的框架,被许多大型企业级项目使用。
- CodeIgniter: 一个轻量级、快速的框架,适合小型项目。
API 开发基础
API (Application Programming Interface) 允许不同的应用程序之间进行通信,Web API 通常通过 HTTP 协议以 JSON 或 XML 格式传输数据。
一个简单的 RESTful API 示例 (使用原生 PHP 和 PDO):
// api.php?user_id=1
header("Content-Type: application/json; charset=UTF-8");
require_once 'db.php'; // 包含 PDO 连接代码
$method = $_SERVER['REQUEST_METHOD'];
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$uri_parts = explode('/', $uri);
// 简单的路由
if ($uri_parts[count($uri_parts) - 2] === 'users' && isset($_GET['id'])) {
$user_id = $_GET['id'];
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$user = $stmt->fetch();
if ($user) {
echo json_encode($user);
} else {
http_response_code(404);
echo json_encode(["message" => "User not found"]);
}
} else {
http_response_code(404);
echo json_encode(["message" => "Endpoint not found"]);
}
RESTful API 设计原则
- 使用 HTTP 方法:
GET: 获取资源。POST: 创建新资源。PUT/PATCH: 更新资源。DELETE: 删除资源。
- 使用名词表示资源: 如
/users,/products。 - 使用状态码: 如
200 OK,201 Created,404 Not Found,500 Internal Server Error。
第六部分:部署与最佳实践
项目结构
一个典型的现代 PHP 项目结构:
/my-project
|-- /src # 源代码
| |-- /Controllers
| |-- /Models
| `-- /Views
|-- /public # Web 服务器指向的根目录
| |-- index.php
| |-- .htaccess (Apache)
| `-- /assets (css, js, images)
|-- /vendor # Composer 依赖
|-- /config # 配置文件
|-- /logs # 日志文件
|-- composer.json
|-- composer.lock
`-- README.md
版本控制
使用 Git 来管理你的代码版本,将你的代码推送到 GitHub 或 GitLab 等平台。
- 基本命令:
git init,git add,git commit,git push,git pull。
安全最佳实践
- 永远不要相信用户输入: 始终对输入进行验证和过滤。
- 永远不要直接输出用户输入: 始终使用
htmlspecialchars()转义输出。 - 永远不要使用拼接 SQL 查询: 始终使用 PDO 或 MySQLi 的预处理语句。
- 对密码进行哈希: 使用
password_hash()和password_verify()。 - 使用 HTTPS: 在生产环境中强制使用 HTTPS 加密通信。
- 关闭错误显示: 在生产环境中,设置
display_errors = Off在php.ini中,将错误记录到日志文件。 - 更新依赖: 定期使用
composer update更新你的库,以修复安全漏洞。
部署到生产环境
- 虚拟主机: 在你的服务器上为每个项目配置一个虚拟主机。
- 文件权限: 确保 Web 服务器(如
www-data用户)对你的项目文件有正确的读写权限。 - 环境配置: 使用环境变量(如
.env文件)来管理数据库密码、API 密钥等敏感信息,而不是硬编码在代码里。 - 构建工具: 使用 Vite 或 Webpack 等工具来处理前端资源。
持续学习与资源
- 官方文档: PHP.net 是最权威的资料。
- Laravel 学院: Laravel学院 提供高质量的 Laravel 和 PHP 教程。
- YouTube 频道: Traversy Media, The Net Ninja 等有非常棒的 PHP 和 Laravel 视频教程。
- 开源项目: 阅读优秀开源项目的源码是提高水平的最佳途径。
- 社区: Stack Overflow, Reddit 的 r/PHP 等社区可以帮你解决遇到的问题。
这份教程为你提供了一个从零开始学习 PHP Web 开发的完整路径,最重要的是动手实践,从创建简单的页面开始,逐步构建更复杂的项目,并不断学习和应用新的技术,祝你学习愉快!
