当前位置:首页>php>PHP 数组的写时复制(COW)原理与实测

PHP 数组的写时复制(COW)原理与实测

  • 2026-08-20 22:30:03
PHP 数组的写时复制(COW)原理与实测

一位开发者在分析一个 PHP 函数的性能:它接收一个 20 万元素的数组,经六个内部辅助函数逐层传递后产出结果。分析器显示该函数耗时约 4 毫秒——考虑到“PHP 到处都会复制数组”的说法,这个速度出乎意料。开发者怀疑分析器在撒谎,于是在每个函数调用周围布下 memory_get_usage() 检查点。结果回来了:第一次调用分配了 0 字节;第二次也是 0 字节;所有只读的调用都是 0 字节。到第七个辅助函数执行 $data['flag'] = true 时,内存增量突然出现了 +5 MB。“复制无处不在”的心智模型是错的;真相是“复制恰好发生在某一个特定时刻,而且只发生在那一刻”。

那个时刻正是写时复制(copy-on-write,COW)在 PHP 中的真正含义。模型是这样的:一个值可以同时拥有多个持有者,它们都指向同一块底层内存;只有当其中一个持有者试图修改它时,这块内存才会被复制。在修改发生之前,“这个数组”无论被多少个变量引用,在内存中都只存在一份。正是这一点让 PHP 惯用的“随意传递数组”的代码保持高性能;也正是这一点让开发者在初次接触时对性能特征感到意外。成本并不出现在人们以为它应该在的地方。

本文是对 COW 的深入实测:不停留在“PHP 有写时复制”这种高层论断,而是对每个时刻实际发生的事情进行测量——通过 xdebug_debug_zval 直接检查 refcount,并以字节为单位测量内存增量。目标是建立一个心智模型:在运行代码之前,就能准确预测复制何时发生、成本会有多大。全文对照 PHP 8.3.6 验证通过。

速览

COW 用一句话概括:一个值在多个变量之间保持共享,直到其中一个变量修改它;修改的那一刻,该变量获得自己的副本。在此之前,无论有多少个变量持有它,“这个数组”在内存中都只存在一份。已验证的测量结果:一个 10,000 个元素的数组占用 266,296 字节;把它赋给另一个变量花费 0 字节(refcount 从 1 变为 2);对任一副本的第一次写入恰好花费 266,296 字节——整个数组被复制;对同一变量的第二次写入花费接近 0 字节(不再需要分离)。分离事件比同一变量上的后续写入慢约 8,800 倍。第一次写入:8.947 毫秒(分配并复制 266,296 字节);第二次写入:0.001 毫秒。这就是为什么正确的思考单位是“第一次修改的成本”,而不是“每次写入的成本”。嵌套数组按需选择性分离。修改 $copy['a'][0] 只会复制外层容器和 'a' 子数组——而不是 'b' 或 'c'。已验证:单叶修改分配 135,600 字节,而完整结构本应约占 400 KB;未触及的子数组保持 refcount=2,仍然共享。字符串同样遵循 COW,但有一个关键差异:任何修改都会复制整个字符串。一个 100KB 字符串的赋值花费 0 字节;修改一个字符花费 102,400 字节(完整复制外加分配器开销)。PHP 字符串不是可以就地修改的字符缓冲区——它们是不可变的值,修改时会被复制。引用(&)会完全禁用 COW。把某个值标记为 is_ref=1,意味着引用集合中的所有变量都必须观察到相同的修改,PHP 因此放弃这一优化。已验证:执行 Misplaced &x 之后,其他共享 $x 数据的变量会被迫立即分离。

学习要点

  • • 数组赋值与首次修改的确切内存成本
  • • 如何用 xdebug_debug_zval 检查 refcount 的变迁
  • • 嵌套数组如何利用选择性分离避免整体复制
  • • 为什么字符串的 COW 行为与数组不同
  • • 引用(&)在何种情况下会破坏这一优化
  • • “分离事件”的性能特征及其预测方法

引用计数模型(简述)

COW 的底层机制是引用计数。PHP 中每个可进行引用计数的值(数组、字符串、对象、资源)都带有一个计数器——refcount——记录有多少个变量或结构引用了该值。赋值使计数器递增;离开作用域或 unset 使计数器递减。当计数器归零时,内存被释放。

