当前位置:首页>php>PHP 8.6 异步初探 Fiber 与 Polling API 对比

PHP 8.6 异步初探 Fiber 与 Polling API 对比

  • 2026-08-21 17:23:49
PHP 8.6 异步初探 Fiber 与 Polling API 对比

几周前的一篇文章曾介绍 Polling API RFC,并将其定位为被低估的提案,原因主要在于:报道往往漏掉了真正的动机——那是内部 php_poll.h API,而非用户态的 Io\Poll 类。这一判断至今仍然成立。不过随后收到了不少类似"好吧,可它到底能用来做什么?"的反馈。这是个合理的问题,也正是本文要回答的问题。

时机也恰到好处。该 RFC 以 33 票赞成、1 票反对、4 票弃权通过,并于 6 月 3 日投票截止,实现已经合入 master 分支。Alpha 1 预定 7 月 2 日发布,功能冻结与 Beta 1 在 8 月中旬落地,GA 初步定于 11 月 19 日。这意味着 Polling API 已经从一个 RFC 文本,变成可以从 master 编译并立即上手试用、先于正式 alpha 标签就能动手的东西。接下来就做这件事。

与此同时,PHP 社区此刻正围绕"生产环境到底该用哪种异步方案"展开一场活跃的争论:基于用户态事件循环的 Fiber、ReactPHP、Swoole,还是跑在 Revolt 之上的 Amp v3。尚未有人把这场争论与 Polling API 带来的变化清晰挂钩。本文要做的正是这件事,用真实代码,而不只是感觉。

Fiber 是并发模型,Polling API 是那块缺失的原语

这两者常常被混为一谈,在动手构建任何东西之前,先把它们彻底分开。

Fiber 是 PHP 的协作式并发原语,自 8.1 起进入核心。它提供一个可以自行暂停的函数:通过 Fiber::suspend() 暂停,之后由 $fiber->resume() 恢复,暂停期间自己的栈与局部状态都原封不动。这就是它的全部。它不知道任何关于 socket、定时器或 I/O 的事,只是一个控制流原语,仅此而已。

事件循环负责决定何时恢复一个被挂起的 Fiber。在 PHP 的历史上,这要么依赖底层的 stream_select(),要么借助 PECL 扩展(如 ext-uv 或 ext-event)以获得原生 epoll 或 kqueue。ReactPHP 一口气提供了四种独立的循环实现——StreamSelectLoop、ExtUvLoop、ExtEventLoop、ExtEvLoop——恰恰是因为没有一个可靠的原生原语可以依托。AMPHP 也通过 Revolt 构建了对应的一套方案。

Polling API 正是那块缺失的原语。它不取代 Fiber,本身也不是事件循环。它是事件循环之下 PHP 一直不曾原生拥有的那一层:一种快速向操作系统询问"这些文件描述符中哪些已就绪"的方式,而无需为此维护四套后端实现。

合在一起,Fiber 提供了可暂停的函数,Polling API 提供了高效判断何时恢复它们的途径。这就是全部。其余一切——定时器、取消、背压——都是用户或某个库在此基础上构建的。

构建尽可能小的调度器

理解 Amp v3 与 ReactPHP 内部到底在做什么,最好的办法是自己动手做一个玩具版本。接下来就来做这件事:一个并发运行若干 Fiber 的调度器,每个 Fiber 通过原始非阻塞 socket 抓取一个 URL,并由一个 Io\Poll\Context 统一恢复。



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

<?php

declare(strict_types=1);

use Io\Poll\{Context, Event};

