首页 / PHP 入门教程 / PHP 性能优化

PHP 入门教程

PHP 性能优化

本教程共 65 篇 · 第 43 篇 · 更新于 2026-07-24 · 约 5 分钟阅读

PHPPHP8性能优化OPcache缓存生成器数据库优化

43. PHP 性能优化

本节目标:了解 PHP 常见的性能瓶颈,掌握 OPcache、缓存策略和代码层面的优化技巧。

性能优化不是 Premature Optimization(过早优化),而是在明确瓶颈后有的放矢。本章介绍投入产出比最高的几项优化。

43.1 OPcache:最重要的优化

PHP 默认每次请求都要把源码编译成字节码。OPcache 把编译结果缓存到内存,下次直接执行,性能提升可达数倍

检查 OPcache 是否启用

<?php
if (extension_loaded("Zend OPcache")) {
    echo "OPcache 已启用\n";
    print_r(opcache_get_status());
} else {
    echo "OPcache 未启用,请在 php.ini 中设置 zend_extension=opcache";
}

推荐配置

; php.ini
zend_extension=opcache
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=2
opcache.validate_timestamps=1
配置项说明
opcache.memory_consumption缓存内存大小(MB)
opcache.max_accelerated_files最大缓存文件数
opcache.revalidate_freq检查文件更新的频率(秒)
Note

生产环境 revalidate_freq 可设为 60 或更高,减少文件检查开销。开发环境设为 01 保证即时更新。

43.2 缓存策略

数据缓存

把数据库查询结果缓存起来,避免重复查询:

<?php
function getUser(int $id): array {
    $cacheFile = "cache/user_{$id}.json";

    // 缓存 5 分钟
    if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < 300) {
        return json_decode(file_get_contents($cacheFile), true);
    }

    // 从数据库查询
    $user = dbQuery("SELECT * FROM users WHERE id = ?", [$id]);

    // 写入缓存
    file_put_contents($cacheFile, json_encode($user));

    return $user;
}
Tip

生产环境推荐使用 Redis 或 Memcached 做分布式缓存,比文件缓存更快,且支持多服务器共享。

输出缓存

把整个页面的 HTML 缓存下来:

<?php
$cacheFile = "cache/page_" . md5($_SERVER["REQUEST_URI"]) . ".html";

if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < 3600) {
    readfile($cacheFile);
    exit;
}

// 开始输出缓冲
ob_start();

// 正常输出页面内容...
echo "<h1>动态内容</h1>";

// 保存到缓存
file_put_contents($cacheFile, ob_get_contents());
ob_end_flush();

43.3 代码层面优化

1. 优先使用单引号字符串

<?php
// 单引号不解析变量,略快
$name = '张三';
$greeting = 'Hello, world'; // 比 "Hello, world" 稍快

// 需要解析变量时用双引号或插值
$msg = "欢迎, {$name}";

2. 避免在循环内做重复操作

<?php
$count = count($array); // 先计算,不要在 for 条件里重复调用
for ($i = 0; $i < $count; $i++) {
    // ...
}

// PHP 8 起 foreach 是最高效的方式
foreach ($array as $item) {
    // ...
}

3. 使用 isset() 代替 array_key_exists()

<?php
// isset 更快,但在值为 null 时返回 false
if (isset($arr["key"])) { }

// array_key_exists 更精确,但稍慢
if (array_key_exists("key", $arr)) { }

4. 及时释放大变量

<?php
$hugeData = fetchLargeDataset();
process($hugeData);
unset($hugeData); // 及时释放内存

5. 使用生成器处理大数据

<?php
// 普通数组:所有数据一次性加载到内存
function readLines(string $file): array {
    return file($file); // 大文件会内存溢出
}

// 生成器:逐行读取,省内存
function readLinesGenerator(string $file): Generator {
    $fp = fopen($file, "r");
    while (($line = fgets($fp)) !== false) {
        yield trim($line);
    }
    fclose($fp);
}

foreach (readLinesGenerator("big.log") as $line) {
    // 处理每一行,内存占用恒定
}
Note

PHP 8 进一步提升了生成器性能。处理大文件、大数据集时,生成器是首选方案。

43.4 数据库优化

  1. 加索引:WHERE、JOIN、ORDER BY 的字段要有索引
  2. 只查需要的字段:避免 SELECT *
  3. 分页优化:大数据量时用覆盖索引或延迟关联
  4. 连接复用:使用持久连接(PDO PDO::ATTR_PERSISTENT

43.5 使用性能分析工具

找到真正的瓶颈才能有效优化:

<?php
// 简单的耗时测量
$start = microtime(true);

// 要测试的代码...

$end = microtime(true);
echo "耗时:" . round(($end - $start) * 1000, 2) . " 毫秒";

生产环境推荐:

  • Xdebug Profiler:生成性能分析报告
  • Blackfire.io:专业的 PHP 性能分析服务
  • Tideways:开源的 APM 工具

来源:参考了 GitHub「php-the-right-way」相关章节、PHP 官方性能指南等,改写后所得。