1 Composer 详解
Composer 是 PHP 的依赖管理工具,也是整个 PHP 现代生态的基石。它负责下载、安装第三方包并自动生成 autoload 文件。
npm 之于 Node.js、pip 之于 Python、Maven/Gradle 之于 Java。配置文件 composer.json 等价于 package.json / requirements.txt。锁文件 composer.lock 等价于 package-lock.json。
常用命令
# 初始化项目(交互式生成 composer.json)
composer init
# 安装一个包(自动写入 composer.json 并下载)
composer require guzzlehttp/guzzle
# 安装开发依赖(仅开发环境使用)
composer require --dev phpunit/phpunit
# 根据 composer.lock 安装所有依赖(部署时使用)
composer install
# 更新依赖到最新兼容版本
composer update
# 更新 autoload 映射(添加新类后)
composer dump-autoload
composer.json 结构
{
"name": "myvendor/myproject",
"description": "我的 PHP 项目",
"type": "project",
"require": {
"php": ">=8.4",
"guzzlehttp/guzzle": "^7.8",
"monolog/monolog": "^3.0",
"nesbot/carbon": "~3.0"
},
"require-dev": {
"phpunit/phpunit": "^11.0"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
}
}
版本约束
| 符号 | 含义 | 示例 |
|---|---|---|
^ |
兼容更新(不破坏主版本) | ^7.8 → >=7.8.0 <8.0.0 |
~ |
允许最后一位增长 | ~3.0 → >=3.0.0 <4.0.0 |
* |
通配符 | 3.* → 任何 3.x 版本 |
| 精确版本 | 锁定特定版本 | 3.7.2 |
PSR-4 自动加载
配置 autoload.psr-4 后,只需引入 vendor/autoload.php,所有类都能自动加载:
<?php
// 项目入口文件
require __DIR__ . '/vendor/autoload.php';
// 直接使用,无需手动 require 每个文件
use App\Services\UserService;
use App\Models\User;
$service = new UserService();
$user = $service->findById(1);
目录结构对应关系:命名空间 App\Services\UserService 映射到文件 src/Services/UserService.php。
2 Guzzle — HTTP 客户端
Guzzle 是 PHP 最流行的 HTTP 客户端库,提供简洁的 API 发送 HTTP 请求、处理响应,支持异步并发。
composer require guzzlehttp/guzzle
基本用法
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$client = new Client([
'base_uri' => 'https://api.example.com',
'timeout' => 5.0,
]);
// GET 请求
$response = $client->get('/users', [
'query' => ['page' => 1, 'limit' => 10],
'headers' => [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
],
]);
$statusCode = $response->getStatusCode(); // 200
$body = json_decode($response->getBody(), true); // 解析 JSON
// POST 请求(发送 JSON)
$response = $client->post('/users', [
'json' => [
'name' => '张三',
'email' => 'zhangsan@example.com',
],
]);
// POST 表单数据
$response = $client->post('/login', [
'form_params' => [
'username' => 'admin',
'password' => 'secret',
],
]);
异常处理
<?php
try {
$response = $client->get('/users/999');
} catch (RequestException $e) {
if ($e->hasResponse()) {
$error = json_decode($e->getResponse()->getBody(), true);
echo "错误: " . $error['message'];
} else {
echo "请求失败: " . $e->getMessage();
}
}
异步请求
<?php
use GuzzleHttp\Promise\Utils;
$promises = [
'users' => $client->getAsync('/users'),
'products' => $client->getAsync('/products'),
'orders' => $client->getAsync('/orders'),
];
// 并发执行所有请求
$results = Utils::unwrap($promises);
$users = json_decode($results['users']->getBody(), true);
$products = json_decode($results['products']->getBody(), true);
$orders = json_decode($results['orders']->getBody(), true);
cURL 发送请求。实际项目中推荐使用 Guzzle —— API 更简洁,内置重试、连接池、异步等高级特性。
3 Monolog — 日志库
Monolog 是 PHP 的标准日志库(遵循 PSR-3 接口),支持将日志输出到文件、数据库、Slack、邮件等多种目标。Laravel、Symfony 等框架均内置 Monolog。
composer require monolog/monolog
基本使用
<?php
require 'vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Formatter\LineFormatter;
// 创建日志通道
$log = new Logger('app');
// Handler 1:所有日志写入文件
$log->pushHandler(new StreamHandler(__DIR__ . '/logs/app.log', Logger::DEBUG));
// Handler 2:错误日志单独归档,按天轮转,保留 30 天
$errorHandler = new RotatingFileHandler(
__DIR__ . '/logs/error.log',
30, // 保留天数
Logger::ERROR // 最低记录级别
);
$log->pushHandler($errorHandler);
// 写入日志
$log->debug('调试信息', ['module' => 'auth']);
$log->info('用户登录成功', ['user_id' => 42]);
$log->warning('缓存命中率低', ['rate' => 0.35]);
$log->error('数据库连接失败', ['host' => 'db.example.com']);
$log->critical('支付网关无响应');
日志级别(从低到高)
| 级别 | 用途 |
|---|---|
DEBUG | 详细调试信息 |
INFO | 关键业务事件(用户登录、订单创建) |
NOTICE | 正常但需关注的事件 |
WARNING | 异常情况但不影响运行 |
ERROR | 运行时错误,需修复 |
CRITICAL | 关键组件不可用 |
ALERT | 必须立即处理 |
EMERGENCY | 系统不可用 |
自定义格式
<?php
$formatter = new LineFormatter(
"[%datetime%] %channel%.%level_name%: %message% %context%\n",
'Y-m-d H:i:s'
);
$handler = new StreamHandler(__DIR__ . '/logs/app.log', Logger::DEBUG);
$handler->setFormatter($formatter);
$log = new Logger('app');
$log->pushHandler($handler);
// 输出: [2026-03-31 10:30:00] app.INFO: 用户登录成功 {"user_id":42}
4 Carbon — 日期时间处理
Carbon 是 PHP DateTime 的增强封装,提供极其流畅的 API 处理日期和时间,Laravel 中默认集成。
composer require nesbot/carbon
dayjs / moment.js 之于 JavaScript,pendulum / arrow 之于 Python。PHP 原生 DateTime 功能较弱,Carbon 补齐了差距。
创建与格式化
<?php
require 'vendor/autoload.php';
use Carbon\Carbon;
// 创建实例
$now = Carbon::now(); // 当前时间
$today = Carbon::today(); // 今天 00:00:00
$date = Carbon::create(2026, 3, 31, 10, 30); // 指定时间
$parsed = Carbon::parse('2026-03-31 10:30:00');
// 格式化输出
echo $now->format('Y-m-d H:i:s'); // 2026-03-31 10:30:00
echo $now->toDateString(); // 2026-03-31
echo $now->toDateTimeString(); // 2026-03-31 10:30:00
echo $now->isoFormat('YYYY年MM月DD日'); // 2026年03月31日
日期计算
<?php
$now = Carbon::now();
// 加减运算
$tomorrow = $now->copy()->addDay();
$nextWeek = $now->copy()->addWeek();
$lastMonth = $now->copy()->subMonth();
$future = $now->copy()->addDays(45)->addHours(3);
// 链式操作
$deadline = Carbon::parse('2026-12-31')
->subDays(7)
->startOfDay(); // 2026-12-24 00:00:00
比较与差值
<?php
$start = Carbon::parse('2026-01-01');
$end = Carbon::parse('2026-03-31');
echo $start->diffInDays($end); // 89
echo $start->diffInMonths($end); // 2
echo $start->diffForHumans($end); // "2个月前"
// 布尔判断
$date = Carbon::parse('2026-03-31');
$date->isWeekday(); // true
$date->isToday(); // true (假设今天是 3/31)
$date->isFuture(); // false
$date->isPast(); // false
$date->isLeapYear(); // false
// 比较
$a = Carbon::parse('2026-01-01');
$b = Carbon::parse('2026-06-01');
$a->lt($b); // true (less than)
$a->gte($b); // false (greater than or equal)
时区处理
<?php
$beijing = Carbon::now('Asia/Shanghai');
$newYork = $beijing->copy()->setTimezone('America/New_York');
echo $beijing->format('Y-m-d H:i'); // 2026-03-31 22:30
echo $newYork->format('Y-m-d H:i'); // 2026-03-31 10:30
add/sub 方法会修改原对象。如果需要保留原始日期,使用 copy() 先复制再操作,或者使用不可变版本 CarbonImmutable。
5 PHPUnit — 单元测试
PHPUnit 是 PHP 事实上的标准测试框架,支持单元测试、Mock、代码覆盖率等。
# 安装为开发依赖
composer require --dev phpunit/phpunit
# 运行测试
./vendor/bin/phpunit
phpunit.xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
colors="true"
stopOnFailure="false">
<testsuites>
<testsuite name="Unit">
<directory>tests</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory>src</directory>
</include>
</source>
</phpunit>
编写测试类
<?php
// tests/CalculatorTest.php
namespace Tests;
use PHPUnit\Framework\TestCase;
use App\Calculator;
class CalculatorTest extends TestCase
{
private Calculator $calc;
// 每个测试方法执行前调用
protected function setUp(): void
{
$this->calc = new Calculator();
}
// 每个测试方法执行后调用
protected function tearDown(): void
{
// 清理资源(如果需要)
}
public function testAdd(): void
{
$this->assertEquals(5, $this->calc->add(2, 3));
$this->assertEquals(0, $this->calc->add(-1, 1));
}
public function testDivide(): void
{
$this->assertEquals(2.5, $this->calc->divide(5, 2));
}
public function testDivideByZeroThrowsException(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('除数不能为零');
$this->calc->divide(10, 0);
}
}
常用断言
<?php
// 相等性
$this->assertEquals('hello', $result); // 值相等(== 宽松比较)
$this->assertSame('hello', $result); // 类型+值完全相同(===)
// 布尔
$this->assertTrue($user->isActive());
$this->assertFalse($user->isBanned());
$this->assertNull($user->deletedAt());
// 数组
$this->assertCount(3, $items);
$this->assertContains('admin', $roles);
$this->assertArrayHasKey('email', $data);
$this->assertEmpty($errors);
// 类型与实例
$this->assertInstanceOf(User::class, $result);
$this->assertIsString($name);
$this->assertIsArray($list);
// 字符串
$this->assertStringContainsString('error', $message);
$this->assertMatchesRegularExpression('/^\d{4}-\d{2}/', $date);
数据提供器(Data Provider)
<?php
use PHPUnit\Framework\Attributes\DataProvider;
class MathTest extends TestCase
{
public static function additionProvider(): array
{
return [
'正数相加' => [3, 4, 7],
'负数相加' => [-1, -2, -3],
'零加任意数' => [0, 5, 5],
'大数相加' => [PHP_INT_MAX, 0, PHP_INT_MAX],
];
}
#[DataProvider('additionProvider')]
public function testAdd(int $a, int $b, int $expected): void
{
$this->assertSame($expected, $a + $b);
}
}
# 运行特定测试文件
./vendor/bin/phpunit tests/CalculatorTest.php
# 运行特定方法
./vendor/bin/phpunit --filter testAdd
# 显示详细输出
./vendor/bin/phpunit --testdox
6 vlucas/phpdotenv — 环境变量
phpdotenv 从 .env 文件加载环境变量,让敏感配置(数据库密码、API 密钥)与代码分离。
composer require vlucas/phpdotenv
.env 文件示例
# .env(不要提交到 Git!加入 .gitignore)
APP_NAME=MyApp
APP_ENV=production
APP_DEBUG=false
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=myapp
DB_USERNAME=root
DB_PASSWORD=secret
REDIS_HOST=127.0.0.1
API_KEY=sk-xxxxxxxxxxxx
加载与使用
<?php
require 'vendor/autoload.php';
// 加载 .env 文件(通常在应用入口处执行一次)
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
// 必须存在的变量(缺少则抛异常)
$dotenv->required(['DB_HOST', 'DB_DATABASE', 'DB_USERNAME']);
// 读取环境变量(三种方式)
$dbHost = $_ENV['DB_HOST']; // 推荐
$dbHost = $_SERVER['DB_HOST']; // 也可以
$dbHost = getenv('DB_HOST'); // 传统方式
// 实际使用
$dsn = sprintf(
'mysql:host=%s;port=%s;dbname=%s;charset=utf8mb4',
$_ENV['DB_HOST'],
$_ENV['DB_PORT'],
$_ENV['DB_DATABASE']
);
$pdo = new PDO($dsn, $_ENV['DB_USERNAME'], $_ENV['DB_PASSWORD']);
最佳实践
✅ 推荐
- • 将
.env加入.gitignore - • 提供
.env.example作为模板 - • 使用
required()校验必要变量 - • 生产环境用真实环境变量替代 .env
❌ 避免
- • 将
.env提交到版本控制 - • 在代码中硬编码密码或密钥
- • 在非入口文件多次
load() - • 在 .env 中存储大段文本
7 其他推荐库
PHP 生态中还有很多高质量的库,以下是实际项目中高频使用的:
symfony/console
构建命令行工具的框架,支持参数解析、彩色输出、进度条、交互式问答。
composer require symfony/console
league/flysystem
文件系统抽象层,统一 API 操作本地磁盘、S3、FTP、阿里云 OSS 等存储。
composer require league/flysystem
ramsey/uuid
生成 RFC 4122 标准 UUID(v4 随机、v7 时间排序),广泛用于分布式 ID。
composer require ramsey/uuid
respect/validation
流畅的数据验证库,链式 API 校验邮箱、手机号、长度、范围等。
composer require respect/validation
predis/predis
纯 PHP 实现的 Redis 客户端,无需安装 C 扩展即可连接 Redis。
composer require predis/predis
intervention/image
图片处理库,支持裁剪、缩放、水印、格式转换,API 简洁优雅。
composer require intervention/image
快速示例
<?php
// ramsey/uuid - 生成 UUID
use Ramsey\Uuid\Uuid;
$uuid = Uuid::uuid4()->toString(); // "550e8400-e29b-41d4-a716-446655440000"
$uuid7 = Uuid::uuid7()->toString(); // 时间排序的 UUID v7
// respect/validation - 数据验证
use Respect\Validation\Validator as v;
$valid = v::email()->validate('user@example.com'); // true
$valid = v::stringType()->length(2, 50)->validate('张三'); // true
$valid = v::numericVal()->between(1, 100)->validate(42); // true
// predis/predis - Redis 操作
$redis = new Predis\Client(['host' => '127.0.0.1']);
$redis->set('user:1:name', '张三');
$redis->expire('user:1:name', 3600);
$name = $redis->get('user:1:name'); // "张三"
8 PHP 框架概览
掌握 PHP 基础后,选择一个框架能极大提升开发效率。以下是目前最主流的三个框架:
| 框架 | 类型 | 特点 | 适用场景 | 学习曲线 |
|---|---|---|---|---|
| Laravel | 全栈框架 | 优雅语法、Eloquent ORM、Blade 模板、队列、广播、丰富生态 | Web 应用、SaaS、API 后端 | ⭐⭐ 中等 |
| Symfony | 全栈框架 | 企业级、组件化设计、高度可配置、长期支持版本 | 大型企业项目、复杂业务系统 | ⭐⭐⭐ 较高 |
| Slim | 微框架 | 轻量、仅路由+中间件、自由选择组件 | REST API、微服务、小型项目 | ⭐ 简单 |
快速创建项目
# Laravel
composer create-project laravel/laravel my-app
cd my-app && php artisan serve # 启动开发服务器 http://localhost:8000
# Symfony
composer create-project symfony/skeleton my-app
cd my-app && symfony server:start
# Slim
composer require slim/slim slim/psr7
Slim 微框架示例
<?php
// public/index.php
require __DIR__ . '/../vendor/autoload.php';
use Slim\Factory\AppFactory;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
$app = AppFactory::create();
$app->addErrorMiddleware(true, true, true);
$app->get('/', function (Request $request, Response $response) {
$response->getBody()->write(json_encode(['message' => '你好,PHP!']));
return $response->withHeader('Content-Type', 'application/json');
});
$app->get('/users/{id}', function (Request $request, Response $response, array $args) {
$userId = $args['id'];
$response->getBody()->write(json_encode(['id' => $userId]));
return $response->withHeader('Content-Type', 'application/json');
});
$app->run();
- • 新手入门或构建 API → Slim(轻量,概念少,快速上手)
- • 快速开发 Web 应用 → Laravel(生态最丰富,社区最活跃,文档优秀)
- • 大型企业项目 → Symfony(架构严谨,适合复杂业务)
- • 本教程学完后,建议从 Laravel 或 Slim 开始实战
9 本章要点
📦 Composer
- •
require安装、install部署 - •
^/~语义化版本约束 - • PSR-4 自动加载映射类到文件
🌐 Guzzle
- • GET/POST 请求、JSON 处理
- • 异步并发请求
- • 替代原生 cURL 的最佳选择
📋 Monolog
- • PSR-3 标准日志接口
- • Handler 控制输出目标
- • 8 个级别从 DEBUG 到 EMERGENCY
📅 Carbon
- • DateTime 增强封装
- • 流畅的链式日期操作
- •
copy()避免修改原对象
🧪 PHPUnit
- •
TestCase+assert*方法 - • Data Provider 参数化测试
- •
setUp/tearDown管理测试生命周期
🔒 phpdotenv
- •
.env文件加载环境变量 - • 敏感配置与代码分离
- •
.env不提交、.env.example提交
🎉 恭喜完成 PHP 速成教程!
你已经掌握了 PHP 8.4 的核心知识 —— 从环境搭建、基础语法、函数与 OOP、数据库操作、网络通信、文件处理,到 Composer 生态与常用工具库。
下一步建议:
- 用 Slim 或 Laravel 构建一个完整的 REST API 项目
- 为项目编写 PHPUnit 测试,养成测试驱动的习惯
- 阅读 PHP-FIG PSR 标准,了解社区最佳实践
- 探索 Packagist 上的更多开源包