eftec / autoloadone
AutoloadOne 是一个用于生成 PHP 的自动加载类的程序。
Requires
- php: >=7.2.5
- ext-json: *
README
AutoloadOne 是一个为 PHP 生成特定项目自动加载类(自动包含)的程序。这个类在代码中使用类时非常有用,无需手动调用每个“包含”。它是 Composer 的自动加载的直接替代品,但工作方式不同。
Composer 的自动加载在运行时扫描文件夹,而此库仅扫描一次文件夹并存储结果。
与其他替代方案不同,它支持使用 PHP 以最简单的方式自动加载类,而不会牺牲性能。它是如何工作的?AutoLoadOne 预计算项目中每个类,并生成一个可用的单一生成 autoload.php(或指定的名称)文件。您无需特定文件夹、结构或规则即可使用它。只需生成 class、include 文件,即可加载任何类(即使是没有任何命名空间的类、不同文件夹中的命名空间内的类、单个文件中定义的多个类...)。
AutoLoadOne 是 Composer 的自动加载的替代品,使得 psr-0 或 psr-4 的使用变得过时。
注意:如果您运行的是 dev-distro,那么您必须排除 example/ 文件夹,因为它包含 @autorun 标签。
最后更新 2023 年 1 月 26 日
"PHP 中的通用自动加载类,任何类,任何时间!"
目录
- PHP 自动包含 AutoLoadOne 生成器
它是如何工作的?
1️⃣
以 CLI 或 Web 的方式运行 AutoLoadOne.php。
2️⃣
AutoLoadOne 将根据您的项目生成一个名为 autoload.php(或指定的名称)的单个文件。记录一下,扫描 WordPress 仅需 1.5 秒,而且它与 WordPress 兼容。
3️⃣
将生成的文件(例如,autoload.php)包含到您的项目代码中并开始使用它。
我应该何时重新运行 AutoLoadOne?
如果您在相同文件夹中添加具有相同命名空间的新的类,则无需再次运行它。
此外,您还可以手动编辑 autoload.php,添加更多类和命名空间。
或者,您可以再次运行 AutoLoadOne.php 并替换旧的生成文件。
Composer 自动加载功能
🔲 每个文件一个类
🔲 每个文件一个命名空间
🔲 文件必须有一个命名空间
🔲 它需要 composer
🔲 它验证每个用户加载类时的每个文件
🔲 文件夹结构应预先定义
✅ 支持CLI
AutoLoadOne 扩展功能
✅ 每个文件一个或多个类
✅ 每个文件一个或多个命名空间
✅ 文件可以包含可选的命名空间。
✅ 只需要PHP。
✅ 文件夹结构和类只验证一次。
✅ 如果你添加一个与之前文件夹共享且使用之前命名空间的类,那么你不需要运行生成器。
✅ 你可以使用任何文件夹结构。建议使用相同的文件夹来存储相同的命名空间,但这不是必需的。
✅ 支持CLI和Web-UI。
✅ 不需要APCU、锁文件或缓存。
✅ 与几乎所有项目兼容,包括使用Composer自动加载的项目。
✅ 与PSR-0、PSR-4以及几乎所有规范兼容,因为你不需要使用任何特殊配置或标准。
✅ 允许项目文件夹外的库。
例如 /someuser/myproject/ 允许包含来自文件夹 /otheruser/library/ 的库。
✅ 不需要APCU、锁文件或缓存。
✅ 对运行时的影响最小。
✅ 允许压缩而不影响运行时。
入门
你可以直接运行AutoLoadOne.php(通过Web或通过CLI),或者你可以创建一个调用它的文件。
通过 CLI 使用
必须在根目录下执行,它将生成一个名为autoload.php的文件。
php AutoLoadOne.php -generate
如果AutoLoadOne.php不在同一文件夹中,则可以复制它,或设置路径以使用它:php /somefolder/AutoLoadOne.php -generate。还有更多你可以使用的命令,但-generate是基本且即用即得的体验。
通过代码使用
- 将AutoLoadOne.php复制到项目的根目录(推荐)
- 直接执行它或
- 创建下一个PHP文件(在根目录下)并执行它。
<?php // This code will generate the file autoload.php use eftec\AutoLoadOne\AutoLoadOne; define("_AUTOLOAD_SELFRUN",false); // we want to call it manually. include "AutoLoadOne.php"; // or change the path of the file. $auto=new AutoLoadOne(); $auto->init(); $auto->process(); $auto->render();
通过 Web 使用(生成代码)
1️⃣
将文件 autoloadone.php 复制到某处。
2️⃣
出于安全考虑,你可以编辑类 autoloadone.php 的前几行。如果需要,更改用户、密码和autoloadenter。
<?php define("_AUTOLOAD_USER","autoloadone"); define("_AUTOLOAD_PASSWORD","autoloadone"); define("_AUTOLOAD_ENTER",true); // if you want to autoload (no user or password) then set to true ?>
3️⃣
启动浏览器
输入您的用户名和密码。如果 _AUTOLOAD_ENTER 为true,则您将自动登录。
4️⃣
选择要扫描的文件夹,然后选择要生成的文件,最后点击生成按钮。
- 根文件夹:要扫描的文件夹。
- 生成文件:autoload.php的完整路径(本地)。即使你不使用文件生成,也必须指定它,因为程序使用它来确定相对路径。
- 保存文件:如果你勾选它,则将生成文件。如果PHP没有权限保存文件,则可以手动复制代码(屏幕结果)
- 排除命名空间:排除映射的命名空间。
- 排除映射:排除扫描的路径(它们不是递归的)
5️⃣
结果应该看起来像这样
通过 CLI 使用
在shell中,浏览到你想要生成代码的文件夹,并运行以下命令
可用命令
- 当前(扫描当前文件夹并生成文件)
- 文件夹(要扫描的文件夹)
- filegen(autoload.php将要生成的文件夹)
- filename(默认生成的文件名,通常是autoload.php)
- save yes/no(保存要生成的文件)。这是必需的选项。
- excludens(排除命名空间)
- excludepath(排除路径)
- externalpath(包含外部路径)。外部路径是位于项目文件夹之外的库
示例:php autoloadone.php -folder folder\scan -filegen folder\whereautoload\ -save yes
php folder/located/autoloadone.php -current
使用生成的文件(autoload.php)
1️⃣
包含上一步生成的文件。例如:autoload.php
<?php define("_AUTOLOAD_ONEDEBUG",true); // this line is optional. By default, the DEBUG is off. The debug mode is used for find errors. include "autoload.php"; // it could be an absolute or relative path. ?>
就是这样!
在/test文件夹中,你可以找到一些示例来尝试。
注意:最后,如果你想,你可以删除文件autoloadone.php。
注意
如果你想排除一个类,你可以将命名空间添加到排除列表中,或者你可以跳过一个文件夹。
此外,如果一个类有以下的注释,它将自动被排除
<?php // @noautoload ?>
自动运行
如果您想执行(运行)一个PHP文件,可以添加以下注释。
<?php // @autorun ?>
您也可以通过添加带有@autorun的注释来设置执行优先级。
<?php // @autorun first ?>
如果您发现错误:语法错误,在第000行。那么一些扫描的PHP文件存在语法错误。解决方案是修复问题或排除整个文件夹。
如何找到有错误的文件?您可以运行带有调试标志的页面:autoloadone.php?debug=1
扩展
您可以通过运行以下命令来更改扩展名(默认为.php)
$auto=new AutoLoadOne(); $auto->extension='.php'; // it's not required. By default it's .php
统计和优化
此库生成以下统计数据。目标很简单,必须(在可能的情况下)减小地图的大小。地图越小,越好。
Number of Classes: 42
Number of Namespaces: 12
Number of Maps: 16
Number of PHP Files: 50
Number of PHP Autorun: 3
Number of conflicts: 0
Ratio map per file: 32% Acceptable (less is better. 100% means one map/one file)<
Ratio map per classes: 38.1% Acceptable (less is better. 100% means one map/one class)
Map size: 3.1 kbytes (less is better, it's an estimate of the memory used by the map)
屏幕示例
在日志文件中
- 白色表示正常操作
- 黄色表示警告。例如,某些文件已被排除。
- 绿色表示优化。
- 蓝色表示成功执行了重要操作。
- 红色是必须注意的错误。
我如何减少映射?
- 您可以使用一个类/一个文件,同时,类名必须与文件名相同。命名空间名称无关紧要
示例 Customer.php 和类 Customer { }
- 将同一命名空间下的类分组在同一文件夹中。因此,库可以将整个命名空间映射为单个文件夹,而不是映射每个文件/类。
-
- 📁 仓库 (repositoryns\)
-
-
- 📃 MyClass.php repositoryns\MyClass
-
-
-
- 📃 MyClass2.php repositoryns\MyClass2
-
-
- 📁 模型 (namespace_model\)
-
-
- 📃 MyClass.php namespace_model\MyClass
-
-
-
- 📃 MyClass2.php namespace_model\MyClass2
-
- 您可以通过删除(:scissors:)不需要的命名空间和文件夹。但是,某些命名空间和文件夹由系统使用,它们不需要自动加载,因为它们是手动加载的(例如,大多数库都手动加载其自己的包含文件)
-
- 📁 somelibrary
-
-
- 📃 MainLibraryClass.php
-
-
-
- 📃 IncludesLibrary.php ✂️
-
-
-
- 📁 somelibrary ✂️
-
-
-
-
- 📃 MoreIncludesLibrary.php ✂️
-
-
-
-
-
- 📃 MoreIncludesLibrary.php ✂️
-
-
- 您还可以通过添加标签 @noautoload 来排除文件/类/include/结构。
/* @noautoload */ class Someclass { }
-
- 📁 somelibrary
-
-
- 📃 MainLibraryClass.php
-
-
-
- 📃 IncludesLibrary.php @noautoload ✂️
-
- 只有扩展名为 .php(或定义的扩展名)的文件才会被加载。所以,.inc、.phpinclude 或类似的文件会被自动排除(:scissors:)。
-
- 📁 somelibrary
-
-
- 📃 file.inc.php (inc.php被包含,但.inc)
-
-
-
- 📃 IncludesLibrary.inc ✂️
-
-
-
- 📃 MoreIncludesLibrary.inc ✂️
-
- 另一种优化是在同一个文件中写入多个类。此库甚至允许在同一个文件中使用多类/多命名空间。因此,可以创建项目的批量版本。
-
- 📃 AllClassesOneFile.php
-
-
- namespace repositoryns\
-
-
-
-
- class repositoryns\MyClass
-
-
-
-
-
- class repositoryns\MyClass3
-
-
-
-
- namespace anotherns\MyClass2
-
-
-
-
- class anotherns\MyClass2
-
-
测试
我在Laravel上创建了一个空的博客。项目是空的,但有默认库和组件。
文件
7545 files in total. (including files that aren't PHP files)
AutoLoadOne
Number of Classes: 5565
Number of Namespaces: 765
Number of Maps: 2305 (you want to reduce it)
Number of PHP Files: 6302
Number of PHP Autorun: 0
Number of conflicts: 31
生成的文件
autoload.php 231kb.
优化后的 AutoLoadOne
我已将PHPUnit和Mockery从项目中分离出来。为什么?这两个库都是用于单元测试的。
排除的命名空间 = /vendor/phpunit/,/vendor/mockery/
Number of Classes: 5565
Number of Namespaces: 765
Number of Maps: 1535 (you want to reduce it)
Number of PHP Files: 6302
Number of PHP Autorun: 0
Number of conflicts: 13
生成的文件
autoload.php 159kb.
Composer 的自动加载(使用优化)
composer dump-autoload -o
Generated optimized autoload files containing 3519 classes
Number of Maps: 3519 (static and not-static)
自动加载使用以下方法之一
-
静态:(快速方法,它使用更多内存,并且需要手动计算)
autoload.php 1kb
autoload_real.php 3kb
autoload_static.php 468kb
ClassLoader.php 14kb -
非静态:(默认方法)
autoload.php 1kb autoload_real.php 3kb autoload_namespaces.php 1kb autoload_psr4.php 4kb autoload_classmap.php 426kb
大小为什么很重要?
假设我们调用一个使用自动加载的单页网页。
如果我们使用 Composer 的自动加载(静态加载),我们也会调用一个使用 468kb(加上其他文件)的文件,并且这个内存被加载到内存中。每次调用可能会使用(平均)609kb 的 RAM(大约是 PHP 文件 x 1.3 x 1kb)。
例如,如果我们有 1000 个并发用户。由于自动加载,它将使用 609kb x 1000 = 609mb 的 RAM,同时有 10k 个并发用户,我们仅因为自动加载就会使用 6gb 的 RAM。
使用 AutoLoadOne,它被优化到 302mb(1000 个用户)或 3gb(10k 个用户),这是对于未优化的版本。
AutoLoadOne 会标记项目中所有的类,包括在 composer.json 中未定义的类(除非它们被排除在项目之外)。Composer 的自动加载只找到了 3519 个类,而 AutoLoadOne 找到了项目中的所有类(5565 个)。
然而,有些类可能不需要被项目加载(例如单元测试类),因此我们可以排除这些项目中的类。
例如,排除 PHPUnit 和 Mockery 可以将使用量减少到 206mb(1000 个用户)或 2gb(10k 个用户),但我们还可以进一步优化。
查找使用?
假设我们有一个包含不同元素的 "map"。查找 map 中的元素需要多长时间?
所以,map 的大小/查找时间并不重要。一个小 map(100 个元素)与一个大 map(1百万个元素)之间的差异总共是 0.1 秒(每 1 百万个查询)。然而,内存使用很重要,可能会对性能产生重大影响。
调用多少次查找?
假设我们有 10k 个并发用户,每个用户调用 100 个不同的类。这意味着我们同时进行 10k x 100 = 1 百万个查找。
第二次测试(Magento 2.2.3)
Magento 是一个巨大的项目,它有 22k 个 PHP 文件,其中 20k 个是类。
AutoLoadOne
Number of Classes: 21063
Number of Namespaces: 7018
Number of Maps: 9473 (you want to reduce it)
Number of PHP Files: 22862
Number of PHP Autorun: 0
Number of conflicts: 6
Ratio map per file: 41.44% Bad. (less is better. 100% means one map/one file)
Ratio map per classes: 44.97% Bad. (less is better. 100% means one map/one class)
Map size: 1398.7 kbytes (less is better, it's an estimate of the memory used by the map)
Map size Compressed: 1195.1 kbytes (less is better, it's an estimate of the memory used by the map)
生成 autoload.php 需要大约 +/- 200 秒。
相比之下,Composer 的自动加载(优化版)使用
Generated optimized autoload files containing 11582 classes
Number of Maps: 11582 classes (2.6mb of memory will be use per request per user)
然而,它没有进行手动优化。
假设我们有 1000 个并发用户
(*) 然而,Magento 并不是为了并发而创建的。但,然而我们测量的不是并发用户的数量,而是并发调用的数量(例如 rest-json、打开页面等)。
压缩和 Magento。
虽然 AutoLoadOne 能够压缩 map,但它只压缩了路径,而不是命名空间。这是因为压缩的目标是尽量减少对系统的影响。Magento 在大型命名空间上依赖很重,因此压缩无法压缩它们。但仍然,系统能够在 15% 的程度上压缩值。
总的来说,压缩可以将值缩小 40-50%。
代码执行。
AutoLoadOne 和 Composer 的自动加载都在初始化/执行时执行代码。
当 AutoLoadOne 生成 map 时,它由以下两个关系数组组成
private $_arrautoloadCustom = array( 'Magento\AdminNotification' => '/app/code/', 'Magento\Notice' => '/app/code/Developer/',...
而 Composer 的自动加载生成一个需要拼接的数组。
array( 'Magento\\AdminNotification' => $baseDir . '/app/code/MagentoActions.php', 'Magento\\Notice' => $baseDir . '/app/code/Developer/Notice.php',
所以它需要拼接每个 map(使用一个名为 $baseDir 的变量)。因此,Composer 的自动加载会稍微影响性能。
基准测试
PHP 7.1.18 + Windows 10 + SSD。
越多越好。
我通过加载不同的类并读取其性能进行了综合基准测试。由于我的机器有 SSD 硬盘,所以与机械硬盘相比,磁盘的影响最小。此图表比较了与 INCLUDE 的性能。
安全性
您可以阻止对文件的访问
RedirectMatch 403 ^/folder/^/folder/.*$
❗ 虽然程序有内置的安全措施,但我建议添加新的安全层,例如将 AutoLoadOne.php 文件放在 public/web 文件夹之外。
AutoLoadOne.php 不安全(因为它会写入生成文件),它没有访问数据库的权限,也不允许写入任何内容到文件,但它可能会覆盖现有的代码并破坏系统。
然而,生成文件(autoload.php)是安全的,并且可以将其暴露在网络上。
- 更改用户名和密码,并将 _AUTOLOAD_ENTER 设置为 false。
- 或者,不要将此文件放在您的公共网站上。
- 或者,更改文件名。
- 或者,您可以使用 .htaccess 或类似工具阻止对文件的访问。
RewriteEngine On
RewriteBase /
<Files "AutoLoadOne.php">
Order Allow,Deny
Deny from all
</Files>
- 或者,您可以限制对 PHP 的访问,Linux 上的默认行为就是这样(通常以 NOBODY 用户身份运行于 Apache 账户下)。
composer.json
通常,这个库不需要 composer.json,并且它直接读取 PHP 源代码,因此会忽略其配置。然而,从 1.19 版本开始,AutoLoadOne(可选地)读取 composer.json 的部分信息,以实现兼容性。例如,guzzlehttp 库就使用了这个功能。
注意:需要将常量 _AUTOLOAD_COMPOSERJSON 设置为 true。默认情况下,此变量为 false。
让我们看看下一个文件
composer.json
{ "autoload": { "psr-4": { "blahblahblah": "some folder blahblahblah/" }, "files": ["src/functions_include.php"] } }
如果 AUTOLOAD_COMPOSERJSON 为 true,AutoLoadOne 将包含 composer.json 和 'files' 中声明的文件。这些文件或文件夹将按如下方式添加到我们的 autoload.php 中
我们生成 autorun.php 的代码
define("_AUTOLOAD_COMPOSERJSON",true); include 'vendor/eftec/autoloadone/AutoLoadOne.php';
生成的 autorun.php 文件
@include __DIR__.'/folder/jsontest/src/functions_include.php';
由于这个过程只执行一次(在生成 autoload.php 时),因此此功能不会影响性能,因为它只读取一次 composer.json 文件。
版本
- 1.28 2023-01-26
- 小清理
- 1.27 2022-08-27
- [修复] 修复了双重映射的问题。
- 1.26 2022-02-21
- [修复] 兼容 PHP 8.1。
- 提高与 php 7.1.5 及更高版本的兼容性。如果需要使用旧版本,可以使用 1.25.1。
- 将 AutoLoadOne 添加为 composer 的二进制文件。
- 1.25.1 2021-06-09
- [修复] 在 autoloadone_exception_handler 中,当错误参数不是数组而是字符串时。
- 1.25 2021-04-17
- 更好的错误管理。现在,它会在自定义跟踪中显示错误所在的行。
- 1.24 2021-04-17
- [cli] 重新着色 CLI。
- [代码] 代码中的某些清理。
- [修复] 现在生成的文件显示了正确的小时。
- 1.23 2021-02-26
- 更新了生成的文件。
- 1.22.2 2021-02-26
- 修复了 composer.json。
- 1.22.1 2021-02-26
- 修复了代码中的错误。
- 1.22 2021-02-26
- 另一个修复(它未能保存配置文件。未能为多个类使用相同的路径)。
- 配置现在存储在同一个文件 autoload.php 中。旧文件仍然可以使用,但仅当未设置或使用新配置时。
- 删除了部分配置,与 json 相关的函数以及与 json 相关的常量。
- 1.21.2 2021-02-15
- 删除了错误的 "']" 字符。
- 1.21.1 2021-02-15
- 修复了 composer.json(错误的数字)。
- 1.21 2021-02-15
- 修复了与 Linux 相关的一个大问题。它使用了 basename(),但在 Linux 和 Windows 中的行为不同。现在,它在 Linux 中正常工作。
- 1.20 2020-09-02
- 一些清理。
- GUI 有一些示例。
- _AUTOLOAD_COMPOSERJSON 指示了它在何处执行或不执行。
- 1.19.2 2020-06-05
- composer.json 功能现在是可选的(默认禁用)。
- 1.19.1 2020-06-05
- composer.json 的 autoload-files 现在可以通过 "exclude-path" 排除。
- 1.19 2020-06-05
- 添加了 composer.json {'autoload': {'files': []}}
- 1.18 2020-04-23
- 一些清理。
- 生成的文件也进行了清理和优化。
- 1.17 2020-01-26(可选但默认),映射被压缩。
- 压缩对运行时的影响最小,它只使用正则表达式替换字符串。
- 1.16 2019-08-04 删除了 git 引用。它不再使用。将样式格式改为 PSR。
- 1.15 2019-06-08 再次删除了外部 CSS。现在它将 CSS 生成在文件内。
- 1.14 2019-06-08 修复了一些错误。重置为全局(const 数组与 php<7.0 不兼容)。
- 1.12 2019-05-10 添加了一些提交的更改。删除了 CSS。
- 1.11 2019-03-04 允许指定结果PHP文件。并进行了一些清理。现在,/namespace/nameclass:class 不会被视作一个类
- 1.10 2018-10-18 解决了从不同URL加载autoload.php时的小错误,并处理了外部和远程文件夹的问题。
- 1.9 2018-10-14 做了一些小修复和一些颜色调整。
- 1.8 2018-10-14 添加了外部路径和一些修复。现在您可以在路径中不包含逗号(将自动添加)[WebUI]
- 1.7 2018-10-12 一些小修复。现在默认情况下,系统使用调用者的路径,而不是AutoLoadOne.php的路径。
- 1.6 2018-09-28 在排除列表(文件夹)中添加了通配符 (*)。
- 1.5 2018-09-05 默认情况下,界面会自动打开。如果用于公开用途,则必须删除或限制此文件。
- 1.4 2018-08-25 一些示例。现在默认情况下,界面不会自动打开。这是出于安全考虑。
- 1.3 2018-07-05 现在它支持界面,并修复了一些特定文件的问题。还修复了Linux与Windows文件夹的问题。
- 1.2 2018-07-01 做了许多更改。修改了排除项。Web UI的标题和图标。它还允许禁用Web。
- 1.1 2018-06-26 一些修复。
- 1.0 2018-06-24 第一个版本
待办事项
保存配置CLI(更多命令)- 清理代码。
转换为单个类。外部文件夹/库(相对或绝对路径)- 如果PHP文件有错误,生成将失败。
指定扩展名。默认情况下,它只扫描.php文件。