finalclass MiniScheduler
{
    private Context $poll;

    /** @var array<int, Fiber> */
    private array $fibers = [];

    publicfunction __construct()
{
        $this->poll = new Context();
    }

    publicfunction spawn(callable $task): void
{
        $fiber = new Fiber($task);
        $fiber->start();

        if ($fiber->isTerminated()) {
            return;
        }

        $this->fibers[spl_object_id($fiber)] = $fiber;
    }

    publicfunction run(): void
{
        while ($this->fibers !== []) {
            foreach ($this->poll->wait(timeoutSeconds: 1) as $watcher) {
                $fiber = $watcher->getData()['fiber'];

                $fiber->resume($watcher);

                if ($fiber->isTerminated()) {
                    unset($this->fibers[spl_object_id($fiber)]);
                }
            }
        }
    }

    publicfunction awaitReadable($stream): void
{
        $fiber = Fiber::getCurrent();
        $handle = new StreamPollHandle($stream);
        $watcher = $this->poll->add($handle, [Event::Read], ['fiber' => $fiber]);

        Fiber::suspend();

        $watcher->remove();
    }

    publicfunction awaitWritable($stream): void
{
        $fiber = Fiber::getCurrent();
        $handle = new StreamPollHandle($stream);
        $watcher = $this->poll->add($handle, [Event::Write], ['fiber' => $fiber]);

        Fiber::suspend();

        $watcher->remove();
    }
}


这实际上就是大部分内容。spawn() 启动一个 Fiber,它会一直运行到遇上 Fiber::suspend()。run() 对 poll 上下文调用 wait(),该调用会阻塞,直到某个被监听的流真正可读,然后恢复恰好等待它的那个 Fiber。没有紧密轮询循环,没有每个 tick 都扫描一遍所有流。操作系统在就绪的第一时间通知,控制权随即直接交还给关心它的那个 Fiber。

现在是真正的任务:基于原始 socket 的非阻塞抓取。这里需要修正初稿中的一处问题:向非阻塞流写入可能发生短写,因此请求必须在一个循环中写入,每当内核发送缓冲区回压时就等待可写状态,而不能指望一次 fwrite() 调用就把整个请求发完:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

<?php

declare(strict_types=1);

function writeAll(MiniScheduler $scheduler, $stream, string $data): void
{
    while ($data !== '') {
        $written = fwrite($stream, $data);

        if ($written === false) {
            throw new RuntimeException('Write failed');
        }

        if ($written === 0) {
            $scheduler->awaitWritable($stream);
            continue;
        }

        $data = substr($data, $written);
    }
}

function fetch(MiniScheduler $scheduler, string $host, string $path): string
{
    $stream = stream_socket_client("tcp://{$host}:80", $errno, $errstr, 30);

    if ($stream === false) {
        throw new RuntimeException("Connect to {$host} failed: {$errstr}");
    }

    stream_set_blocking($stream, false);

    writeAll($scheduler, $stream, "GET {$path} HTTP/1.1\r\nHost: {$host}\r\nConnection: close\r\n\r\n");

    $response = '';

    while (!feof($stream)) {
        $scheduler->awaitReadable($stream);
        $response .= fread($stream, 8192);
    }

    fclose($stream);

    return $response;
}


关于终止:这个循环依赖 feof() 在一次读到流尾之后翻转为 true,这与 RFC 自己的 TCP 客户端示例采用同一模式。这里之所以成立,有一个值得点明的理由:awaitReadable() 只请求 Event::Read,但 Event::Error 与 Event::HangUp 会被每个后端自动监控,无论请求的是什么,因此当服务器关闭连接时 wait() 仍会返回该 watcher。代码在调用 fread() 之前并不依据 hasTriggered() 做分支,一旦被唤醒就无条件调用它;而在已关闭的非阻塞流上,fread() 会返回空字符串并置位 EOF 标志,既不会阻塞也不会报错。正是这一点让最后一轮迭代干净利落地退出,而不是卡在最后一个描述符上。如果想更严格,读取前检查 hasTriggered(Event::Read)、把 Event::HangUp 单独处理,是更防御性的写法;只是不想让核心循环淹没在一堆不改变普通 HTTP GET 结果的分支之下。

把五个这样的任务接入调度器并发运行:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

<?php

declare(strict_types=1);

$scheduler = new MiniScheduler();

$hosts = [
    'example.com',
    'httpbin.org',
    'jsonplaceholder.typicode.com',
];

foreach ($hosts as $host) {
    $scheduler->spawn(function () use ($scheduler, $host) {
        $body = fetch($scheduler, $host, '/');
        echo "{$host}: " . strlen($body) . " bytes\n";
    });
}

$scheduler->run();


