Skip to content

性能优化技巧

性能优化是提升用户体验的关键。本文介绍实用的 PHP 性能优化方法。

1. 使用适当的数据结构

php
// ❌ 低效:使用数组存储键值对进行频繁查找
$users = [['id' => 1, 'name' => '张三'], ['id' => 2, 'name' => '李四']];
foreach ($users as $user) {
    if ($user['id'] == $searchId) { /* ... */ }
}

// ✅ 高效:使用关联数组
$userMap = [1 => '张三', 2 => '李四'];
$name = $userMap[$searchId] ?? null;

// isset 比 array_key_exists 快
if (isset($arr['key'])) { }        // ✅ 更快
if (array_key_exists('key', $arr)) { } // 较慢

// 空数组检查
if (!$arr) { }      // ✅ 最快
if (empty($arr)) { } // 稍慢
if (count($arr) === 0) { } // 最慢

2. 字符串操作优化

php
// 单引号比双引号快(无变量插值时)
$str = 'hello world';  // ✅ 更快
$str = "hello world";  // PHP 会解析变量

// 字符串连接
$name = $first . ' ' . $last;        // ✅ 少量连接
$name = "$first $last";              // 可读性更好

// 大量连接使用数组
$parts = [];
foreach ($items as $item) {
    $parts[] = process($item);
}
$result = implode('', $parts);       // ✅ 比 .= 快

3. 循环优化

php
// 缓存数组长度
$count = count($array);              // ✅ 只计算一次
for ($i = 0; $i < $count; $i++) { }

// 优先使用 foreach
foreach ($array as $key => $value) { } // ✅ PHP 中通常最快

// 避免在循环中调用函数
$len = strlen($str);                 // ✅ 提取到循环外
for ($i = 0; $i < $len; $i++) { }

// 预分配数组容量(大数据量)
$result = new SplFixedArray(10000);  // 固定大小数组

4. 文件操作优化

php
// 读取大文件
// ❌ 内存占用高
$content = file_get_contents('huge.log');

// ✅ 流式读取
$handle = fopen('huge.log', 'r');
while (($line = fgets($handle)) !== false) {
    process($line);
}
fclose($handle);

// 包含文件优化
// ✅ 使用绝对路径
require_once __DIR__ . '/config.php';

// 自动加载优化
// ✅ 使用 Composer 优化后的自动加载
// composer dump-autoload --optimize

5. 数据库查询优化

php
// ✅ 批量插入代替单条插入
$data = [
    ['name' => '张三', 'age' => 20],
    ['name' => '李四', 'age' => 25],
];
$pdo->prepare("INSERT INTO users (name, age) VALUES (?, ?)");
foreach ($data as $row) {
    $stmt->execute([$row['name'], $row['age']]);
}

// ✅ 使用 JOIN 代替 N+1 查询
// ❌ 低效:循环查询
foreach ($users as $user) {
    $orders = fetchOrders($user['id']);  // N次查询
}

// ✅ 高效:一次 JOIN 查询
$stmt = $pdo->query("
    SELECT u.*, o.id as order_id, o.amount
    FROM users u
    LEFT JOIN orders o ON u.id = o.user_id
");

6. 使用 Opcode 缓存

php
// ✅ 启用 OPcache(php.ini)
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0  // 生产环境

// 使用 APCu 做数据缓存
apcu_store('config', $config, 3600);
$config = apcu_fetch('config');

7. 延迟加载与懒加载

php
class UserService {
    private $db = null;

    // ✅ 延迟初始化
    private function getDb() {
        if ($this->db === null) {
            $this->db = new PDO('...');
        }
        return $this->db;
    }

    public function getUser($id) {
        $stmt = $this->getDb()->prepare("SELECT * FROM users WHERE id = ?");
        // ...
    }
}

注意事项

  1. 先分析再优化:使用 Xdebug 或 Blackfire 找出真正的瓶颈
  2. 避免过早优化:清晰的代码比微优化更重要
  3. 内存管理:注意循环引用可能导致内存泄漏
  4. 缓存策略:合理设计缓存,比代码优化效果更明显

Binstork