背景
作为前端工程师,我一直想拓展后端能力。PHP 是最容易入门的服务端语言之一,语法和 JavaScript 相似,学习曲线平缓。用一个下午的时间,我从零学完了 PHP 基础,并进阶到前后端分离 API。
学习路径
1
| PHP 基础语法 → 表单处理 → PDO + MySQL → RESTful API → CORS → Token 认证 → MVC 分层
|
PHP 基础:和 JavaScript 的对比
| JS |
PHP |
说明 |
let name = "test" |
$name = "test" |
PHP 变量必须 $ 前缀 |
str + str |
str . str |
PHP 用 . 拼接字符串 |
=== |
=== |
PHP 也有严格相等 |
obj.prop |
$obj->prop |
PHP 对象用 -> |
arr.push(x) |
$arr[] = x |
PHP 数组追加语法 |
foreach |
foreach ($arr as $item) |
类似但需 $ |
关键认知转变:PHP 是请求级生命周期——每次请求开始时变量都是空的,请求结束后进程就退出(不像 Node.js 常驻内存)。
PDO + MySQL:安全的数据库操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| function db(): PDO { static $pdo = null; if ($pdo === null) { $pdo = new PDO( "mysql:host=127.0.0.1;dbname=learnphp;charset=utf8mb4", "root", "password" ); } return $pdo; }
$stmt = db()->prepare("SELECT * FROM messages WHERE name LIKE ?"); $stmt->execute(["%$search%"]); $messages = $stmt->fetchAll();
|
预处理语句是把 SQL 模板和数据分开发送,数据库先编译模板,再填入参数。参数不会被当作 SQL 执行,彻底杜绝 SQL 注入。
RESTful API 设计
| 方法 |
路径 |
含义 |
| GET |
/messages |
获取列表 |
| POST |
/messages |
创建留言 |
| DELETE |
/messages?id=1 |
删除留言(需认证) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function jsonOut(int $code, string $message, $data = null, int $http = 200): void { http_response_code($http); echo json_encode([ "code" => $code, "message" => $message, "data" => $data ]); exit; }
function inputJson(): array { return json_decode(file_get_contents("php://input"), true) ?? []; }
|
CORS:跨域请求处理
前端和 API 不同域名时,浏览器会发 CORS 预检(OPTIONS 请求)。简单请求(GET/POST 无自定义头)直接通过,复杂请求需要预检。
1 2 3 4 5 6 7 8 9 10
| function handleCORS(): void { header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS"); header("Access-Control-Allow-Headers: Content-Type, Authorization"); if ($_SERVER["REQUEST_METHOD"] === "OPTIONS") { http_response_code(204); exit; } }
|
Bearer Token 认证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function requireAuth(): array { $header = $_SERVER["HTTP_AUTHORIZATION"] ?? ""; if (!preg_match("/^Bearer\s+(.+)$/", $header, $m)) { jsonOut(1, "未登录", null, 401); } $token = $m[1]; $stmt = db()->prepare( "SELECT id, username FROM users WHERE token = ? AND token_expires_at > NOW()" ); $stmt->execute([$token]); $user = $stmt->fetch(); if (!$user) { jsonOut(2, "token 无效或过期", null, 401); } return $user; }
|
登录时用 random_bytes(32) 生成 64 字符随机 token,存到 users 表。这种 opaque token 比 JWT 更适合学习场景——简单直观,不引入额外库。
密码存储用 bcrypt:
1 2
| $hash = password_hash($password, PASSWORD_DEFAULT); password_verify($password, $user["password_hash"]);
|
MVC 分层重构
从单文件 API 重构到 MVC 分层:
1 2 3 4 5 6 7 8 9
| api/v2/ ├── index.php # 前端控制器 + 路由表 ├── models/ │ ├── Message.php # 数据层(SQL) │ └── User.php ├── controllers/ │ ├── MessageController.php # 业务层(HTTP + 规则) │ └── UserController.php └── common.php # 公共工具(DB/CORS/jsonOut)
|
Model 层只管 SQL,不碰 HTTP。Controller 层处理请求解析、业务校验、响应格式。
1 2 3 4 5 6 7 8 9
| $routes = [ "messages" => [ "GET" => [$controller, "index"], "POST" => [$controller, "store"], "DELETE" => [$controller, "destroy"], ], ]; ($routes[$path][$method])();
|
依赖注入:从外层组装对象图,传入内部:
1 2
| $messageModel = new Message(db()); $controller = new MessageController($messageModel);
|
这让你理解了 Laravel 的核心概念——Eloquent ORM、路由文件、Controller、中间件、服务容器,都是你手写原型的标准化版本。
总结
前端工程师学 PHP 的优势:
- 语法相似度高(
$ 前缀、. 拼接是最大差异)
- HTTP 概念相通(请求/响应/状态码/Header)
- MVC 分层思想和其他框架一致
- 异步思维转变后,同步阻塞模型反而更简单
最难的不是语言本身,而是服务端思维:请求级生命周期、并发处理、进程管理。但这些理解后,PHP 就是最直观的后端入门选择。