三个 Fiber,各自阻塞在自己的 socket 上,全部由一个 Io\Poll\Context 独立恢复。从结构上讲,这就是 Revolt 的 driver 在做的事,也是 ReactPHP 的 loop 在做的事。这里只是写出了仍然可用、且最小的那个版本。

刻意不展示的东西

这个调度器没有定时器,没有取消令牌,没有从 Fiber 传回调用方的错误传播,没有对永不挂起、从而拖住其他所有人的 Fiber 的防护,也没有 DNS 处理——除 stream_socket_client() 免费提供的部分之外。这不是疏漏,这正是重点。

Amp v3 与 ReactPHP 之所以存在,是因为把这件事做成正确、安全的版本确实很难;要让数百个并发 Fiber 的取消与背压都处理妥当,不是周末就能完成的项目。别把这个调度器带到生产环境附近。把它带来的理解带进你真正选用的那个库。

坦诚地做基准测试

在给出数据之前,先把局限说清楚。写下本文时,PHP 8.6 仍是 pre-alpha,从 master 自行编译,并不是可以 apt install 的打包构建。没有稳定版本,没有发行版软件包,Io\Poll 实现到 GA 之前仍可能变化。请把后面的内容视为方向性参考,而非生产环境 SLA。

上面的三主机抓取以四种方式各跑一遍:顺序阻塞的 file_get_contents() 调用、8.6 alpha 构建上的上述迷你调度器、8.4 上 ReactPHP 的 StreamSelectLoop、8.4 上跑在 Revolt 之上的 Amp v3。同样的三个主机、同样的简单 GET 请求,每种十轮,取中位数。

顺序阻塞大致等于三次往返之和,这并不意外,因为每个请求都要等上一个完成后才开始。迷你调度器与 ReactPHP 的 StreamSelectLoop 结果接近,二者大致受限于最慢的单个请求而非总和,这正是并发 I/O 想要的结果。跑在 Revolt 上的 Amp v3 比两者都略微领先,这也符合预期——Revolt 背后有多年调优,而这里只有四十行的调度器。

有趣的结果不是耗时,而是 CPU 行为。基于 stream_select() 的循环,随着被监听流数量的增长,会在用户态重扫描述符集合上消耗明显更多的开销。Io\Poll\Context 版本则保持平稳。三条流对三十条流,每次 wait() 调用代价大致相同,因为 epoll 不会重扫整个集合,它只告诉你哪些就绪了。这才是真正的回报,而且除非有人真的在高并发——数百上千条流,而不是三条——下做基准测试,否则它不会清楚地显现出来。

这个对比中有一个诚实的缺口:ReactPHP 与 Amp v3 跑在 8.4 上,迷你调度器跑在 8.6 pre-alpha 上,因此测到的是循环实现与 PHP 版本一起变化,而非循环本身。同版本对比——ReactPHP 与 Amp v3 都基于同一个 8.6 构建上的 Polling API 后端——才能干净地剥离出循环自身的贡献。目前这还做不到,因为两个项目都还没有交付 Io\Poll driver,而这恰恰是整篇文章的题眼。请把 CPU 行为当作更可靠的信号,因为它是架构层面的,不依赖跑的是哪个 PHP 构建;墙钟耗时则当作粗略的合理性校验,而非定论。

这对 Fiber、ReactPHP、Swoole 与 Amp v3 之争意味着什么

这正是前文说要串联起来的争论,以下是最终结论。

Swoole 其实不属于这个对比的范畴,把它当作四个选项之一,正是大量网络争论跑偏的地方。Swoole 是另一个 PHP 运行时。它取代应用原有的启动方式,透明地修补核心函数,使其变为非阻塞,并提供内置 worker 进程的生产级 HTTP 服务器。不是往现有应用里加 Swoole,而是从零开始为 Swoole 构建应用。对合适的工作负载,它确实非常出色;当每一毫秒都要精打细算、且具备在 Docker 镜像中管理编译扩展的运维纪律时,C 层面的协程切换让它对用户态 Fiber 拥有真实优势。Polling API 不会改变这个权衡的任何一个侧面,因为 Swoole 从未被 Polling API 所修复的那个问题限制住。

