APC (Alternative PHP Cache) 早期同時提供 Opcode 緩存與用戶數據緩存。PHP 5.5+ 內置 OpCache 取代了 Opcode 部分,用戶緩存功能由 APCu 獨立維護。本文記錄在 CentOS/RHEL 系統下通過 Yum 安裝 APCu、配置上傳進度監控、常用 API 封裝類,並給出演能調優建議。
# 1. 安裝編譯依賴(若選擇 pecl 安裝)
yum install -y php-pear php-devel httpd-devel pcre-devel gcc make
# 2. 推薦:直接從系統源安裝預編譯包(更穩定、自動跟隨 php 版本)
yum install -y php-pecl-apcu # EPEL 源通常命名為 php-pecl-apcu
# 或
yum install -y php-apcu # Remi 源命名
# 3. 啟用擴展(PHP 7+ 通常自動生成 /etc/php.d/40-apcu.ini)
echo "extension=apcu.so" > /etc/php.d/40-apcu.ini
# 4. 重載 PHP-FPM / Apache
systemctl reload php-fpm
# 或
systemctl reload httpd
php -m | grep apcu
# 輸出 apcu 即成功
php -r "var_dump(apcu_cache_info());"
# 返回數組含 num_slots、ttl 等信息
extension=apcu.so
apc.enabled=1
apc.shm_segments=1
apc.shm_size=128M # 共享內存大小,根據可用內存調整
apc.entries_hint=10000 # 預估條目數,減少重哈希
apc.ttl=7200 # 條目生存時間(秒),0=永不過期(慎用)
apc.gc_ttl=3600 # 垃圾回收間隔
apc.mmap_file_mask=/tmp/apc.XXXXXX # mmap 文件掩碼,提升穩定性
apc.enable_cli=1 # CLI 模式也啟用(方便腳本調試)
apc.serializer=php # 序列化器:php/igbinary/msgpack
; php.ini
apc.rfc1867=1
apc.rfc1867_prefix=upload_
apc.rfc1867_name=APC_UPLOAD_PROGRESS
apc.rfc1867_freq=0 # 更新頻率:0=盡可能快
apc.rfc1867_ttl=3600 # 進度數據保留時間
<form action="upload.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="APC_UPLOAD_PROGRESS" value="<?= uniqid('up_') ?>" />
<input type="file" name="bigfile" />
<button type="submit">上傳</button>
</form>
<div id="progress">0%</div>
<script>
// 輪詢進度接口
setInterval(async () => {
const key = document.querySelector('[name="APC_UPLOAD_PROGRESS"]').value;
const res = await fetch('progress.php?key=' + key);
const data = await res.json();
if (data) document.getElementById('progress').textContent = data.percent + '%';
}, 500);
</script>
<?php
// progress.php
header('Content-Type: application/json');
$key = $_GET['key'] ?? '';
if ($key) {
$info = apcu_fetch('upload_' . $key);
if ($info) {
echo json_encode([
'percent' => $info['total'] ? round($info['current'] / $info['total'] * 100) : 0,
'current' => $info['current'],
'total' => $info['total'],
'rate' => $info['rate'],
]);
}
}
| 函數 | 用途 | 覆蓋行為 |
|---|---|---|
| apc_add($k,$v,$ttl) | 僅當 key 不存在時存入 | 存在返回 false |
| apc_store($k,$v,$ttl) | 無條件存入/覆蓋 | 總是覆蓋 |
| apc_fetch($k, &$ok) | 讀取 | $ok 區分「值為 false」與「不存在」 |
| apc_delete($k) | 刪除單個 key | - |
| apc_clear_cache('user') | 清空用戶緩存 | - |
| apc_exists($keys) | 批量檢查 key 存在性 | 返回存在的 key 數組 |
| apc_inc/dec($k,$step) | 原子增減計數器 | 僅限整數值 |
class ApcuCache {
public function set(string $key, $value, int $ttl = 0): bool {
return apc_store($key, $value, $ttl ?: null);
}
public function get(string $key, &$found = null) {
return apc_fetch($key, $found);
}
public function add(string $key, $value, int $ttl = 0): bool {
return apc_add($key, $value, $ttl ?: null);
}
public function delete(string $key): bool {
return apc_delete($key);
}
public function clear(): bool {
return apc_clear_cache('user');
}
public function exists(string $key): bool {
return apc_exists($key);
}
public function inc(string $key, int $step = 1): int|false {
return apc_inc($key, $step);
}
public function dec(string $key, int $step = 1): int|false {
return apc_dec($key, $step);
}
public function info(): array {
return apcu_cache_info('user');
}
}
// 使用示例
$cache = new ApcuCache();
$cache->set('config:site', ['name' => 'MySite', 'debug' => false], 3600);
var_dump($cache->get('config:site'));
apcu_cache_info()['mem_size'] 使用率,目標 < 80%。apc.serializer=igbinary。apc.php,部署後修改默認帳號密碼即可查看命中率、碎片率、條目分佈。APCu 是單機 PHP 高性能用戶緩存的首選:安裝簡單、API 豐富、支持原子計數與上傳進度。關鍵在於合理規劃 shm_size、選對序列化器、關閉 stat、做好監控。分佈式場景請轉向 Redis/Memcached,但單機高頻熱點數據,APCu 依然是延遲最低、維護成本最小的方案。