COW 的规则只有一句话:当 refcount > 1 时发生写入,PHP 会先复制该值(原值的 refcount 递减),再对副本执行写入。原值保持不动;原值的其他持有者看不到任何变化。

xdebug_debug_zval 可以直接暴露 refcount:

1
2
3

$arr = [1, 2, 3];xdebug_debug_zval('arr');// arr: (refcount=2, is_ref=0)=array (0 => 1, 1 => 2, 2 => 3)

这里的 refcount=2 包含了 xdebug 自身的临时引用——应用可见的 refcount 是 1。is_ref=0 表示该值不属于引用集合(没有涉及 &)。本文后续将使用这种格式展示各操作过程中值的实际状态。

测量一:赋值零成本

第一项测量确立基线:把一个 10,000 个元素的数组赋给多个变量。

1
2
3
4
5
6
7
8

$mem = memory_get_usage();$big = range(1, 10000);echo "After range(1, 10000): +" . (memory_get_usage() - $mem) . " bytes\n";// After range(1, 10000): +266296 bytes$mem = memory_get_usage();$copy = $big;echo "After \$copy = \$big: +" . (memory_get_usage() - $mem) . " bytes\n";// After $copy = $big: +0 bytes

这个 10,000 个元素的数组本身占用 266,296 字节。赋值花费为零。不是“几个字节”——是零。整个操作不过是“递增 refcount,让 big 原本指向的那块内存”。

继续增加赋值也不会改变任何结果:

1
2
3
4
5
6

$a = $big;  // refcount: 1 → 2$b = $big;  // refcount: 2 → 3$c = $big;  // refcount: 3 → 4$d = $big;  // refcount: 4 → 5$e = $big;  // refcount: 5 → 6// Memory growth across all 5 assignments: 0 bytes

这就是“PHP 数组是带 COW 的按值传递”在实践中的含义。语义模型是“每个变量都拥有自己的数组”;实现却是“一个数组,多个引用”。在有人修改它之前,这一差别无关紧要。

测量二:分离事件

现在修改其中一个变量:

1
2
3
4

$mem = memory_get_usage();$copy[0] = 999;echo "After \$copy[0] = 999: +" . (memory_get_usage() - $mem) . " bytes\n";// After $copy[0] = 999: +266296 bytes

完全相同的数字——266,296 字节。整个数组被复制。不只是元素 0;而是整个结构(HashTable、所有元素、所有键)。这就是分离事件。

在此之后:

  • • copy 共享)
  • • $copy 拥有自己的数组,refcount=1,包含全部原始元素以及这次修改
  • • 对 $copy 的后续修改不再需要任何复制

对比分离与后续写入的耗时,可以看出量级差异:

1
2
3
4

Setup: $arr1 = range(1, 100000); $copy1 = $arr1;$copy1[0] = 'modified'  → 8.947 ms (allocates and copies the entire array)$copy1[1] = 'modified'  → 0.001 ms (just modifies an element)Ratio: 8,823× slower for the first write

第一次写入不只是稍慢——它慢三个数量级,因为它做的是本质上不同的工作。第一次写入触发分离:分配新内存、复制每一个元素、递减原值的 refcount、让 $copy1 指向新内存,然后修改元素 0。第二次写入只是修改一个已被独占的数组的元素 1。

这种耗时特征在性能分析结果中一眼可辨。同一个函数多次被调用、每次看起来都传入“同一个数组”,但单次调用的耗时可能天差地别,取决于那次调用是否触发分离。赋值后的第一次调用昂贵;同一变量上的后续调用便宜。

测量三:嵌套数组的选择性分离

这里才是 COW 真正聪明的地方。对于嵌套数组,只有实际被修改的那条路径会分离——兄弟分支保持共享。

一个三层结构:

1
2
3
4
5
6
7
8
9

