snapshotpl / preloader
从 Opcache 创建 PHP 通用预加载脚本的辅助工具。
Requires
- php: ^7.4 || ^8.0
- ext-json: *
Requires (Dev)
- phpunit/phpunit: ^9.5.6
This package is auto-updated.
Last update: 2024-08-29 05:00:59 UTC
README
Opcache 预加载
只需一行代码,即可获得最佳选项,保持您的应用程序始终运行快速。
此包会自动从您的 Opcache 统计信息中生成 PHP 7.4 预加载脚本。无需手动修改。
如果您正在寻找预加载 Laravel 项目,请查看 Laraload。
目录
安装
使用 Composer 在项目中安装此软件包
composer require darkghosthunter/preloader
此软件包不需要
ext-opcache
即可安装。只需确保在您的应用程序服务器中将其启用。
用法
在任何 Opcache 已启用并运行的应用程序位置,使用您的 Composer 自动加载器路径调用 Preloader
,并指定输出编译脚本的路径
<?php use DarkGhostHunter\Preloader\Preloader; Preloader::make()->autoload(__DIR__ . '/vendor/autoloader.php') ->output(__DIR__.'/preloader.php') ->generate();
这将自动收集 Opcache 统计信息,并生成优化的 preload.php
文件。在这种情况下,文件将在调用 Preloader 的同一目录中创建。
www
└── app
├── PreloaderCall.php
└── preload.php
然后,在您的 php.ini
中告诉 PHP 在启动时使用此文件作为预加载器。
opcache.preload=/www/app/preload.php
重新启动使用 Opcache 的 PHP 进程,这就完成了。
如果您在 Opcache 禁用或无命中时使用 Preloader,将会抛出异常。
工作原理
此软件包将向 Opcache 请求有关最常请求的文件的信息。您可以在此 Medium 文章中查看有关预加载的详细信息。
由于最佳统计数据是在应用程序运行一段时间后获得的,因此您可以使用自己的机制(或类提供的机制)仅在满足某些条件后编译列表。
请放心,您可以配置编译列表的内容和方式。
配置
您可以将 Preloader 配置为在满足条件时运行,限制文件列表,并指定输出编译预加载列表的位置。
when()
(可选)
如果您不想使用 Opcache 命中,则可以使用 when()
。当传递的变量评估为 true
时,Preloader 将继续执行,这由您控制。
Preloader::make()->when(false); // You will never run, ha ha ha!
您还可以使用返回 true
的闭包(箭头函数或任何其他可调用函数)。
Preloader::make()->when(fn () => $app->cache()->get('should_run'));
whenHits()
(可选)
如果您不知道应用程序的实际负载,这是收集良好预加载列表的最好方法。
Preloader::make()->whenHits(200000); // After a given number of hits.
当命中数达到设置的数值时,列表将被生成。这将避免在应用程序运行多次之前生成预加载列表。
注意!如果您使用
overwrite()
,则每次达到命中数后都会重新生成脚本!
whenOneIn()
(可选)
列表将在给定的机会次数中生成一次(次数越高,运行越少)。
Preloader::make()->whenOneIn(2000); // 1 in 2,000 chances.
使用overwrite()
可以与它一起使用,以便不断重新创建列表,这可能会很有用。
Preloader::make()->overwrite()->whenOneIn(2000);
memory()
(可选,默认值)
Preloader::make()->memory(32);
在MB
中设置你的内存限制。默认的32MB对于大多数应用程序来说已经足够了。预加载器将在达到内存限制之前生成文件列表。
这考虑了Opcache中缓存的每个脚本的memory_consumption
键,而不是实际文件大小。
此限制与Opcache内存限制无关。
exclude()
(可选)
您可以使用exclude()
排除Opcache提供的列表中的文件,它接受单个文件或文件数组。这些文件将传递给glob()
方法。这些文件路径必须是**绝对路径**。
Preloader::make()->exclude([ '/app/foo.php', '/app/bar.php', '/app/quz/*.php' ]);
这些被排除的文件将不会包含在列表生成中,也不会计入内存限制。
预加载器库文件将自动排除。您可以使用includePreloader()
禁用此功能。
Preloader::make()->includePreloader() ->exclude([ '/app/foo.php', '/app/bar.php', '/app/quz/*.php' ]);
append()
(可选)
当然,您也可以使用绝对路径手动将文件添加到要生成的预加载脚本中。只需使用append()
发出它们。这些文件将传递给glob()
方法。这些文件路径必须是**绝对路径**。
Preloader::make()->append([ '/app/foo.php', '/app/bar.php', '/app/quz/*.php' ]);
将文件添加到开头将它们放在列表生成的**之后**,因此它们不会计入列表内存限制。
Preloader::make()->memory(64)->append('foo.bar');
任何重复添加的文件都将被忽略,因为列表在编译脚本之前会自动删除它们。
output()
(必需)
我们需要知道输出脚本的位置。建议在同一个应用程序文件夹中执行此操作,因为大多数PHP进程都将能够访问同一目录内的写入。如果不是这样,您可以选择指出位置。
Preloader::make()->output(__DIR__ . '/../../my-preloader.php');
overwrite()
(可选)
有时您可能已经运行了预加载器脚本。为了避免用另一个列表替换它,默认情况下,当检测到脚本文件已存在时,预加载器不会执行任何操作。
要更改此行为,您可以使用overwrite()
方法指示预加载器始终重新写入文件。
Preloader::make()->overwrite()->generate();
注意与
whenHits()
和when()
等条件一起使用。如果条件为真,预加载器将反复覆盖预加载脚本...
shouldCompile()|shouldRequire()
(可选)
默认情况下,预加载器将使用require_once
将文件上传到Opcache。由于此操作会**执行**文件本身以预先解析链接,因此某些项目可能在使用此方法时遇到问题。
您可以使用shouldCompile()
将其更改为使用opcache_compile_file()
来更改此行为。这将读取文件,但不会解析链接,因此列表中最后的一些文件可能具有悬空链接(如 Traits、Interfaces和其他类),并且在文件被Opcache读取时可能会出现一些警告。
Preloader::make()->shouldCompile()->generate();
generate()
(必需)
一旦您的预加载器配置就绪,您就可以使用generate()
生成列表。
Preloader::make()->generate();
这将自动创建一个用于预加载应用程序的PHP脚本。如果成功,它将返回true
,如果条件不满足或存在不应覆盖的现有预加载文件,则返回false
。
list()
(替代方案)
或者,您可以使用list()
检索文件原始列表作为数组。
Preloader::make()->list();
如果您有自己的脚本或只是想对其进行实验,这可能会很有用。
给我一个例子
好吧。假设我们有一个包含1500个文件的框架。我们不知道任何指标,所以我们将在部署一周后盲目地将尽可能多的文件推入256MB的内存中,以便它有足够的Opcache统计信息。
<?php // index.php require __DIR__ . '/../vendor/autoload.php'; $app = \Framework\App::make(); $response = $app->run(); $response->sendToBrowser(); // A week after deployment $weekAfterDeploy = $app->deploymentTimestamp() + (7*24*60*60); // If a week has passed, and no script was created, do it! \DarkGhostHunter\Preloader\Preloader::make() ->when(time() > $weekAfterDeploy) ->autoload(__DIR__ , '/../vendor/autoload.php') ->memory(256) // 256MB of memory limit ->output(PHP_LOCALSTATEDIR . '/preload.php') // put it in /var. ->generate();
安全性
如果您发现任何与安全相关的问题,请通过电子邮件发送到darkghosthunter@gmail.com,而不是使用问题跟踪器。
许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。