真正受影响的是 ReactPHP 与 Amp v3,而且方向一致。二者的存在,都是想在 Fiber 之上提供事件循环,而不要求你围绕另一个运行时重写应用。两者都花了多年时间维护多套后端实现——ReactPHP 的 StreamSelectLoop、ExtUvLoop、ExtEventLoop、ExtEvLoop,Amp 的同等规模铺开——纯粹是为了掩盖这样一个事实:PHP 核心从未给它们一个可靠的原生轮询原语。Polling API 终于就是那个原语,它消解了这些平行实现存在的原因。尤其期待 Revolt 会迅速把它接为原生后端——Revolt 本来就坐在 Amp v3 之下,充当共享的底层 driver,而这正是它被设计用来抽象的那类内部管道。

这一切都不会让 ReactPHP 与 Amp v3 之间的选择消失。那仍然主要是一个风格问题。Amp v3 的 Fiber 优先 API 读起来更接近同步代码;ReactPHP 的 promise 链式风格在你想要时给你对循环更显式的控制;而如果确实需要两者共存于同一进程,它们可以通过 revolt/event-loop-adapter-react 互操作。Polling API 所做的是剥夺二者继续维护特制原生后端的借口,同时意味着:一台五美元的 droplet 上跑原版 PHP 8.6,就能获得过去需要编译 PECL 扩展(大多数共享主机都不具备)才能得到的同等 epoll 性能。

用 PestPHP 对调度器做个快速检查

如果不想仅凭上面的耗时数字相信并发论断,而是想自行验证,这是大致的测试方式:用两个服务器,各自在响应前固定睡眠一段时间,以确认总耗时跟随最慢的请求而非总和:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

<?php

declare(strict_types=1);

it('resumes concurrent fibers without serialising the wait time', function () {
    $scheduler = new MiniScheduler();
    $started = microtime(true);

    foreach (['sleepy-one.test', 'sleepy-two.test'] as $host) {
        $scheduler->spawn(function () use ($scheduler, $host) {
            fetch($scheduler, $host, '/sleep?ms=200');
        });
    }

    $scheduler->run();

    $elapsed = microtime(true) - $started;

    expect($elapsed)->toBeLessThan(0.35);
});


两个各约两百毫秒的请求,总耗时远低于二者相加的四百毫秒,这就是整个测试。它不是什么精妙的断言,但它正是这里真正要紧的那一个,而且一旦在某个 Fiber 里不小心写了阻塞代码又忘了,它会立刻失败。

实际结论

如果今天在写应用代码,请选择 Amp v3 或 ReactPHP,而不是手写的调度器,并依据想要原生 Fiber 的使用体验,还是显式的 promise 控制来决定。如果运行的负载中每一毫秒、每个连接每一字节内存都举足轻重,并且具备使用编译扩展的运维成熟度,那么 Swoole 配得上它的复杂度。如果你本人就是维护这些库中某一个的人,Polling API 就是当下应该投入开发的东西——趁它还走在 alpha 之前,你的反馈还能真正影响 11 月发布的东西。

PHP 花了整整十年被人断言做不好这件事。事实证明,它只是需要操作系统不再陌生。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-21 18:02:05 HTTP/2.0 GET : https://f.mffb.com.cn/a/509304.html
  2. 运行时间 : 0.468740s [ 吞吐率:2.13req/s ] 内存消耗:4,958.38kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=c746786271f3dd322f0f58d899996b30
  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.001173s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001439s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.035055s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.017924s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001531s ]
  6. SELECT * FROM `set` [ RunTime:0.006978s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001538s ]
  8. SELECT * FROM `article` WHERE `id` = 509304 LIMIT 1 [ RunTime:0.012102s ]
  9. UPDATE `article` SET `lasttime` = 1787306525 WHERE `id` = 509304 [ RunTime:0.059455s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.002730s ]
  11. SELECT * FROM `article` WHERE `id` < 509304 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001375s ]
  12. SELECT * FROM `article` WHERE `id` > 509304 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.002097s ]
  13. SELECT * FROM `article` WHERE `id` < 509304 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.006815s ]
  14. SELECT * FROM `article` WHERE `id` < 509304 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.110377s ]
  15. SELECT * FROM `article` WHERE `id` < 509304 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.022701s ]
0.472270s