$nested = [    'a' => range(1, 5000),  // ~135 KB    'b' => range(1, 5000),  // ~135 KB    'c' => range(1, 5000),  // ~135 KB];$copy = $nested;// 0 bytes allocated (top-level COW)$copy['a'][0] = 'modified';// 135,600 bytes allocated - NOT 400 KB

对 $copy['a'][0] 的修改触发了:

  • • 外层数组(copy 共享的容器)的分离——几百字节
  • • 'a' 子数组(被写入的那个)的分离——135 KB

保持共享的部分:'b' 和 'c' 子数组。它们从未被触及,因此无需复制。经 xdebug_debug_zval 验证:

1
2
3
4
5

copy: (refcount=1, is_ref=0)=array (  'a' => (refcount=1, is_ref=0)=array (0 => 'modified', 1 => 2, ...),  'b' => (refcount=2, is_ref=0)=array (0 => 1, 1 => 2, ...),  ← still shared  'c' => (refcount=2, is_ref=0)=array (0 => 1, 1 => 2, ...),  ← still shared)

'b' 和 'c' 显示 refcount=2——它们仍在 copy['b'] 和 copy['c'] 之间共享。PHP 只复制了不得不复制的部分,仅遍历从根到被修改叶子的路径。

这正是深层嵌套的配置结构、JSON 形态的数据和树状数据在 PHP 中高效的原因。修改深树的一个分支不会复制其他分支。成本与实际触及的部分成正比,而不是与数据总量成正比。

同样的原则,也适用于修改嵌套数据的函数调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

function deepCopyModify(array $data): array{    $data['users'][0]['email'] = 'changed';    return $data;}$shared = [    'users' => [        ['id' => 1, 'email' => 'a@example.com'],        ['id' => 2, 'email' => 'b@example.com'],    ],    'config' => range(1, 1000),  // ~30 KB];$before = memory_get_usage();$mutated = deepCopyModify($shared);$after = memory_get_usage();// Memory delta: 968 bytes

968 字节——而不是 30 KB。30 KB 的 config 子数组未被触及,保持共享。只有 users → 0 → email 这条路径发生了分离。每一层分离都会为被复制的容器结构增加几百字节。

正是这种效率让“纯函数式更新”风格在 PHP 中能够合理地工作。返回大数据结构的修改版本,不必支付整个结构的成本——只需支付路径的成本。

测量四:字符串同样遵循 COW

PHP 中的字符串是值,而不是字符缓冲区。它们与数组遵循相同的 COW 规则,但有一个关键差异:对字符串的任何修改都会复制整个字符串。

1
2
3
4
5
6
7

$s = str_repeat('A', 100000);  // 100KB stringxdebug_debug_zval('s');// s: (refcount=2, is_ref=0)='AAAA...' (100000 chars)$s2 = $s;xdebug_debug_zval('s');// s: (refcount=3, is_ref=0)='AAAA...' (refcount incremented)// 0 bytes allocated for the assignment

现在修改一个字符:

1
2

$s2[0] = 'X';// +102,400 bytes allocated (full string duplication + allocator overhead)

在一个 100,000 字节的字符串中修改一个字符,要花 102,400 字节。原因在于:PHP 字符串内部不是可变的字符数组。“修改一个字符”的操作会创建一个与旧字符串几乎完全相同的新字符串,然后让 s 仍然持有它。

这对性能的影响出人意料。一个“向字符串追加”的循环,实际上每次迭代都在重新复制字符串:

1
2
3
4

$s = '';for ($i = 0; $i < 10000; $i++) {    $s .= 'x';  // re-allocates a slightly larger string each time}

PHP 的字符串处理会对某些情形做优化(对非共享字符串的小幅追加可以使用预分配了额外空间的缓冲区),但概念模型仍是“每次 .= 都会产生一个新字符串”。构建长字符串时,惯用的做法是 implode(array_fill(...))、先构建数组最后再 implode,或者使用基于流的输出缓冲区——这些都能避免反复的整串复制。

与数组的差异:数组有 HashTable 结构,在数组未被共享时,元素可以在原地添加或修改。字符串没有这种结构——它们是连续的字符数据,修改任意字符都等同于创建新字符串。COW 的分离规则以相同的方式适用(refcount > 1 触发复制),但单次修改的成本不同。

测量五:函数不会复制

COW 最实际的影响体现在函数调用上。函数参数是接收该值的新变量。没有 & 时,函数参数与任何其他变量一样参与 COW。

1
2
3
4
5
6
7
8
9
10
11
12

function readOnly(array $data): int{    return count($data);}function passesAlong(array $data): int{    return readOnly($data);  // passes through another layer}$big = range(1, 50000);// $big costs about 1.39 MBreadOnly($big);// Memory delta: 0 bytespassesAlong($big);// Memory delta: 0 bytes (through two layers)

一个 1.39 MB 的数组穿过两次函数调用,两个函数都不修改它:分配 0 字节。每个函数内部的变量 big 指向同一块内存;调用期间 refcount 上升,作用域退出时下降。

对比——一个会修改其参数的函数:

1
2
3
4
5
6

function modifies(array $data): array{    $data[] = 'extra';    return $data;}modifies($big);// Memory delta: 1,052,728 bytes

该函数在修改 big 保持不变。这就是 PHP 所谓“按值传递”的含义——修改只作用于函数的局部变量,调用方看不到。COW 机制让这一切既高效(不修改就不复制)又正确(调用方的数组不受函数修改的影响)。

这有一个反直觉的推论:把数组传给一个不修改它的函数,本质上免费,与数组大小无关。为了“性能”而使用 & 的本能几乎总是错的——& 只改变语义(让修改对调用方可见);它不会加速传参本身。

什么会破坏 COW

这一优化假设一个值可以有多个持有者,且每个持有者都能看到一致的状态。引用(&)违背了这一假设——按设计,PHP 中的引用意味着“该值是某个集合的一部分;集合中的所有成员必须观察到相同的修改”。一旦某个值被引用,该值的 COW 就变得不可能。

1
2
3
4
5
6
7
8
9
10

$x = [1, 2, 3];$y = $x;$z = $x;xdebug_debug_zval('x');// x: (refcount=4, is_ref=0)=array  ← all three share the zval$y = &$x;  // make $y a reference to $xxdebug_debug_zval('x');// x: (refcount=2, is_ref=1)=array  ← only $x and $y now share the (now-referenced) valuexdebug_debug_zval('z');// z: (refcount=1, is_ref=0)=array  ← $z had to separate!

创建 Misplaced &x 这一动作迫使 z 原本与 x 成了引用集合的一部分(is_ref=1)。z 的修改就必须传播到 y(因为它们共享同一存储),这违背了 z 分配一份自己的副本。

教训:在某处引入 & 不只是改变那一个变量——它可能迫使共享同一值的其他变量立即分配副本。对于大型数据结构,这可能是一笔相当可观的意外开销。

另一件破坏 COW 的事:对象上的类型化属性,在特定情况下。当 PHP 向类型化属性赋值时,可能需要校验类型是否匹配;如果被赋的值是共享的(refcount > 1),这就会以取决于具体类型的方式与 COW 相互作用。常见情形(把共享数组赋给数组类型属性)仍然正确使用 COW。边界情形涉及要求该值只能被唯一持有的类型强制转换。这种情况相当少见,大多数应用代码永远不会遇到。

嵌套修改中的逐层分离

当深入嵌套结构进行修改时,PHP 会在从根到修改点的每一层都执行分离——但只针对那一条路径。前面已验证过:

1
2
3
4
5
6

$shared['users'][0]['email'] = 'new'  → outer array separates (refcount was > 1, now its own copy)  → 'users' sub-array separates (was shared, now its own copy)  → users[0] sub-array separates (was shared, now its own copy)  → email property gets the new value

其他子数组在每一层都未被触及,保持共享,refcount=2成本等式:分离深度 × 每层开销 + 最终修改。对于浅层嵌套(1–2 层),成本由最终修改主导;对于深层嵌套(10 层以上),每层开销就变得不可忽视。

这就是为什么“宽而浅”的数据结构(一个根、许多叶子、深度相同)在 PHP 中通常比“窄而深”的结构(一个根,向下穿过许多包装层)表现更好。宽结构只修改被触及的叶子;深结构则让分离逐层传播过每一个包装层。

对于频繁变更且嵌套很深的数据结构,访问模式很重要。在函数局部变量中构建最终状态(无共享,因此无需 COW)再赋值结果,有时比增量地修改共享结构更便宜。函数局部的构建方式避免了每次修改的分离成本;最终的一次赋值只是一个 COW 事件。

需要避免的陷阱

以为函数会复制它们的参数。不会,除非函数修改它们。“把大数组传给函数很慢”的直觉对 PHP 来说是错的——只有当函数修改数组时才会慢。只读的函数调用在传参上零开销。

用 & 来“优化”。引用不会加速传参;它们只改变语义。它们还会迫使共享同一值的其他变量分离,从而增加意外的内存成本。

在紧凑循环中用 .= 构建字符串。每次 .= 概念上都是一个新字符串。PHP 会优化某些情形,但模型是“字符串追加 = 新字符串”。构建长字符串时,先在数组中累积,最后一次性 implode。

只对函数分析一次就相信结果。第一次调用可能包含分离成本;同一变量上的后续调用则不会。“这个函数耗时 50ms”的分析结果,可能实际上是“这个函数第一次耗时 50ms,之后耗时 5ms”。应在循环中分析,或用能控制 COW 状态的显式设置来分析。

修改函数参数却期待调用方看到变化。没有 & 时,函数的修改是局部的。返回修改后的值并使用返回值才是惯用模式;指望通过修改参数让调用方看到变化,是对 PHP 语义的误解。

忘记 is_ref 的粘性。一旦某个值被引用(引用集合中的任何变量),该值就会保持 is_ref=1,直到所有引用都被 unset。这意味着后续对其他变量的赋值会经由该引用(破坏 COW),而不是全新赋值。

在 COW 问题上把对象属性当作数组元素。对象使用的是句柄共享,而不是 COW。对对象执行 a 会共享同一个底层对象——通过任一方进行的修改,双方都能看到。对象内部的数组仍然使用 COW,但对象本身不使用。

迷你问答

把大数组传给函数时,PHP 真的不会复制吗?

已验证,确实不会。一个 1.39 MB 的数组穿过两次函数调用(两者都不修改数组),额外分配为零字节。函数参数成为对同一底层内存的额外引用;调用期间 refcount 上升,函数退出时下降。只有当函数修改其参数时才会发生复制——而且只复制结构中被触及的部分。

如何判断某段代码是否会触发 COW 分离?

最直接的方法:在疑似操作前后用 memory_get_usage() 测量内存。出现非零增量且没有明显的分配原因,就表明发生了分离。xdebug_debug_zval 直接显示 refcount 值——如果某个变量的 refcount > 1(扣除 xdebug 自身的引用后),修改该变量就会触发分离。

为什么字符串构建循环会分配这么多内存?

因为每次 .= 操作概念上都会创建一个新字符串。增长模式取决于 PHP 的分配器和具体情形,但模型是“新字符串是一次全新分配,包含旧内容加上新片段”。构建长字符串时,先在数组中累积(追加高效),最后再 implode。

unset() 能加速 COW 操作吗?

间接可以。如果 copy 共享数据(refcount=2),修改任一都会触发分离。如果先 unset(big 的修改就不会触发分离,因为没有其他东西共享该值。对于明知即将修改、且不需要其他引用的变量,显式 unset 其他引用可以避免复制成本。

类型化属性会因 COW 而变慢吗?

通常不会——类型化数组属性仍然正确使用 COW。边界情形涉及类型强制转换(例如赋入一个需要转换以匹配声明类型的值)。类型匹配时(把数组赋给数组属性),COW 行为与无类型属性完全一致。

array_merge 或 array_combine 会复制数据吗?

会。这些函数会生成包含其输入元素的新数组。元素本身可能是 COW 共享的(如果输入是简单值,新数组会包含对这些值的引用并 refcount++)。新数组结构(HashTable 和桶数据)是全新分配的。对于非常大的数组,这些函数有真实的内存成本;对于小数组,成本可以忽略。

那 foreach 呢——会造成复制吗?

对数组的 foreach 使用一个与迭代共享该数组的内部迭代器;在只读迭代期间不会发生复制。foreach (Misplaced &v)(按引用)会把每个元素变成引用,从而影响这些元素后续的 COW。最常见的 bug 模式:在 foreach (Misplaced &v) 之后,变量 v)。

总结

PHP 的写时复制是这样一个特性:它无处不在,以至于大多数开发者从不会明确地思考它;但又举足轻重,以至于不理解它就无从理解 PHP 代码的性能特征。在 PHP 代码中习以为常的“随意传递数组”惯用法,在没有 COW 的语言里会成为性能灾难;有了 COW,它就是正确的模式。“PHP 在每次赋值时都会复制数组”的心智模型,错在一个对性能至关重要的具体地方。

正确的心智模型是:赋值免费(refcount 递增);对共享值的修改触发该特定值的分离,成本与被分离部分的大小成正比;嵌套结构选择性分离——只有通向修改点的路径,而不是整个结构;字符串在任何修改上都会整体分离,因为它们是连续数据,没有可共享的内部结构。

对应用代码而言,实际后果是:把数组传给函数很便宜;修改函数参数不影响调用方(没有 & 时);引用会以可能产生非局部影响的方式破坏优化;用 .= 增量构建字符串在规模上很昂贵。这些都不需要显式编程——它们只是影响那些本就自然写出的代码的性能特征。

更深一层的收获,也适用于 PHP 之外:一次计算的成本并不总在人们以为它应该在的地方。一个“做了很多事”的函数可能很便宜,因为底层数据是共享的;一个“只修改一个字段”的函数可能很贵,因为那次修改会穿透多层触发分离。为成本而读代码,需要理解运行时模型,而不只是表层语法。COW 正是这样一类机制:表层语法(big)对实际运行时行为(refcount 递增、零分配、成本推迟)毫无描述。内化这个模型,正是区分“PHP 有时神秘地快”与“我确切知道这段代码在哪里分配内存”的分界线。

收尾

那位分析 20 万元素数组穿过六个辅助函数的开发者,最终得到了清晰的理解。4 毫秒的总耗时不是分析器撒谎——它是六层 refcount 递增(可忽略)加上一次最终读取(可忽略)的实际成本。昂贵的操作是第七个辅助函数的 $data['flag'] = true:因为数组在全部六层调用之间共享,第七层的修改触发了对整个 20 万元素数组的复制。

修复的办法不是让第七个辅助函数更快——而是要认识到分离才是昂贵的操作,进而要么避免它,要么改在另一个时点只做一次。在本例中,团队重构了代码,让修改作用在函数局部变量上(不共享,因此无需分离),最终结果被返回。第七个辅助函数的运行时间从 60 毫秒降到 4 毫秒;团队整体请求时间每次请求改善 50 毫秒,因为同样的分离模式还发生在另外三处他们尚未分析过的地方。

一年后,一位新开发者看着同一份代码,问为什么辅助函数返回结果,而不是修改那个“显而易见”、本就在各处传递的参数。资深开发者解释了 COW、分离成本,以及那个“显而易见”的修改模式正是最初的性能 bug。新开发者内化了这个模型;团队从此在代码评审文化中开始在上线前就捕捉类似模式。

这就是理解 COW 的实际回报:不只是“PHP 传数组比你预期的快”,更是在分析之前就能预测成本所在。多数时候这无关紧要——处理小数组的应用代码,无论团队是否理解 COW,运行起来都一样。但对于处理大型数据结构的代码,懂与不懂这个模型的差别,就是“性能可预测的代码”与“有着神秘性能悬崖的代码”之间的差别。

“大家还想知道”

  1. 1. PHP 中的写时复制是什么?写时复制(COW)是这样一种优化:PHP 在把一个变量赋给另一个变量时,并不真正复制数组或字符串数据。相反,两个变量引用同一块底层内存,由一个 refcount 追踪存在多少个引用。只有当其中一个变量修改该值时,PHP 才分配新内存并复制数据。已验证:一个 10,000 个元素的数组(266,296 字节)赋给另一个变量花费 0 字节;第一次修改花费 266,296 字节(完整结构被复制)。
  2. 2. 把数组传给函数时 PHP 会复制吗?不会,除非函数修改数组。函数参数与变量赋值一样使用 COW——参数是对同一底层值的新引用,调用时 refcount 上升,函数退出时下降。只读取数组的函数分配 0 字节;修改数组的函数承担分离成本(对嵌套结构而言,与数组中被修改的部分成正比)。已验证:一个 1.39 MB 的数组穿过两层函数且无任何修改,额外分配为 0 字节。
  3. 3. 如何查看某个变量的 refcount?使用 Xdebug 扩展的 xdebug_debug_zval() 函数。它会为任意变量打印 refcount、is_ref 标志和值:xdebug_debug_zval('arr') 会输出类似 arr: (refcount=2, is_ref=0)=array(...) 的内容。显示的 refcount 包含 Xdebug 自身的临时引用;应用可见的 refcount 需减去 1。这是在开发期间检查 COW 状态的标准方法。
  4. 4. 为什么对复制后的数组第一次写入这么慢?因为第一次写入会触发分离事件——PHP 分配一块等于数组大小的新内存,把所有元素复制过去,递减原数组上的 refcount,然后才执行修改。对一个 100,000 个元素的数组,这大约需要 8.947 毫秒(实测)。对同一变量的后续写入不会触发分离(该变量已拥有自己的副本),大约需要 0.001 毫秒。第一次写入与后续写入的比率约为 8,800 倍。
  5. 5. 修改深层元素时,PHP 会整体复制嵌套数组吗?不会。PHP 执行选择性分离——只有从根到被修改元素的路径会分离。每一层的兄弟分支保持共享,refcount 不变。已验证:一个包含三个各含 5,000 个元素的子数组的结构(总计约 400 KB),修改第一个子数组中的一个元素,只分配 135,600 字节(一个子数组加外层容器)。另外两个子数组保持 refcount=2——仍与原始变量共享。
  6. 6. PHP 引用(&)与写时复制如何相互作用?引用会禁用它们触及的值的 COW。当某个变量属于引用集合(is_ref=1)时,集合中的所有变量都必须观察到彼此的修改,这与 COW 的“惰性复制”模型不相容。用 & 创建引用还可能迫使原本共享同一值的其他变量立即分离,因为它们不能与一个期待值语义的变量处于同一个引用集合中。
  7. 7. PHP 字符串也使用写时复制吗?是的,但有一个重要差异。字符串赋值使用 COW(赋值时不复制),但对字符串的任何修改都会复制整个字符串。字符串没有数组 HashTable 那样的内部结构——它们是连续的字符数据,因此“修改第 N 个字符”等价于“生成一个改了那个字符的新字符串”。已验证:一个 100,000 字节字符串的赋值花费 0 字节;修改单个字符花费 102,400 字节(完整字符串复制)。构建字符串时,应先在数组中累积、最后再 implode,而不是在循环中使用 .=。
  8. 8. 如何判断 PHP 代码中哪一行导致了内存增长?在可疑操作周围加入 memory_get_usage() 调用并测量增量。出现非零增量且没有明显的分配原因,通常表明发生了 COW 分离——该行触发了一个先前共享值的复制。更详细的信息可借助 xdebug_debug_zval:它显示操作前后的 refcount,让分离事件清晰可见(refcount 从大于 1 降到 1,且该变量现在拥有自己的副本)。两者结合,就能精确定位代码中真正发生分配工作的地方。

注:本文中所有内存测量和计时数据均使用 memory_get_usage() 和 hrtime() 在 PHP 8.3.6 上验证。通过 xdebug_debug_zval 显示的 refcount 值包含 Xdebug 自身的临时引用(通常比应用可见的 refcount 高 1)。数组的具体字节数取决于数组的内部结构(HashTable 大小、桶数量、分配器开销),在不同 PHP 版本和配置下可能略有差异;文中描述的规律和比率在 PHP 7+ 各版本应保持稳定。分离事件的计时(比后续写入慢约 8,800 倍)在典型的 Linux x86_64 环境上测得;硬件和分配器状态会改变绝对值,但数量级比率反映的是“分配+复制”与“单元素修改”之间根本性的成本差异。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-21 12:25:01 HTTP/2.0 GET : https://f.mffb.com.cn/a/509454.html
  2. 运行时间 : 0.338858s [ 吞吐率:2.95req/s ] 内存消耗:4,817.71kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=02c4b97e7f34c6b7e37373ee87b4e37f
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.001132s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001750s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.003970s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.005079s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001094s ]
  6. SELECT * FROM `set` [ RunTime:0.006827s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000930s ]
  8. SELECT * FROM `article` WHERE `id` = 509454 LIMIT 1 [ RunTime:0.009726s ]
  9. UPDATE `article` SET `lasttime` = 1787286302 WHERE `id` = 509454 [ RunTime:0.026668s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.011740s ]
  11. SELECT * FROM `article` WHERE `id` < 509454 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.013224s ]
  12. SELECT * FROM `article` WHERE `id` > 509454 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.018770s ]
  13. SELECT * FROM `article` WHERE `id` < 509454 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.021762s ]
  14. SELECT * FROM `article` WHERE `id` < 509454 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.023248s ]
  15. SELECT * FROM `article` WHERE `id` < 509454 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.002594s ]
0.342911s